Rust Matrix客户端API库ruma-client-api的使用,实现高效安全的Matrix协议通信与消息处理
ruma-client-api
ruma-client-api 包含用于 Matrix 客户端 API 规范中每个端点请求和响应的可序列化类型。这些类型可以被客户端和服务器代码共享。
安装
在项目目录中运行以下 Cargo 命令:
cargo add ruma-client-api
或者在 Cargo.toml 中添加以下行:
ruma-client-api = "0.20.4"
完整示例
以下是一个使用 ruma-client-api 实现 Matrix 协议通信与消息处理的完整示例:
use ruma_client_api::{
error::Error as RumaError,
r0::{
account::register::{Request as RegisterRequest, Response as RegisterResponse},
session::login::{Request as LoginRequest, Response as LoginResponse},
sync::sync_events::{Request as SyncRequest, Response as SyncResponse},
},
};
use ruma_common::presence::PresenceState;
use ruma_identifiers::{DeviceId, RoomId, UserId};
use ruma_client::{Client, HttpClient};
use std::error::Error;
#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
// 创建 HTTP 客户端
let client = Client::new().await?;
// 1. 注册新用户
let register_request = RegisterRequest::new().username("example_user").password("secure_password");
let register_response: RegisterResponse = client.send_request(register_request).await?;
println!("Registered user: {:?}", register_response.user_id);
// 2. 登录
let login_request = LoginRequest::Password {
identifier: ruma_client_api::r0::session::login::UserIdentifier::MatrixId(register_response.user_id.clone()),
password: "secure_password".to_string(),
device_id: Some(DeviceId::new()),
initial_device_display_name: Some("My Device".to_string()),
};
let login_response: LoginResponse = client.send_request(login_request).await?;
println!("Logged in with access token: {}", login_response.access_token);
// 3. 同步消息
let sync_request = SyncRequest::new(login_response.next_batch.unwrap_or_default())
.set_presence(PresenceState::Online);
let sync_response: SyncResponse = client.send_request(sync_request).await?;
println!("Received sync response with {} rooms", sync_response.rooms.join.len());
// 4. 处理消息
for (room_id, room_info) in sync_response.rooms.join {
println!("Messages in room {}:", room_id);
for event in room_info.timeline.events {
println!("- {:?}", event);
}
}
Ok(())
}
示例说明
- 用户注册:使用
RegisterRequest
创建新用户账户 - 用户登录:使用
LoginRequest
进行密码认证,获取访问令牌 - 消息同步:使用
SyncRequest
获取最新消息和房间状态 - 消息处理:遍历同步响应中的房间和消息事件
这个示例展示了如何使用 ruma-client-api 实现基本的 Matrix 客户端功能,包括用户认证、消息同步和处理。
扩展示例
以下是一个更完整的 Matrix 客户端实现示例,包含房间创建和消息发送功能:
use ruma_client_api::{
r0::{
account::register::{Request as RegisterRequest, Response as RegisterResponse},
session::login::{Request as LoginRequest, Response as LoginResponse},
sync::sync_events::{Request as SyncRequest, Response as SyncResponse},
room::create_room::{Request as CreateRoomRequest, Response as CreateRoomResponse},
message::send_message_event::{Request as SendMessageRequest, Response as SendMessageResponse},
},
};
use ruma_common::presence::PresenceState;
use ruma_identifiers::{DeviceId, RoomId};
use ruma_events::{
room::message::{MessageEventContent, TextMessageEventContent},
EventType,
};
use ruma_client::{Client, HttpClient};
use std::error::Error;
#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
// 初始化客户端
let client = Client::new().await?;
// 1. 用户注册
let register_response: RegisterResponse = client
.send_request(
RegisterRequest::new()
.username("rust_user")
.password("matrix_rs")
)
.await?;
// 2. 用户登录
let login_response: LoginResponse = client
.send_request(LoginRequest::Password {
identifier: ruma_client_api::r0::session::login::UserIdentifier::MatrixId(
register_response.user_id.clone(),
),
password: "matrix_rs".to_string(),
device_id: Some(DeviceId::new()),
initial_device_display_name: Some("Rust Client".to_string()),
})
.await?;
// 3. 创建房间
let create_room_response: CreateRoomResponse = client
.send_request(
CreateRoomRequest::new()
.name("Ruma Test Room")
.visibility(ruma_client_api::r0::room::Visibility::Public)
)
.await?;
println!("Created room: {}", create_room_response.room_id);
// 4. 发送消息
let message_content = MessageEventContent::Text(
TextMessageEventContent::plain("Hello from Ruma client!")
);
let send_message_response: SendMessageResponse = client
.send_request(
SendMessageRequest::new(
create_room_response.room_id.clone(),
EventType::RoomMessage,
&message_content
)
)
.await?;
println!("Sent message with event ID: {}", send_message_response.event_id);
// 5. 同步消息
let sync_response: SyncResponse = client
.send_request(
SyncRequest::new(login_response.next_batch.unwrap_or_default())
.set_presence(PresenceState::Online)
)
.await?;
// 6. 处理同步事件
for (room_id, room_info) in sync_response.rooms.join {
println!("Room {} has {} messages", room_id, room_info.timeline.events.len());
}
Ok(())
}
示例说明
- 用户注册:创建新用户账户
- 用户登录:使用密码认证登录
- 房间创建:创建一个新的公开聊天室
- 消息发送:向新创建的聊天室发送文本消息
- 消息同步:获取最新的消息和房间状态
- 事件处理:处理同步响应中的房间和消息事件
这个扩展示例展示了更完整的 Matrix 客户端功能,包括房间创建和消息发送等高级操作。
许可证
MIT 许可证
1 回复
Rust Matrix客户端API库ruma-client-api的使用
介绍
ruma-client-api是一个用于与Matrix协议服务器交互的Rust客户端API库。它提供了类型安全的接口来构建Matrix客户端应用,支持高效、安全的Matrix协议通信。
Matrix是一个开放标准的去中心化实时通信协议,提供端到端加密的消息传递、VoIP/VoIP通话等功能。ruma-client-api是ruma项目的一部分,专注于客户端API的实现。
主要特性
- 完全类型安全的Matrix API请求和响应
- 支持同步、消息发送、房间管理等核心功能
- 异步/等待支持
- 良好的错误处理
- 可扩展的认证机制
完整示例代码
下面是一个完整的Matrix客户端示例,包含初始化、同步消息、发送消息和处理消息的功能:
use ruma_client_api::{
self,
r0::{
message::create_message_event,
sync::sync_events,
},
ruma_api,
};
use ruma_common::{
api::MatrixVersion,
authentication::AccessToken,
};
use ruma_events::{
room::message::MessageEventContent,
AnyMessageEventContent,
AnySyncRoomEvent,
};
use ruma_identifiers::{RoomId, UserId};
use tokio::time::{sleep, Duration};
#[tokio::main]
async fn main() -> anyhow::Result<()> {
// 1. 初始化客户端
let homeserver_url = "https://matrix.org".parse()?;
let user_id = UserId::parse("@youruser:matrix.org")?;
let access_token = AccessToken::new("your_access_token".to_owned());
let client = ruma_client_api::Client::builder()
.homeserver_url(homeserver_url)
.access_token(access_token)
.build()?;
// 2. 持续同步和处理消息
let mut since = None;
loop {
// 同步消息请求
let request = sync_events::Request::new()
.since(since)
.timeout(Duration::from_secs(30));
match client.send_request(request).await {
Ok(response) => {
since = Some(response.next_batch.clone());
// 处理加入的房间
for (room_id, joined_room) in response.rooms.join {
println!("房间 {} 有新事件", room_id);
// 处理时间线事件
for event in joined_room.timeline.events {
if let Ok(AnySyncRoomEvent::Message(msg_event)) = event.deserialize() {
println!("收到新消息: {:?}", msg_event.content);
// 自动回复
if let Some(sender) = msg_event.sender {
if sender != user_id {
reply_to_message(&client, &room_id, &msg_event.content).await?;
}
}
}
}
}
}
Err(e) => eprintln!("同步错误: {}", e),
}
sleep(Duration::from_secs(5)).await;
}
}
/// 回复消息
async fn reply_to_message(
client: &ruma_client_api::Client,
room_id: &RoomId,
original_content: &MessageEventContent,
) -> anyhow::Result<()> {
let reply_content = match original_content {
MessageEventContent::Text(text) => {
MessageEventContent::text_plain(format!("回复: {}", text.body))
}
_ => MessageEventContent::text_plain("已收到您的消息".to_owned()),
};
let event_content = AnyMessageEventContent::RoomMessage(reply_content);
client
.send_request(create_message_event::Request::new(
room_id.clone(),
format!("txn_{}", chrono::Utc::now().timestamp()),
&event_content,
))
.await?;
Ok(())
}
代码说明
-
客户端初始化:
- 配置Matrix服务器URL、用户ID和访问令牌
- 使用ClientBuilder创建客户端实例
-
消息同步循环:
- 使用sync_events API定期同步新消息
- 维护since token以实现增量同步
- 设置30秒超时防止长轮询阻塞
-
消息处理:
- 解析收到的消息事件
- 过滤出文本消息内容
- 自动回复收到的消息
-
消息发送:
- 构建回复消息内容
- 使用create_message_event API发送消息
- 为每个消息生成唯一的事务ID
使用方法
- 将上述代码保存为main.rs
- 在Cargo.toml中添加依赖:
[dependencies]
ruma-client-api = "0.10"
tokio = { version = "1.0", features = ["full"] }
anyhow = "1.0"
chrono = "0.4"
- 运行程序:
cargo run
注意事项
- 需要替换示例中的homeserver_url、user_id和access_token为实际值
- 程序会持续运行并自动回复收到的消息
- 按Ctrl+C可停止程序
- 生产环境应考虑添加更完善的错误处理和日志记录