使用WebSocketClient ReceiveAsync和缓冲区的正确方法是什么?

时间:2015-02-14 04:16:42

标签: c# asynchronous websocket

我想在C#中为slack创建一个Bot类,让服务为我们公司创建和使用消息。为了方便我们的服务使用,我只需使用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或其他东西来继续添加字节,直到我收到消息结束,然后发送它?

1 个答案:

答案 0 :(得分:1)

看看RFC,对我来说似乎就是这种情况。我对WebSocket协议的熟悉程度低于底层TCP和其他网络协议,但是如果每次调用ReceiveAsync()时你实际上收到了一条完整的消息,那么似乎不需要{{ 1}}结果的属性。

另请注意,您的代码可以通过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方法的一般规则的一个例外,但它可以避免I / O构建一系列延续,只有在连接实际关闭时才能解析。