使用 WebSocketClient ReceiveAsync 和缓冲区的正确方法是什么?
What is the proper way to use WebSocketClient ReceiveAsync and buffer?
我想在 C# 中为 slack 创建一个机器人 class,让服务为我们公司创建和使用消息。为了让我们的服务更容易使用,我只是用 Connect()
调用它,并使用一个事件让调用者知道何时有消息。基本上是这样称呼它的:
SlackBot bot = new SlackBot(TOKEN);
bot.OnReceiveMessage += message => {
Console.WriteLine("DELEGATE GOT MESSAGE: '{0}'", message);
};
bot.Connect();
Connect()
方法调用内部 Receive()
方法,该方法在每条消息后调用自身:
public delegate void MessageReceivedDelegate(string message);
public event MessageReceivedDelegate OnReceiveMessage;
void Receive()
{
_ReceiveTask = _Client.ReceiveAsync(_ClientBuffer, _CancellationToken);
_ReceiveTask.ContinueWith(twsrr =>
{
WebSocketReceiveResult result = twsrr.Result;
string message = Encoding.ASCII.GetString(_ClientBuffer.Array,
_ClientBuffer.Offset, result.Count);
OnReceiveMessage(message);
Receive();
});
}
所以可接受的最大缓冲区是 64k,我是否需要检查 result.EndOfMessage
并使用 MemoryStream 或其他东西来不断添加字节,直到我收到消息的结尾,然后发送它?
查看 RFC,我似乎就是这种情况。与底层 TCP 和其他网络协议相比,我对 WebSocket 协议不太熟悉,但如果每次调用 ReceiveAsync()
时你实际上收到了一条完整的消息,似乎就不需要 EndOfMessage
属性关于结果。
另请注意,您的代码可以受益于以 async
/await
模式编写:
async Task Receive()
{
WebSocketReceiveResult result = await _Client.ReceiveAsync(_ClientBuffer, _CancellationToken);
if (result.Count != 0 || result.CloseStatus == WebSocketCloseStatus.Empty)
{
string message = Encoding.ASCII.GetString(_ClientBuffer.Array,
_ClientBuffer.Offset, result.Count);
OnReceiveMessage(message);
await Receive();
}
}
或者,如果您愿意,可以将 Receive()
更改为 async
,但将其保留为 void
,不要等待。这是 async
方法的一般规则的一个例外,但它会避免 I/O 构建只有在连接实际关闭时才会解析的延续链。
我想在 C# 中为 slack 创建一个机器人 class,让服务为我们公司创建和使用消息。为了让我们的服务更容易使用,我只是用 Connect()
调用它,并使用一个事件让调用者知道何时有消息。基本上是这样称呼它的:
SlackBot bot = new SlackBot(TOKEN);
bot.OnReceiveMessage += message => {
Console.WriteLine("DELEGATE GOT MESSAGE: '{0}'", message);
};
bot.Connect();
Connect()
方法调用内部 Receive()
方法,该方法在每条消息后调用自身:
public delegate void MessageReceivedDelegate(string message);
public event MessageReceivedDelegate OnReceiveMessage;
void Receive()
{
_ReceiveTask = _Client.ReceiveAsync(_ClientBuffer, _CancellationToken);
_ReceiveTask.ContinueWith(twsrr =>
{
WebSocketReceiveResult result = twsrr.Result;
string message = Encoding.ASCII.GetString(_ClientBuffer.Array,
_ClientBuffer.Offset, result.Count);
OnReceiveMessage(message);
Receive();
});
}
所以可接受的最大缓冲区是 64k,我是否需要检查 result.EndOfMessage
并使用 MemoryStream 或其他东西来不断添加字节,直到我收到消息的结尾,然后发送它?
查看 RFC,我似乎就是这种情况。与底层 TCP 和其他网络协议相比,我对 WebSocket 协议不太熟悉,但如果每次调用 ReceiveAsync()
时你实际上收到了一条完整的消息,似乎就不需要 EndOfMessage
属性关于结果。
另请注意,您的代码可以受益于以 async
/await
模式编写:
async Task Receive()
{
WebSocketReceiveResult result = await _Client.ReceiveAsync(_ClientBuffer, _CancellationToken);
if (result.Count != 0 || result.CloseStatus == WebSocketCloseStatus.Empty)
{
string message = Encoding.ASCII.GetString(_ClientBuffer.Array,
_ClientBuffer.Offset, result.Count);
OnReceiveMessage(message);
await Receive();
}
}
或者,如果您愿意,可以将 Receive()
更改为 async
,但将其保留为 void
,不要等待。这是 async
方法的一般规则的一个例外,但它会避免 I/O 构建只有在连接实际关闭时才会解析的延续链。