如何使用 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);
我正在寻找有关当传输的消息大于分配的缓冲区时如何正确使用 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);