c# - Web 套接字在一段时间后停止响应
问题描述
我有一个 Windows 服务,它使用 websocket(来自http://sta.github.io/websocket-sharp/)连接到 Slack 并监视消息。
我的连接代码如下所示:
ws = new WebSocket(connection.Url);
ws.OnMessage += async (sender, e) =>
{
var msg = JsonConvert.DeserializeObject<MessageFromSlack>(e.Data);
if (msg.Type == "message" && msg.Text != null && msg.User != UserId)
{
if (userMatcher.IsMatch(msg.Text))
{
await ProcessDirectMessage(msg);
}
await ProcessMessage(msg);
}
if (msg.Type == "channel_joined")
{
await ChannelJoined(msg.ChannelModel.Id);
}
};
ws.OnClose += (sender, e) =>
{
var reason = e.Reason;
var code = e.Code;
System.Diagnostics.Debug.WriteLine($"{code}:{reason}");
};
ws.Connect();
基本上它会等待一条消息,然后如果它被定向到@我的机器人,它会调用ProcessDirectMessage
,如果不是,它会调用ProcessMessage
. 我认为这些功能的细节并不重要(它们会进行一些匹配以寻找关键短语并通过发回消息来响应)。
这一切都很好。一阵子。但经过一段时间(通常超过一天)后,它就会完全停止响应。我的OnMessage
处理程序永远不会被击中。我认为可能正在发生的事情是 websocket 在服务器端关闭,所以我添加了OnClose
处理程序,但这似乎也从未受到影响。
有人知道这里可能发生什么吗?有没有办法让连接保持活动状态,或者在它死时重新连接?
解决方案
根据 TCP 连接的性质 - 检测其消失的唯一可靠方法是向其写入内容。如果您只是在阅读(等待数据到达)-您可以在很长一段时间内这样做,而另一方已经死了很长时间。如果另一方没有优雅地关闭连接(这涉及一些 TCP 数据包的交换),就会发生这种情况。
Web 套接字协议定义了特殊的 Ping 帧和相应的 Pong 帧,您应该使用它们来避免问题中描述的情况。您应该不时发送Ping
帧并等待(一定的超时)服务器以Pong
帧响应。如果它在给定的超时时间内没有响应 - 假设连接已死并重新连接。
据我所知 - 您使用的库不会自动代表您发送 ping 请求。Ping
但是,它允许您通过方法来做到这一点。
您需要配置超时
ws.WaitTime = TimeSpan.FromSeconds(5);
然后,不时地(例如 - 当您在过去 X 秒内没有收到任何新消息时),请执行以下操作:
bool isAlive = ws.Ping();
还有一个布尔属性可以做同样的事情:
bool isAlive = ws.IsAlive;
这是一个阻塞调用(以上两者)。如果服务器在间隔Pong
期间回复,则返回 true,否则返回ws.WaitTime
false。然后你可以采取相应的行动。
推荐阅读
- android - java.lang.IllegalArgumentException: 南纬超过北纬 (23.029011581089936 > 23.0060917)
- node.js - 自动迁移创建数据库名称“未定义”,在 loopback-connector-cassandra 中的“未定义”数据库中创建表
- javascript - 卸载或卸载扩展程序时,Chrome Native Messaging 退出 NodeJS 主机
- sql - 在员工领取高薪的部门工作的员工姓名
- flutter - 颤振:处理 File.path 空/空
- gemfire - Gemfire 9.8.4 的主机要求
- c# - .net如何在zipfile中包含目录和文件关系
- ngxs - ngxs 实验室 immer 要求完整状态?
- sql - 如何查找 SQL 数据库信息
- php - 如何在 php 中动态设计表格,在 td 和数据之后有 3 行