C# 使用WebSocketClient ReceiveAsync和buffer的正确方法是什么?

C# 使用WebSocketClient ReceiveAsync和buffer的正确方法是什么?,c#,asynchronous,websocket,C#,Asynchronous,Websocket,我想在C#for中创建一个Bot类,让服务为我们的公司创建和使用消息。为了使我们的服务易于使用,我只使用Connect()调用了它,并使用事件让调用方知道何时有消息。这就是它的基本名称: SlackBot bot = new SlackBot(TOKEN); bot.OnReceiveMessage += message => { Console.WriteLine("DELEGATE GOT MESSAGE: '{0}'", message); }; bot.Connect();

我想在C#for中创建一个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或其他东西不断添加字节,直到我得到消息的结尾,然后发送它

看看RFC,我似乎就是这样。与底层TCP和其他网络协议相比,我对WebSocket协议不太熟悉,但如果每次调用
ReceiveAsync()
时您都实际收到了完整的消息,那么结果中似乎不需要
EndOfMessage
属性

还请注意,以
async
/
wait
模式编写代码可能会使您的代码受益:

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构建一个只有在连接实际关闭时才能解决的连续链。

我想过这样做,但我的Connect()中有一个警告(我讨厌警告),它调用receive。我不希望连接是异步的,我希望等待连接完成,然后让它启动我的
OnReceiveMessge()
委托。有没有一种方法可以消除警告,除非忽略它无处不在?@JasonGoemaat:理想情况下,消除警告的方法是继续并使事情
异步
(即包括
Connect()
方法)。也就是说,如果方法返回
void
而不是
Task
,或者将返回值存储在局部变量中(然后忽略),则可以避免出现警告。在某些情况下,这些都是可以接受的替代方案……通常情况下,您不应该忽略警告,但如果您确定行为是您想要的(包括不能等待完成或捕获任务中的异常),那么您可以这样做。