• 【一起学Rust | 框架篇 | ws-rs框架】属于Rust的Websocket框架——ws-rs



    前言

    ws-rs实现了MIO的WebSockets RFC6455标准。它允许在单个线程上处理多个连接,甚至可以在同一线程上生成新的客户端连接。这使得WebSockets非常快速且资源高效。API设计抽象了WebSocket协议的底层部分,使开发者可以专注于应用程序代码,而不必担心协议的一致性。


    一、创建项目

    首先还是老规矩,先创建本期内容所需要的工程,由于本期是通信类的Websocket,因此需要准备两个工程,一个server,一个client。

    1. 创建服务端项目

    cargo new ws_rs_server
    
    • 1

    然后添加依赖,将以下内容加入到工程Cargo.toml中,如下图所示

    ws = "0.9.2"
    env_logger = "0.6"
    
    • 1
    • 2

    2. 创建客户端项目

    cargo new ws_rs_client
    
    • 1

    然后添加依赖,同样加上刚才的依赖,

    ws = "0.9.2"
    env_logger = "0.6"
    
    • 1
    • 2

    二、编写测试代码

    1.服务端

    首先是服务端部分的代码,使用该库需要引入ws::listen

    use ws::listen;
    
    • 1

    然后在main中调用,实现监听操作,例如

        // 监听地址并为每个连接调用闭包
        if let Err(error) = listen("127.0.0.1:3012", |out| {
            // 处理程序需要获取out的所有权,因此我们使用move
            move |msg| {
                // 处理在此连接上接收的消息
                println!("服务器收到消息 '{}'. ", msg);
    
                // 使用输出通道发送消息
                out.send(msg)
            }
        }) {
            // 通知用户故障
            println!("创建Websocket失败,原因: {:?}", error);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    listen需要传入两个参数,一个是监听的地址和端口,这里使用的是127.0.0.1:3012,然后就是个匿名函数,传入out,获取out的所有权,然后在其内部使用move关键字自动捕获msg,其中msg就是服务端收到的消息,在服务端开发中,主要处理的就是这部分内容。

    这里处理客户端消息逻辑很简单,

    1. 输出从客户端接收到的消息
    2. 把客户端发送的消息返回

    也就是说,实际上就是个echo,但是还是有点区别的,这个只返回一次。

    2.客户端

    客户端部分需要引入connect用来连接服务端,引入CloseCode来关闭连接。

    use ws::{connect, CloseCode};
    
    • 1

    然后就是在main中调用,首先是connect,其调用方式和serverlisten是一样的,需要传入两个参数,

    1. wss连接,例如ws://127.0.0.1:3012,其中ws://表示使用websocket协议,127.0.0.1是ip地址,3012是端口,值得注意的是要和server相对应,否则会连接失败
    2. 一个闭包匿名函数,传入out

    客户端的闭包匿名函数主要要做两件事,

    1. 发送消息到服务端
    2. 处理来自服务端的消息

    这里的示例代码如下

     // 连接到url并调用闭包
        if let Err(error) = connect("ws://127.0.0.1:3012", |out| {
            // 将WebSocket打开时要发送的消息排队
            if out.send("Hello WebSocket").is_err() {
                println!("Websocket无法初始消息排队")
            } else {
                println!("Client 发送消息 'Hello WebSocket'. ")
            }
    
            // 处理程序需要获取out的所有权,因此我们使用move
            move |msg| {
                // 处理在此连接上接收的消息
                println!("Client 收到消息 '{}'. ", msg);
    
                // 关闭连接
                out.close(CloseCode::Normal)
            }
        }) {
            // 通知用户故障
            println!("Failed to create WebSocket due to: {:?}", error);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    可以看到,这段代码的逻辑是,

    1. 先发送Hello WebSocket到服务端,同时判断发送过程中是否有错,如果发送出错,则输出Websocket无法初始消息排队,发送成功的情况下在客户端界面输出Client 发送消息 'Hello WebSocket'.
    2. 处理来自服务端的消息,可以看到这里和server是高度相似的,收到消息后,输出Client 收到消息 '{}'. ,其中{}是服务端消息的占位符,收到消息后直接断开服务端的连接

    三、 运行效果

    运行服务端

    运行客户端


    总结

    本期学习了Rust的websocket通信框架ws-rs,并且编写了两个官方提供的小案例,通过本期内容的学习,你已学会了使用Rust来编写websocket程序,这个在开发中是具有里程碑意义的,你写的程序从此可以联网进行数据传输,使得程序给用户带来更好的体验,并且会让你的程序变得丰富多彩。

    完整代码

    服务端

    use ws::listen;
    
    fn main() {
        // 初始化日志
        env_logger::init();
    
        // 监听地址并为每个连接调用闭包
        if let Err(error) = listen("127.0.0.1:3012", |out| {
            // 处理程序需要获取out的所有权,因此我们使用move
            move |msg| {
                // 处理在此连接上接收的消息
                println!("服务器收到消息 '{}'. ", msg);
    
                // 使用输出通道发送消息
                out.send(msg)
            }
        }) {
            // 通知用户故障
            println!("创建Websocket失败,原因: {:?}", error);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    客户端

    use ws::{connect, CloseCode};
    
    fn main() {
        // 初始化日志
        env_logger::init();
    
        // 连接到url并调用闭包
        if let Err(error) = connect("ws://127.0.0.1:3012", |out| {
            // 将WebSocket打开时要发送的消息排队
            if out.send("Hello WebSocket").is_err() {
                println!("Websocket无法初始消息排队")
            } else {
                println!("Client 发送消息 'Hello WebSocket'. ")
            }
    
            // 处理程序需要获取out的所有权,因此我们使用move
            move |msg| {
                // 处理在此连接上接收的消息
                println!("Client got message '{}'. ", msg);
    
                // 关闭连接
                out.close(CloseCode::Normal)
            }
        }) {
            // 通知用户故障
            println!("Failed to create WebSocket due to: {:?}", error);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    本人创建了一起学Rust社区,欢迎各位对rust感兴趣的朋友加入

     http://t.csdn.cn/AsEZ9 
    
    • 1
  • 相关阅读:
    火山引擎 DataTester 背后,抖音的名字原来是 AB 测试来的
    06JavaIntelliJ IDEA 的下载/安装/设置/使用
    北京映急物流有限公司 面试.net软件工程师岗位
    OSGeoLive 15.0 版本发布
    C++:拷贝构造函数的初始化列表
    正确主动关闭连接
    清理n天前的文件和目录
    教你用Python制作BMI计算器
    【Opencv工程开发所用类】VideoTracker 视频摄像头
    linux批量杀进程命令
  • 原文地址:https://blog.csdn.net/weixin_47754149/article/details/127521053