c# - Web 套接字在一段时间后停止响应

标签 c# websocket windows-services slack slack-api

我有一个 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套接字协议(protocol)定义了特殊的Ping帧和相应的Pong帧,您应该使用它们来避免问题中描述的情况。您应该不时地发送 Ping 帧并等待(在一定的超时时间内)服务器响应 Pong 帧。如果它在给定的超时时间内没有响应 - 假设连接已断开并重新连接。

据我所知 - 您使用的库不会代表您自动发送 ping 请求。但是,它允许您通过 Ping 方法来执行此操作。

您需要配置超时

ws.WaitTime = TimeSpan.FromSeconds(5);

然后,时不时地(例如,当您在过去 X 秒内没有收到任何新消息时),执行以下操作:

bool isAlive = ws.Ping();

还有一个 bool 属性具有相同的作用:

bool isAlive = ws.IsAlive;

这是一个阻塞调用(以上均为阻塞调用)。如果服务器在 ws.WaitTime 间隔期间回复 Pong,则返回 true,否则返回 false。然后你就可以采取相应的行动。

关于c# - Web 套接字在一段时间后停止响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50530504/

相关文章:

java - JavaExe下Windows服务启动失败: Updated

c# - Razor View 看不到外部组件

c# - 异常的 WCF 客户端行为

c# - 检查列表中的所有元素是否在其属性之一中都有值 - 这可以在一行中完成吗?

rest - "WebSocket"和 "REST API"之间有何不同

c# - 没有调用 Windows 服务 OnStart 的原因可能是什么?

c# - 我应该调用 GC.Collect

Laravel-echo-server , net::ERR_CONNECTION_TIMED_OUT

java - 使用 websocket javascript 客户端发送文件

C# Windows 服务 SqlCommand 挂起