【问题标题】:Why are System.Net.WebSockets not event based? [closed]为什么 System.Net.WebSockets 不是基于事件的? [关闭]
【发布时间】:2020-10-23 17:20:19
【问题描述】:

我想问一下 System.Net.WebSockets 不是基于事件的原因是什么。在 JS 中,我只需要订阅事件:

// Create WebSocket connection.
const socket = new WebSocket('ws://localhost:8080');

// Connection opened
socket.addEventListener('open', function (event) {
    socket.send('Hello Server!');
});

// Listen for messages
socket.addEventListener('message', function (event) {
    console.log('Message from server ', event.data);
});

但在 C#System.Net.WebSockets 中,事件根本不存在。如果我想接收消息,我必须这样做:

while (true){
    byte[]? buffer = new byte[1024 * 4];
    var result = await socket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
    string message = Encoding.UTF8.GetString(buffer, 0, result.Count);
    // here I can call event.Invoke if i want to turn it into event-based
}

我可以理解,这可能是因为 C# 中的 WebSockets 的抽象级别比 JS 中的要低,我应该自己实现事件逻辑。

我完全不明白的是连接关闭检测。 System.Net.WebSockets 套接字有一个属性State,其中包含有关套接字当前状态的信息并根据它进行更改。 据我了解,这个属性是我知道套接字是否关闭的唯一方法。为什么我不能只听它的变化?定期轮询此属性真的是我检测套接字状态的唯一选择吗?同样,我可以自己实现逻辑,但会失去有效性(因为轮询)。为什么不能在每次设置此属性时触发一个事件?

【问题讨论】:

  • 你使用的是原始套接字,如果你想让事件使用库,例如​​ Signalr 应该处理你想做的事情

标签: c# .net websocket


【解决方案1】:

WebSockets 基于 TCP 套接字,因此它们实现了与那些相同的逻辑。当套接字关闭并且您有一个循环等待接收时,它将接收 0 个字节并继续,因此,如果您在每次接收后检查套接字是否已关闭,您将立即知道它,如下所示:

//Create the buffer only once, it's more efficient
byte[] buffer = new byte[1024 * 4];

while (true)
{
    
    var result = await socket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);

    if(socket.CloseStatus.HasValue) //Has the socket been closed?
    {
       Closed?.Invoke(this, EventArgs.Empty);//your close event
       break;
    }

    string message = Encoding.UTF8.GetString(buffer, 0, result.Count);
    Received?.Invoke(this, message); //Your receive event.
}

【讨论】:

    猜你喜欢
    • 2013-09-07
    • 2013-05-28
    • 2021-11-22
    • 2019-03-27
    • 1970-01-01
    • 2013-06-05
    • 2014-09-28
    • 1970-01-01
    • 2017-01-27
    相关资源
    最近更新 更多