Пример ClientWebSocket зависает - PullRequest
       33

Пример ClientWebSocket зависает

1 голос
/ 11 февраля 2020

Пример, показанный на следующей странице, не работает: Использование c# ClientWebSocket с потоками

Он висит в следующей строке:

await ws.ConnectAsyn c (serverUri, CancellationToken.None);

Похоже, соединение не установлено.

Укажите простейшую модификацию, чтобы следующий код работал. Я не могу sh использовать какие-либо сторонние инструменты или библиотеки.

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));
        }
    }
}

1 Ответ

1 голос
/ 12 февраля 2020

Вы правы. Вам не нужно добавлять какие-либо заголовки, чтобы использовать wss://echo.websocket.org/. Ваш код работает нормально на моем конце. Но я предлагаю одно улучшение, включающее timeout для ваших вызовов ConnectAsync, SendAsync и ReceiveAsync, чтобы они не застревали надолго.

Я ограничил код для вызова SendAsync всего 5 раз, чтобы было легче проверить вывод.

[Отредактировано:] Включите лог c для получения полного ответа, вызывая `ReceiveAsyn c несколько раз.

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
...