首页 > 解决方案 > ClientWebSocket 示例挂起

问题描述

下页显示的示例不起作用: Using c# ClientWebSocket with streams

它挂在以下行:

等待 ws.ConnectAsync(serverUri, CancellationToken.None);

似乎没有建立连接。

请指出使以下代码工作的最简单修改。我不想使用任何 3rd 方工具或库。

private static async Task DoClientWebSocket()
{
    using (ClientWebSocket ws = new ClientWebSocket())
    {
        Uri serverUri = new Uri("wss://echo.websocket.org/");
        await ws.ConnectAsync(serverUri, CancellationToken.None);
        while (ws.State == WebSocketState.Open)
        {
            string msg = "hello123";
            ArraySegment<byte> bytesToSend = new ArraySegment<byte>(Encoding.UTF8.GetBytes(msg));
            await ws.SendAsync(bytesToSend, WebSocketMessageType.Text, true, CancellationToken.None);
            ArraySegment<byte> bytesReceived = new ArraySegment<byte>(new byte[1024]);
            WebSocketReceiveResult result = await ws.ReceiveAsync(bytesReceived, CancellationToken.None);
            Console.WriteLine(Encoding.UTF8.GetString(bytesReceived.Array, 0, result.Count));
        }
    }
}

标签: c#clientwebsocket

解决方案


你是对的。您无需添加任何标题即可使用wss://echo.websocket.org/. 你的代码在我结束时运行得很好。但我会建议timeout您的ConnectAsync,SendAsyncReceiveAsync调用包括一项改进,以免它长时间卡住。

我将代码限制SendAsync为仅调用 5 次,以便更容易验证输出。

[已编辑:]包括通过多次调用 `ReceiveAsync 来接收完整响应的逻辑。

private static async Task DoClientWebSocket()
{
    using (ClientWebSocket ws = new ClientWebSocket())
    {
        Uri serverUri = new Uri("wss://echo.websocket.org/");

        //Implementation of timeout of 5000 ms
        var source = new CancellationTokenSource();
        source.CancelAfter(5000);

        await ws.ConnectAsync(serverUri, source.Token);
        var iterationNo = 0;
        // restricted to 5 iteration only
        while (ws.State == WebSocketState.Open && iterationNo++ < 5)
        {
          string msg = "hello0123456789123456789123456789123456789123456789123456789";
          ArraySegment<byte> bytesToSend =
                      new ArraySegment<byte>(Encoding.UTF8.GetBytes(msg));
          await ws.SendAsync(bytesToSend, WebSocketMessageType.Text,
                               true, source.Token);
          //Receive buffer
          var receiveBuffer = new byte[200];
          //Multipacket response
          var offset = 0;
          var dataPerPacket = 10; //Just for example
          while (true)
          {
              ArraySegment<byte> bytesReceived =
                        new ArraySegment<byte>(receiveBuffer, offset, dataPerPacket);
              WebSocketReceiveResult result = await ws.ReceiveAsync(bytesReceived,
                                                            source.Token);
              //Partial data received
              Console.WriteLine("Data:{0}",
                               Encoding.UTF8.GetString(receiveBuffer, offset,
                                                            result.Count));
              offset += result.Count;
              if (result.EndOfMessage)
                    break;
            }
            Console.WriteLine("Complete response: {0}",
                                Encoding.UTF8.GetString(receiveBuffer, 0,
                                                            offset));
        }
    }
}


static void Main(string[] args)
{
    var taskWebConnect = Task.Run(() => DoClientWebSocket());

    taskWebConnect.Wait();
}

命令提示符下的输出:

Data:hello01234
Data:5678912345
Data:6789123456
Data:7891234567
Data:8912345678
Data:9123456789
Complete response: hello0123456789123456789123456789123456789123456789123456789

推荐阅读