C# 为什么System.Net.WebSocket不基于事件?

C# 为什么System.Net.WebSocket不基于事件?,c#,.net,websocket,C#,.net,Websocket,我想问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!'); }); //

我想问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#
系统.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
}
//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.
}
while(true){
字节[]?缓冲区=新字节[1024*4];
var result=await socket.ReceiveAsync(新的ArraySegment(缓冲区),CancellationToken.None);
字符串消息=Encoding.UTF8.GetString(缓冲区,0,结果.计数);
//这里我可以调用event.Invoke,如果我想把它变成基于事件的
}
我可以理解这可能是因为C#中的WebSocket的抽象级别低于JS,我应该自己实现事件逻辑

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

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

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
}
//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.
}
//只创建一次缓冲区,效率更高
字节[]缓冲区=新字节[1024*4];
while(true)
{
var result=await socket.ReceiveAsync(新的ArraySegment(缓冲区),CancellationToken.None);
if(socket.CloseStatus.HasValue)//套接字是否已关闭?
{
关闭?.Invoke(this,EventArgs.Empty);//关闭事件
打破
}
字符串消息=Encoding.UTF8.GetString(缓冲区,0,结果.计数);
已接收?.调用(此,消息);//您的接收事件。
}

您使用的是原始套接字,如果您想让事件使用库,例如信号器应该处理您想要做的事情