#tcp-udp #tcp-server #client-server #stream #networking #message #communication

net-stream

为Rust客户端/服务器TCP和UDP网络提供类型化流

2个版本

0.1.1 2023年7月30日
0.1.0 2023年7月29日

#26 in #tcp-server

28 每月下载次数

MIT/Apache

1MB
1.5K SLoC

Logo

NetStream - 为Rust客户端/服务器TCP和UDP网络提供类型化流

NetStream是一个Rust库,它为类型化的TCP和UDP流提供网络抽象。它简化了编写可以在网络上以类型安全的方式发送和接收数据的客户端和服务器实现的过程。

使用NetStream,您可以使用Rust结构体定义服务器和客户端将发送和接收的消息。该库处理所有底层网络细节,因此您可以专注于编写易于推理的高级、类型安全代码。封装和序列化是自动处理的。目前,消息使用bincode进行序列化,但这是一个实现细节,可能会发生变化。

NetStream可用于构建多人游戏、分布式系统或介于两者之间的任何东西。这是一个目前作为爱好项目,不建议用于生产环境。尽管如此,我们欢迎社区提供的反馈、贡献和错误报告。

使用方法

要开始使用NetStream,首先通过为结构体实现net_stream::MessageTypes特性来定义您的消息类型

#[derive(Debug, Clone)]
struct MessageTypes;

// These types represent the messages sent and received over TCP and UDP, respectively.
impl net_stream::MessageTypes for MessageTypes {
    // Message types for server/client communication over TCP.
    type TcpToServer = TcpToServer;
    type TcpFromServer = TcpFromServer;

    // No UDP messages used in this example.
    type UdpToServer = ();
    type UdpFromServer = ();
}

TcpToServer表示通过TCP从客户端(对等方)发送到服务器的消息类型。在这个例子中,它有一个单一的重构Message(String),表示客户端发送的聊天消息。

#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
enum TcpToServer {
    /// Send message to chat room.
    Message(String),
}

TcpFromServer表示通过TCP从服务器发送到客户端(对等方)的消息类型。在这个例子中,它是一个枚举,用于表示聊天服务器上发生的事件,如新用户连接或新消息。

#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
enum TcpFromServer {
    /// Welcome message.
    Welcome(WelcomeMessage),

    /// New user connected.
    UserConnect(User),

    /// User disconnected.
    UserDisconnect(User),

    /// New message posted to the chat room.
    NewMessage(String),
}

WelcomeMessageUser类型创建结构体。通过定义这些消息类型并实现net_stream::MessageTypes特性,您为服务器和客户端实现创建了一个类型化接口。序列化和封装是自动处理的。

使用方法:服务器

启动服务器

let config = net_stream::server::Config::default();
let (server_handle, mut events) = net_stream::server::start::<MessageTypes>(socket_addr, socket_addr, config).await?;

在循环中处理事件

// Main server loop.
while let Some(ev) = events.next().await {
    // Handle server event
    match ev {
        net_stream::server::event::Event::NewPeer(new_peer) => {
            // New client has connected to the server.
        }
        net_stream::server::event::Event::TcpMessage(tcp_message) => {
            // Message received from one of the connected clients over TCP.
        }
        net_stream::server::event::Event::UdpMessage(udp_message) => {
            // Message received from one of the connected clients over UDP.
        }
        net_stream::server::event::Event::PeerDisconnect(peer_disconnect) => {
            // A client has voluntarily disconnected or has been dropped by the server.
        }
    }
}

使用server_handle执行操作,例如向连接的客户端发送消息

// Send a message to a single connected client on TCP.
server_handle.message_peer_tcp(new_peer.peer_uid, TcpFromServer::Welcome(WelcomeMessage {
    // (...)
}));

或将消息发送给所有连接的客户端

// Broadcast a message to all connected clients
server_handle.announce_tcp(TcpFromServer::NewMessage(String::from("message")));

使用方法:客户端

连接到服务器

let (mut handle, mut events) = net_stream::client::connect::<MessageTypes>("my.server.com").await?;

处理从服务器接收到的消息

while let Some(ev) = events.next().await {
    match ev {
        net_stream::client::event::Event::TcpMessage(msg) => {
            // Handle message received from server over TCP.
        }
        net_stream::client::event::Event::UdpMessage(msg) => {
            // Handle message received from server over UDP.
        }
        net_stream::client::event::Event::CanSendUdpMessages => {
            // This event simply indicates that a test message sent from client to server over UDP has reached the server.
            // This lets you know that there is no firewall blocking the UDP messages in this direction.
        }
        net_stream::client::event::Event::CanReceiveUdpMessages => {
            // This event simply indicates that a test message sent from server to client over UDP has reached the client.
            // This lets you know that there is no firewall blocking the UDP messages in this direction.
        }
    }
}

使用handle向服务器发送消息

if let Err(err) = handle.send_message_tcp(TcpToServer::Message(String::from("Hello!"))) {
    log::error!("{:?}", err);
}

查看示例以获取更多详细信息。

依赖项

~5–17MB
~174K SLoC