如何使用 System.Net.WebSockets 发送和接收碎片数据

How to send and receive fragmented data with System.Net.WebSockets

我正在寻找有关当传输的消息大于分配的缓冲区时如何正确使用 WebSocket.ReceiveAsync()WebSocket.SendAsync() 碎片数据的参考。

以下是我正在使用的方法。不确定它们是否涵盖所有情况,但目前对我有用。将感谢任何改进提示。

分配缓冲区

const int bufferSize = 1024;
readonly byte[] receiveBuffer = new byte[bufferSize];
readonly byte[] sendBuffer = new byte[bufferSize];

Wait/Receive留言

async Task<string> WaitMessageAsync (CancellationToken token)
{
    using var stream = new MemoryStream();
    var segment = new ArraySegment<byte>(receiveBuffer);
    var result = default(WebSocketReceiveResult);
    do
    {
        result = await WebSocket.ReceiveAsync(segment, token);
        if (result.MessageType == WebSocketMessageType.Close)
            throw new OperationCanceledException();
        stream.Write(segment.Array, segment.Offset, result.Count);
    } while (!result.EndOfMessage);
    return Encoding.UTF8.GetString(stream.ToArray());
}

发送消息

async Task SendMessageAsync (string message, CancellationToken token)
{
    var messageLength = message.Length;
    var messageCount = (int)Math.Ceiling((double)messageLength / bufferSize);
    for (var i = 0; i < messageCount; i++)
    {
        var offset = bufferSize * i;
        var count = bufferSize;
        var lastMessage = i + 1 == messageCount;
        if (count * (i + 1) > messageLength)
            count = messageLength - offset;
        var segmentLength = Encoding.UTF8.GetBytes(message, offset, count, sendBuffer, 0);
        var segment = new ArraySegment<byte>(sendBuffer, 0, segmentLength);
        await WebSocket.SendAsync(segment, WebSocketMessageType.Text, lastMessage, token);
    }
}

关闭连接

以正确的方式关闭连接(握手):

WebSocket.CloseOutputAsync(WebSocketCloseStatus.NormalClosure, "", token);