简体   繁体   中英

Different instances of the static list of web sockets in ASP.NET on Azure

When I use the static list of web sockets, sometimes for different calls the values of static field are different.

How it should work:

  • When I open some HTML pages using web sockets (WebSocketHandler.ashx), any message sent from the page comes to all pages.
  • When I call the API, the message "Hello from API" also comes to all pages.

How it actually works (on Azure):

  • Sometimes it works fine
  • But sometimes messages from the first page comes only to the first one, and from the second page comes only to the second one, and when I call the API - variable isWebSocketInit = false (this means _webSockets = null)

So can't I use a static variable to store web sockets? Then where to keep a list of sockets? Or how can I do that a static field has always had the same value?

WebSocketHandler.ashx:

private static List<WebSocket> _webSockets;

public void ProcessRequest(HttpContext context)
{
  if (context.IsWebSocketRequest)
    context.AcceptWebSocketRequest(WebSocketRequest);
}

private async Task WebSocketRequest(AspNetWebSocketContext context)
{
  var webSocket = context.WebSocket;
  _webSockets = new List<WebSocket>();
  _webSockets.Add(webSocket); // simplified by removing EnterWriteLock, ExitWriteLock
  try
  {
    while (true)
    {
      var arraySegment = new ArraySegment<byte>(new byte[1024]);
      var result = await _webSocket.ReceiveAsync(arraySegment, CancellationToken.None);
      SendToAll(result);
    }
  }
  catch { _webSockets.Remove(webSocket); }
}

public static bool SendToAll(ArraySegment<byte> arraySegment)
{
  if (_webSockets == null)
    return false;
  foreach (var webSocket in _webSockets.ToList()) // simplified
    try
    {
      if (webSocket.State == WebSocketState.Open)
        webSocket.SendAsync(arraySegment, WebSocketMessageType.Text, true, CancellationToken.None).Wait();
    }
    catch { _webSockets.Remove(webSocket); } // simplified
  return true;
}

public static bool SendToAll(string text)
{
    return Send(new ArraySegment<byte>(Encoding.UTF8.GetBytes(text)));
}

APIHandler.ashx:

var isWebSocketInit = WebSocketHandler.SendToAll("Hello from API");

I noticed that in the scaling settings of the Azure portal was selected 2 Instances .

Selecting 1 Instance resolved the problem.

manage.windowsazure.comWeb apps<My site>ScaleInstance Count1 Instance

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM