title: System.Net.WebSockets.ClientWebSocket no reliably working?
body: <p>I am implementing passing a web socket back from our api according to this url here;</p>
  
  <p><a href="http://blogs.msdn.com/b/youssefm/archive/2012/07/17/building-real-time-web-apps-with-asp-net-webapi-and-websockets.aspx" rel="nofollow noreferrer">http://blogs.msdn.com/b/youssefm/archive/2012/07/17/building-real-time-web-apps-with-asp-net-webapi-and-websockets.aspx</a></p>
  
  <p>Now the idea is that the user will register for a web socket. This is done and works using the following code;</p>
  
  <pre><code>    [HttpGet]
      [Route("getsocket")]
      public HttpResponseMessage GetWebSocket()
      {
          HttpContext.Current.AcceptWebSocketRequest(new TestWebSocketHandler());
          return Request.CreateResponse(HttpStatusCode.SwitchingProtocols);
      }
  </code></pre>
  
  <p>Then they make a call to the api to begin doing some specific functions, which will then report with message back down the same websocket.</p>
  
  <pre><code>    private static WebSocketWrapper _socket;
  
      [HttpGet]
      [Route("begin")]
      public async Task&lt;IHttpActionResult&gt; StartRunning(string itemid)
      {
          try
          {
              if (_socket == null ||
                  _socket.State() == WebSocketState.Aborted ||
                  _socket.State() == WebSocketState.Closed ||
                  _socket.State() == WebSocketState.None)
              {
                  _socket = WebSocketWrapper.Create("wss://localhost:44301/api/v1/testcontroller/getsocket");
  
                  _socket.OnConnect(OnConnect);
                  _socket.OnDisconnect(OnDisconnect);
                  _socket.OnMessage(OnMessage);
  
                  await _socket.ConnectAsync();
              }
              //builds first message to be sent and sends it
              _socket.QueueMessage(firstTest);
          }
          catch(Exception ex)
          {
              //logs error
          }
  
          return Ok();
      }
  </code></pre>
  
  <p>So effectively the client cretes a new websocket connected to the server. They then call the second message to trigger the server to start a number of tests on the device passed. The server start the tests and broadcast the messages back down the socket (the json message model contains the deviceid, so the client can filter for relevent messages). </p>
  
  <p>When they receive a message the client will then acknowledge it and the next test is done etc. </p>
  
  <p>Now it works the first time I run it (after compilation). However, I want to be able to have multiple client connect to the websocket list (the solution is tabulated and the tests it will run may take a while, so its possible multiple tests will be ran at any one time). So I think it has something to do with the static WebSocketWrapper instance.</p>
  
  <p>However, they have asked that a single websocket be used on the server, with a list of the devices being listened for. So in effect all messages are sent to all clients from the one server connection. The clients then filter out the messages they want to listen to based on the deviceid they pass.</p>
  
  <p>When I try re-running, ore running a second test, Which is basically calling the getwebsocket and then the begin method, the code runs without error, but the onopen method never gets called? Its as though the socket just doesnt fire up?</p>
  
  <p>Unfortunately we cannot use signalr as this is not specified</p>
  
  <p>For reference the socket wrapper class is</p>
  
  <p>public class WebSocketWrapper
          {
              private const int ReceiveChunkSize = 2048;
              private const int SendChunkSize = 2048;</p>
  
  <pre><code>        private readonly ClientWebSocket _ws;
          private readonly Uri _uri;
          private readonly CancellationTokenSource _cancellationTokenSource = new CancellationTokenSource();
          private readonly CancellationToken _cancellationToken;
  
          private Action&lt;WebSocketWrapper&gt; _onConnected;
          private Action&lt;TestResultModel, WebSocketWrapper&gt; _onMessage;
          private Action&lt;WebSocketWrapper&gt; _onDisconnected;
  
          //private static Queue&lt;TestResultModel&gt; _messageQueue = new Queue&lt;TestResultModel&gt;();
          private static BlockingCollection&lt;TestResultModel&gt; _messageQueue = new BlockingCollection&lt;TestResultModel&gt;();
  
          protected WebSocketWrapper(string uri)
          {
              _ws = new ClientWebSocket();
              _ws.Options.KeepAliveInterval = TimeSpan.FromSeconds(30);
              _uri = new Uri(uri);
              _cancellationToken = _cancellationTokenSource.Token;
          }
  
          /// &lt;summary&gt;
          /// Creates a new instance.
          /// &lt;/summary&gt;
          /// &lt;param name="uri"&gt;The URI of the WebSocket server.&lt;/param&gt;
          /// &lt;returns&gt;&lt;/returns&gt;
          public static WebSocketWrapper Create(string uri)
          {
              return new WebSocketWrapper(uri);
          }
  
          /// &lt;summary&gt;
          /// Get the current state of the socket
          /// &lt;/summary&gt;
          /// &lt;returns&gt;WebSocketState of the current _ws&lt;/returns&gt;
          public WebSocketState State()
          {
              return _ws.State;
          }
  
          /// &lt;summary&gt;
          /// Disconnects from the websocket
          /// &lt;/summary&gt;
          public async Task DisconnectAsync()
          {
              try
              {
                  await _ws.CloseOutputAsync(
                      WebSocketCloseStatus.NormalClosure,
                      "Server has been closed by the disconnect method",
                      _cancellationToken);
                  CallOnDisconnected();
              }
              catch(Exception ex)
              {
                  throw ex;
              }
              finally
              {
                  _ws.Dispose();
              }
          }
  
          /// &lt;summary&gt;
          /// Connects to the WebSocket server.
          /// &lt;/summary&gt;
          /// &lt;returns&gt;&lt;/returns&gt;
          public async Task&lt;WebSocketWrapper&gt; ConnectAsync()
          {
              try
              {
                  await _ws.ConnectAsync(_uri, _cancellationToken);
              }
              catch(Exception ex)
              {
  
              }
  
             CallOnConnected();
  
              RunInTask(() =&gt; ProcessQueueAsync());
              RunInTask(() =&gt; StartListen());
  
              return this;
          }
  
          /// &lt;summary&gt;
          /// Set the Action to call when the connection has been established.
          /// &lt;/summary&gt;
          /// &lt;param name="onConnect"&gt;The Action to call.&lt;/param&gt;
          /// &lt;returns&gt;&lt;/returns&gt;
          public WebSocketWrapper OnConnect(Action&lt;WebSocketWrapper&gt; onConnect)
          {
              _onConnected = onConnect;
              return this;
          }
  
          /// &lt;summary&gt;
          /// Set the Action to call when the connection has been terminated.
          /// &lt;/summary&gt;
          /// &lt;param name="onDisconnect"&gt;The Action to call&lt;/param&gt;
          /// &lt;returns&gt;&lt;/returns&gt;
          public WebSocketWrapper OnDisconnect(Action&lt;WebSocketWrapper&gt; onDisconnect)
          {
              _onDisconnected = onDisconnect;
              return this;
          }
  
          /// &lt;summary&gt;
          /// Adds a message to the queu for sending
          /// &lt;/summary&gt;
          /// &lt;param name="message"&gt;&lt;/param&gt;
          public void QueueMessage(TestResultModel message)
          {
              //_messageQueue.Enqueue(message);
              _messageQueue.Add(message);
          }
  
          /// &lt;summary&gt;
          /// returns the size of the current message queue.
          /// Usefult for detemning whether or not an messages are left in queue before closing
          /// &lt;/summary&gt;
          /// &lt;returns&gt;&lt;/returns&gt;
          public int QueueCount()
          {
              return _messageQueue.Count;
          }
  
          /// &lt;summary&gt;
          /// Processes the message queue in order
          /// &lt;/summary&gt;
          public async Task ProcessQueueAsync()
          {
              try
              {
                  foreach(var current in _messageQueue.GetConsumingEnumerable())
                  {
                      await SendMessageAsync(current);
                  }
              }
              catch(Exception ex)
              {
                  //TODO
              }
          }
  
          /// &lt;summary&gt;
          /// Set the Action to call when a messages has been received.
          /// &lt;/summary&gt;
          /// &lt;param name="onMessage"&gt;The Action to call.&lt;/param&gt;
          /// &lt;returns&gt;&lt;/returns&gt;
          public WebSocketWrapper OnMessage(Action&lt;TestResultModel, WebSocketWrapper&gt; onMessage)
          {
              _onMessage = onMessage;
              return this;
          }
  
          /// &lt;summary&gt;
          /// Send a message to the WebSocket server.
          /// &lt;/summary&gt;
          /// &lt;param name="message"&gt;The message to send&lt;/param&gt;
          public async Task SendMessageAsync(TestResultModel result)
          {
              if (_ws.State != WebSocketState.Open)
              {
                  throw new Exception("Connection is not open.");
              }
  
              var message = JsonConvert.SerializeObject(result);
              var messageBuffer = Encoding.UTF8.GetBytes(message);
              var messagesCount = (int)Math.Ceiling((double)messageBuffer.Length / SendChunkSize);
  
              for (var i = 0; i &lt; messagesCount; i++)
              {
                  var offset = (SendChunkSize * i);
                  var count = SendChunkSize;
                  var lastMessage = ((i + 1) == messagesCount);
  
                  if ((count * (i + 1)) &gt; messageBuffer.Length)
                  {
                      count = messageBuffer.Length - offset;
                  }
  
                  await _ws.SendAsync(new ArraySegment&lt;byte&gt;(messageBuffer, offset, count), WebSocketMessageType.Text, lastMessage, _cancellationToken);
              }
          }
  
          private async Task StartListen()
          {
              var buffer = new byte[ReceiveChunkSize];
              //part of a big hack, temporary solution
              string prevResult = "";
  
              try
              {
                  while (_ws.State == WebSocketState.Open)
                  {
                      var stringResult = new StringBuilder();
  
                      WebSocketReceiveResult result;
  
                      do
                      {
                          result = await _ws.ReceiveAsync(new ArraySegment&lt;byte&gt;(buffer), _cancellationToken);
  
  
                          if (result.MessageType == WebSocketMessageType.Close)
                          {
                              await _ws.CloseAsync(WebSocketCloseStatus.NormalClosure, string.Empty, CancellationToken.None);
                              CallOnDisconnected();
                          }
                          else
                          {
                              var str = Encoding.UTF8.GetString(buffer, 0, result.Count);
                              stringResult.Append(str);
                          }
                      } while (!result.EndOfMessage);
  
  
                      if (!prevResult.Equals(stringResult.ToString()))
                      {
                          prevResult = stringResult.ToString();
                          CallOnMessage(stringResult);
                      }
  
                  }
              }
              catch (Exception ex)
              {
                  CallOnDisconnected();
              }
              finally
              {
                  _ws.Dispose();
              }
          }
  
          private void CallOnMessage(StringBuilder stringResult)
          {
              if (_onMessage != null)
              {
                  try
                  {
                      var message = JsonConvert.DeserializeObject&lt;TestResultModel&gt;(stringResult.ToString());
                      RunInTask(() =&gt; _onMessage(message, this));
                  }
                  catch (Exception ex)
                  {
                      //Ignore any other messages not TestResultModel
                  }
              }
          }
  
          private void CallOnDisconnected()
          {
              if (_onDisconnected != null)
                  RunInTask(() =&gt; _onDisconnected(this));
          }
  
          private void CallOnConnected()
          {
              if (_onConnected != null)
                  RunInTask(() =&gt; _onConnected(this));
          }
  
          private static Task RunInTask(Action action)
          {
              return Task.Factory.StartNew(action);
          }
      }
  </code></pre>
  
  <p>As an update please see the debug screen taken when trying to call the websocket for the second time. As you can see it appears to be in the aborted state? (on first run obviousl its null). Any ideas?</p>
  
  <p><a href="https://i.stack.imgur.com/oTmpD.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/oTmpD.png" alt="Screen Shot of Socket Code Running"></a></p>