
文章目录
ws-rs实现了MIO的WebSockets RFC6455标准。它允许在单个线程上处理多个连接,甚至可以在同一线程上生成新的客户端连接。这使得WebSockets非常快速且资源高效。API设计抽象了WebSocket协议的底层部分,使开发者可以专注于应用程序代码,而不必担心协议的一致性。
首先还是老规矩,先创建本期内容所需要的工程,由于本期是通信类的Websocket,因此需要准备两个工程,一个server,一个client。
cargo new ws_rs_server
然后添加依赖,将以下内容加入到工程Cargo.toml中,如下图所示
ws = "0.9.2"
env_logger = "0.6"

cargo new ws_rs_client
然后添加依赖,同样加上刚才的依赖,
ws = "0.9.2"
env_logger = "0.6"
首先是服务端部分的代码,使用该库需要引入ws::listen
use ws::listen;
然后在main中调用,实现监听操作,例如
// 监听地址并为每个连接调用闭包
if let Err(error) = listen("127.0.0.1:3012", |out| {
// 处理程序需要获取out的所有权,因此我们使用move
move |msg| {
// 处理在此连接上接收的消息
println!("服务器收到消息 '{}'. ", msg);
// 使用输出通道发送消息
out.send(msg)
}
}) {
// 通知用户故障
println!("创建Websocket失败,原因: {:?}", error);
}
listen需要传入两个参数,一个是监听的地址和端口,这里使用的是127.0.0.1:3012,然后就是个匿名函数,传入out,获取out的所有权,然后在其内部使用move关键字自动捕获msg,其中msg就是服务端收到的消息,在服务端开发中,主要处理的就是这部分内容。
这里处理客户端消息逻辑很简单,
也就是说,实际上就是个echo,但是还是有点区别的,这个只返回一次。
客户端部分需要引入connect用来连接服务端,引入CloseCode来关闭连接。
use ws::{connect, CloseCode};
然后就是在main中调用,首先是connect,其调用方式和server的listen是一样的,需要传入两个参数,
ws://127.0.0.1:3012,其中ws://表示使用websocket协议,127.0.0.1是ip地址,3012是端口,值得注意的是要和server相对应,否则会连接失败out客户端的闭包匿名函数主要要做两件事,
这里的示例代码如下
// 连接到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);
}
可以看到,这段代码的逻辑是,
Hello WebSocket到服务端,同时判断发送过程中是否有错,如果发送出错,则输出Websocket无法初始消息排队,发送成功的情况下在客户端界面输出Client 发送消息 'Hello WebSocket'. 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);
}
}
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);
}
}
本人创建了一起学Rust社区,欢迎各位对rust感兴趣的朋友加入。
http://t.csdn.cn/AsEZ9
我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t
如果我使用ruby版本2.5.1和Rails版本2.3.18会怎样?我有基于rails2.3.18和ruby1.9.2p320构建的rails应用程序,我只想升级ruby的版本,而不是rails,这可能吗?我必须面对哪些挑战? 最佳答案 GitHub维护apublicfork它有针对旧Rails版本的分支,有各种变化,它们一直在运行。有一段时间,他们在较新的Ruby版本上运行较旧的Rails版本,而不是最初支持的版本,因此您可能会发现一些关于需要向后移植的有用提示。不过,他们现在已经有几年没有使用2.3了,所以充其量只能让更
Transformers开始在视频识别领域的“猪突猛进”,各种改进和魔改层出不穷。由此作者将开启VideoTransformer系列的讲解,本篇主要介绍了FBAI团队的TimeSformer,这也是第一篇使用纯Transformer结构在视频识别上的文章。如果觉得有用,就请点赞、收藏、关注!paper:https://arxiv.org/abs/2102.05095code(offical):https://github.com/facebookresearch/TimeSformeraccept:ICML2021author:FacebookAI一、前言Transformers(VIT)在图
我已经找到了几个使用datamapper的示例,并且能够让它们正常工作。不过,所有这些示例都是针对sqlite数据库的。我正在尝试将数据映射器与postgresql一起使用。我将datamapper中的调用从sqlite3更改为postgres,并且我已经安装了dm-postgres-adapter。但它仍然不起作用。我还需要做什么? 最佳答案 与SQLite不同,PostgreSQL不将数据库存储在单个文件中。在你拥有createdyourdatabase之后,尝试这样的事情:DataMapper.setup:default,{:
我有一个super简单的脚本,它几乎包含了FayeWebSocketGitHub页面上用于处理关闭连接的内容:ws=Faye::WebSocket::Client.new(url,nil,:headers=>headers)ws.on:opendo|event|p[:open]#sendpingcommand#sendtestcommand#ws.send({command:'test'}.to_json)endws.on:messagedo|event|#hereistheentrypointfordatacomingfromtheserver.pJSON.parse(event.d
我经常将预配置的lambda插入可枚举的方法中,例如“map”、“select”等。但是“注入(inject)”的行为似乎有所不同。例如与mult4=lambda{|item|item*4}然后(5..10).map&mult4给我[20,24,28,32,36,40]但是,如果我制作一个2参数lambda用于像这样的注入(inject),multL=lambda{|product,n|product*n}我想说(5..10).inject(2)&multL因为“inject”有一个可选的单个初始值参数,但这给了我......irb(main):027:0>(5..10).inject
我需要使用ActiveMerchant库在我们的一个Rails应用程序中设置支付解决方案。尽管这个问题非常主观,但人们对主要网关(BrainTree、Authorize.net等)的体验如何?它必须:处理定期付款。有能力记入个人帐户。能够取消付款。有办法存储用户的付款详细信息(例如Authotize.netsCIM)。干杯 最佳答案 ActiveMerchant很棒,但在过去一年左右的时间里,我在使用它时发现了一些问题。首先,虽然某些网关可能会得到“支持”——但并非所有功能都包含在内。查看功能矩阵以确保完全支持您选择的网关-http
我想开始使用“Sinatra”框架进行编码,但我找不到该框架的“MVC”模式。是“MVC-Sinatra”模式或框架吗? 最佳答案 您可能想查看Padrino这是一个围绕Sinatra构建的框架,可为您的项目提供更“类似Rails”的感觉,但没有那么多隐藏的魔法。这是使用Sinatra可以做什么的一个很好的例子。虽然如果您需要开始使用这很好,但我个人建议您将它用作学习工具,以对您来说最有意义的方式使用Sinatra构建您自己的应用程序。写一些测试/期望,写一些代码,通过测试-重复:)至于ORM,你还应该结帐Sequel其中(imho
我有一个Rails应用程序,我正在尝试使用acts_as_list插件设置可排序列表。数据库中的位置字段正在更新,但是在呈现页面时,不考虑顺序。我想我是在寻求帮助。这是我的模型...classQuestionMembership:question_membershipsendclassQuestion:question_membershipsacts_as_listend还有给我列表的草率View代码...>true)%>拖放用于重新排序。数据库中QuestionMembership对象的位置值更新,页面实际上正确显示重新排序。问题是在页面重新加载时,它默认返回到它感觉的任何顺序。我认
我正在运行rspec测试以确保两个模型通过has_many和belongs_to相互关联。下面是我的测试。describe"testingforhasmanylinks"dobeforedo@post=Post.new(day:"Day1",content:"Test")@link=Link.new(post_id:@post.id,title:"google",url:"google.com")endit"inthepostmodel"do@post.links.first.url.should=="google.com"endend测试告诉我url是一个未定义的方法。我的测试有什么