14个版本
0.4.5 | 2022年9月9日 |
---|---|
0.4.4 | 2022年5月11日 |
0.4.3 | 2021年7月10日 |
0.4.2 | 2020年6月5日 |
0.1.3 | 2015年5月23日 |
在 HTTP客户端 类别中排名第47
每月下载量 511 次
64KB
762 行
Pusher HTTP Rust库
用于与Pusher HTTP API交互的Rust库。
此包允许您向客户端触发事件并查询Pusher频道的状态。当与服务器一起使用时,您可以验证Pusher webhook并认证私有或存在频道。
执行HTTP请求的函数是 异步 的,因此您需要使用类似 tokio 的执行器来运行它们。该库是 hyper 客户端的包装器。
为了使用此库,您需要在 http://pusher.com 上有一个免费账户。注册后,您将需要您应用程序的应用程序凭据。
目录
安装
添加到您的 Cargo.toml
pusher="*"
支持的平台
- Rust版本1.39及以上
入门
extern crate pusher; // imports the `pusher` module
use pusher::PusherBuilder; // brings the PusherBuilder into scope
// the functions are async, so we need a reactor running (e.g. tokio)
// this example uses "current_thread" for simplicity
#[tokio::main(flavor = "current_thread")]
async fn main() {
// initializes a Pusher object with your app credentials
let pusher = PusherBuilder::new("APP_ID", "KEY", "SECRET").finalize();
// triggers an event called "my_event" on a channel called "test_channel", with the payload "hello world!"
let result = pusher.trigger("test_channel", "my_event", "hello world!").await;
match result {
Ok(events) => println!("Successfully published: {:?}", events),
Err(err) => println!("Failed to publish: {}", err),
}
}
配置
配置此库的最简单方法是创建一个新的 Pusher
实例
let pusher = PusherBuilder::new("id", "key", "secret").finalize();
PusherBuilder::new
返回一个 PusherBuilder
,您可以在此实例上链式调用配置方法,然后再调用 finalize()
。
其他选项
从URL实例化
PusherBuilder::from_url("http://key:[email protected]/apps/id").finalize();
从环境变量实例化
PusherBuilder::from_env("PUSHER_URL").finalize();
如果您使用Pusher作为Heroku插件,这尤其相关,因为它将凭据存储在名为 "PUSHER_URL"
的环境变量中。
HTTPS
为确保请求通过HTTPS进行,请在调用finalize()
之前调用secure()
。
let pusher = PusherBuilder::new("id", "key", "secret").secure().finalize();
更改主机
在调用finalize()
之前调用host()
将确保请求发送到指定的主机。
let pusher = PusherBuilder::new("id", "key", "secret").host("foo.bar.com").finalize();
默认情况下,这是"api.pusherapp.com"
。
更改底层的hyper::client::connect::Connect
上述函数有等效的函数,也可以提供自定义的Connect
。例如。
let pusher = PusherBuilder::new_with_client(my_client, "id", "key", "secret").host("foo.bar.com").finalize();
使用
触发事件
可以在一个或多个频道上触发事件。频道名称只能包含字母数字字符、_
或`-`,并且长度不能超过200个字符。事件名称的长度也不能超过200个字符。
单个频道
异步fn 触发<S: serde::Serialize>(&self, channel: &str, event: &str, payload:S)
Argument | Description |
---|---|
channel &str |
您希望触发其上的频道名称。 |
event &str |
您希望触发的事件名称 |
data S: serde::Serialize |
您希望发送的有效载荷。必须能够将其序列化为JSON。 |
返回值 | Description |
---|---|
result Result<TriggeredEvents, String> |
如果触发成功并且您连接到某些集群,将作为Result 的一部分返回包含event_ids 字段的对象。如果遇到任何错误,将返回一个Err 值。 |
示例
let mut hash_map = HashMap::new();
hash_map.insert("message", "hello world");
pusher.trigger("test_channel", "my_event", &hash_map).await;
多个频道
异步fn 触发_multi<S: serde::Serialize>(&self, channels: &[&str], event: &str, payload:S)
Argument | Description |
---|---|
channels &[&str] |
您希望在它们上发送事件的频道名称向量。最大长度为10。 |
event &str |
与上面相同。 |
data S: serde::Serialize |
与上面相同。 |
返回值 | Description |
---|---|
result Result<TriggeredEvents, String> |
与上面相同。 |
示例
let channels = vec!["test_channel", "test_channel2"];
pusher.trigger_multi(&channels, "my_event", "hello").await;
排除事件接收者
trigger_exclusive
和trigger_multi_exclusive
遵循上述模式,但最后一个参数是socket_id
。
这些方法允许您排除具有该socket_id
的连接的接收者,使他们不会收到该事件。您可以在此处了解更多信息。
示例
在一个频道上:
pusher.trigger_exclusive("test_channel", "my_event", "hello", "123.12").await;
在多个频道上:
let channels = vec!["test_channel", "test_channel2"];
pusher.trigger_multi_exclusive(&channels, "my_event", "hello", "123.12").await;
认证频道
应用程序安全性非常重要,因此Pusher提供了一种机制,用于在订阅点验证用户对频道的访问权限。
这可以用于限制对私有频道的访问,以及在存在频道的情况下,通过存在事件通知订阅者还有谁订阅了。
此库提供了一种生成认证签名并将其发送回客户端以授权它们的机制。
有关更多信息,请参阅我们的文档。
私有频道
fn authenticate_private_channel(&self, channel_name: &str, socket_id: &str)
Argument | Description |
---|---|
channel_name &str |
客户端发送请求中的频道名称 |
socket_id &str |
客户端发送请求中的socket ID |
返回值 | Description |
---|---|
结果 String, &str> |
Ok 值将作为包含身份验证签名的响应发送回客户端,而Err 值将描述生成的任何错误 |
使用hyper的示例
async fn pusher_auth(req: Request<Body>) -> Result<Response<Body>, Error> {
let body = to_bytes(req).await.unwrap();
let params = parse(body.as_ref()).into_owned().collect::<HashMap<String, String>>();
let channel_name = params.get("channel_name").unwrap();
let socket_id = params.get("socket_id").unwrap();
let auth_signature = pusher.authenticate_private_channel(channel_name, socket_id).unwrap();
Ok(Response::new(auth_signature.into()))
}
身份验证存在频道
使用存在频道类似于私有频道,但为了识别用户,客户端会收到一个user_id,以及可选的自定义数据。
fn authenticate_presence_channel(&self, channel_name: &str, socket_id: &str, member: &成员)
Argument | Description |
---|---|
channel_name &str |
客户端发送请求中的频道名称 |
socket_id &str |
客户端发送请求中的socket ID |
member &pusher::Member |
一个表示要分配给频道成员的结构,包括一个user_id 和任何自定义的user_info 。见下文 |
自定义类型
pusher::Member
pub struct Member<'a> {
pub user_id: &'a str,
pub user_info: Option<HashMap<&'a str, &'a str>>,
}
使用hyper的示例
async fn pusher_auth(req: Request<Body>) -> Result<Response<Body>, Error> {
let body = to_bytes(req).await.unwrap();
let params = parse(body.as_ref()).into_owned().collect::<HashMap<String, String>>();
let channel_name = params.get("channel_name").unwrap();
let socket_id = params.get("socket_id").unwrap();
let mut member_data = HashMap::new();
member_data.insert("twitter", "jamiepatel");
let member = pusher::Member{user_id: "4", user_info: Some(member_data)};
let auth_signature = pusher.authenticate_presence_channel(channel_name, socket_id, &member).unwrap();
Ok(Response::new(auth_signature.into()))
}
应用程序状态
此库允许您查询我们的API以检索有关您的应用程序频道、它们各自属性的信息,对于存在频道,还有当前订阅它们的所有用户的信息。
获取应用程序中的频道列表
异步fn channels(&self)
在不提供任何查询选项的情况下请求应用程序频道的列表。
返回值 | Description |
---|---|
result Result<ChannelList, String> |
Ok 值将表示频道列表的结构。见下文。一个Err 值将表示遇到的任何错误。 |
异步fn channels_with_options(&self, params:QueryParameters)
在您的channels
请求中添加选项。
Argument | Description |
---|---|
params QueryParameters |
包含查询选项的元组向量。如果元组的第一个值是"filter_by_prefix" ,则API将使用第二个值过滤返回的频道。要获取存在频道的订阅用户数,请在一个包含相应"user_count" 值的元组中指定一个包含“info”值的值。 |
返回值 | Description |
---|---|
result Result<ChannelList, String> |
与上面相同。 |
自定义类型
pusher::ChannelsList
pub struct ChannelList {
pub channels: HashMap<String, Channel>,
}
pusher::Channel
pub struct Channel {
pub occupied: Option<bool>,
pub user_count: Option<i32>,
pub subscription_count: Option<i32>,
}
示例
无选项:
pusher.channels().await;
//=> Ok(ChannelList { channels: {"presence-chatroom": Channel { occupied: None, user_count: None, subscription_count: None }, "presence-notifications": Channel { occupied: None, user_count: None, subscription_count: None }} })
有选项:
let channels_params = vec![("filter_by_prefix", "presence-"), ("info", "user_count")];
pusher.channels_with_options(channels_params).await;
//=> Ok(ChannelList { channels: {"presence-chatroom": Channel { occupied: None, user_count: Some(92), subscription_count: None }, "presence-notifications": Channel { occupied: None, user_count: Some(29), subscription_count: None }} })
获取单个频道的状态
异步fn channel(&self, channel_name: &str)
在不提供任何查询选项的情况下请求单个频道的状态。
返回值 | Description |
---|---|
result Result<Channel, String> |
Ok 值将表示频道。见上文。一个Err 值将表示遇到的任何错误。 |
异步fn channel_with_options(&self, channel_name: &str, params:QueryParameters)
在您的channel
请求中添加选项。
Argument | Description |
---|---|
channel_name &str |
频道的名称 |
params QueryParameters |
包含查询选项的元组向量。要请求有关user_count和subscription_count的信息,元组必须包含一个“info”值和一个包含以逗号分隔的属性列表的值。对于任何无效的API请求,将返回一个Err 。 |
返回值 | Description |
---|---|
result Result<Channel, String> |
与上面相同。 |
示例
无选项:
pusher.channel("presence-chatroom").await;
//=> Ok(Channel { occupied: Some(true), user_count: None, subscription_count: None })
有选项:
let channel_params = vec![("info", "user_count,subscription_count")];
pusher.channel_with_options("presence-chatroom", channel_params).await;
//=> Ok(Channel { occupied: Some(true), user_count: Some(96), subscription_count: Some(96) })
获取存在频道中的用户列表
异步fn channel_users(&self, channel_name : &str)
Argument | Description |
---|---|
channel_name &str |
频道名称 |
返回值 | Description |
---|---|
结果 Result<ChannelUserList, String> |
Ok 的值将表示订阅了存在频道的用户列表的结构体。详见下文。而 Err 将表示遇到的所有错误。 |
自定义类型
pusher::ChannelUserList
pub struct ChannelUserList {
pub users: Vec<ChannelUser>,
}
pusher::ChannelUser
pub struct ChannelUser {
pub id: String,
}
示例
pusher.channel_users("presence-chatroom").await;
//=> Ok(ChannelUserList { users: [ChannelUser { id: "red" }, ChannelUser { id: "blue" }] })
Webhook验证
在您的 仪表板 上,您可以设置 webhook,在特定事件发生后将有效负载 POST 到您的服务器。这些事件包括频道被占用或腾空,成员在存在频道中被添加或删除,或在客户端触发的事件之后。更多详细信息请参阅 https://pusher.com/docs/webhooks。
这个库提供了一种机制,通过检查请求头中的令牌和身份验证签名来验证这些 POST 请求确实来自 Pusher。
fn webhook(&self, key: &str, signature: &str, body: &str)
Argument | Description |
---|---|
key &str |
在 "X-Pusher-Key" 头部提供的密钥 |
signature &str |
在 "X-Pusher-Signature" 头部提供的签名 |
body &str |
请求体 |
返回值 | Description |
---|---|
result Result<Webhook, &str> |
如果 webhook 有效,则 Ok 的值将包含其时间戳和关联事件的 webhook 表示。如果 webhook 无效,将传递 Err 。 |
自定义类型
pusher::Webhook
pub struct Webhook {
pub time_ms: i64,
pub events: Vec<HashMap<String, String>>,
}
示例
pusher.webhook("supplied_key", "supplied_signature", "body")
功能支持
特性 | 支持 |
---|---|
在单个频道上触发事件 | ✔ |
在多个频道上触发事件 | ✔ |
排除事件接收者 | ✔ |
验证私有频道 | ✔ |
身份验证存在频道 | ✔ |
获取应用程序中的频道列表 | ✔ |
获取单个频道的状态 | ✔ |
获取存在频道中的用户列表 | ✔ |
Webhook 验证 | ✔ |
Heroku 扩展支持 | ✔ |
调试 & 日志 | ✔ |
集群配置 | ✔ |
HTTPS | ✔ |
超时 | ✘ |
HTTP 代理配置 | ✘ |
HTTP KeepAlive | ✘ |
辅助功能
这些辅助函数已实现,以确保仅当与 HTTP API 的交互不会失败时才发生,例如 频道命名约定。
辅助功能 | 支持 |
---|---|
频道名称验证 | ✔ |
每个触发器限制为 10 个频道 | ✔ |
限制事件名称长度为 200 个字符 | ✔ |
开发库
请随意 fork 这个仓库,以任何您喜欢的任何方式改进它,并发送给我们一个 pull request :)
运行测试
只需输入
$ cargo test
许可证
此代码可在 MIT 许可证条款下免费使用。
待办事项
- 审查不同字符串类型的使用。
- 更多测试覆盖率
依赖项
~10–14MB
~272K SLoC