Search code examples
c#clientwebsocket

ClientWebSocket example hangs


The example shown on the following page doesn't work: Using c# ClientWebSocket with streams

It hangs on the following line:

await ws.ConnectAsync(serverUri, CancellationToken.None);

It appears the connection is not made.

Please indicate the simplest modification to make the following code work. I do not wish to use any 3rd party tools or libraries.

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

Solution

  • You are correct. You don't need to add any header in order to use wss://echo.websocket.org/. Your code run just fine at my end. But I'll suggest one improvement to include timeout for your ConnectAsync, SendAsync and ReceiveAsync calls so that it do not get stuck for long.

    I have restricted code to call SendAsync to just 5 times so that its easier to verify output.

    [Edited:] Include logic to receive complete response by calling `ReceiveAsync multiple times.

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

    Output on command prompt:

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