public virtual async Task InvokeAsync(HttpContext context)
        {
            try
            {
                if (!context.WebSockets.IsWebSocketRequest)
                {
                    return;
                }

                var userId   = context.Request.GetHeaderValue("UserId");
                var userName = context.Request.GetHeaderValue("UserName");
                ConnectionAborted abortStatus = ConnectionAborted.None;

                if (string.IsNullOrEmpty(userId.ToString()))
                {
                    abortStatus = ConnectionAborted.UserIdNotFound;
                }
                else if (string.IsNullOrEmpty(userName))
                {
                    abortStatus = ConnectionAborted.UserNameNotFound;
                }

                var info = new WSUserInfo()
                {
                    Id   = userId,
                    Name = userName
                };

                await InvokeWSAsync(context, info, abortStatus);
            }
            catch (Exception ex)
            {
                Logger.LogError(ex, "An error on opening connection of WebSocket to the server");
            }
        }
        protected async Task InvokeWSAsync(HttpContext context, WSUserInfo userInfo, ConnectionAborted abortStatus = ConnectionAborted.None)
        {
            try
            {
                await WebSocketHub.WSManager.RemoveWebSocketIfExists(userInfo.Id);

                var socket = await context.WebSockets.AcceptWebSocketAsync();

                if (abortStatus == ConnectionAborted.None)
                {
                    await WebSocketHub.OnConnectedAsync(socket, userInfo);

                    await Receive(socket, async (result, buffer) =>
                    {
                        if (result.MessageType == WebSocketMessageType.Binary)
                        {
                            await WebSocketHub.ReceiveMessageAsync(socket, Encoding.UTF8.GetString(buffer, 0, result.Count));
                        }
                        else
                        {
                            await WebSocketHub.OnDisconnectedAsync(userInfo.Id);
                        }
                        return;
                    });
                }
                else
                {
                    await WebSocketHub.WSManager.AbortConnection(socket, abortStatus);
                }
            }
            catch
            {
                throw;
            }
        }
        public override async Task InvokeAsync(HttpContext context)
        {
            try
            {
                if (!context.WebSockets.IsWebSocketRequest)
                {
                    return;
                }

                var authResult = await context.AuthenticateAsync(JwtBearerDefaults.AuthenticationScheme);

                var               isAuthenticated = authResult.Succeeded && authResult.Principal.Identity.IsAuthenticated;
                object            userId          = isAuthenticated ? authResult.Principal.Claims.SingleOrDefault(c => c.Type == "UserId")?.Value : Guid.NewGuid();
                string            userName        = isAuthenticated ? authResult.Principal.Claims.SingleOrDefault(c => c.Type == ClaimTypes.Name)?.Value : string.Empty;
                ConnectionAborted abortStatus     = ConnectionAborted.None;

                if (!isAuthenticated)
                {
                    abortStatus = ConnectionAborted.TokenExpiredOrInvalid;
                }
                else if (string.IsNullOrEmpty(userId.ToString()))
                {
                    abortStatus = ConnectionAborted.UserIdNotFound;
                }
                else if (string.IsNullOrEmpty(userName))
                {
                    abortStatus = ConnectionAborted.UserNameNotFound;
                }

                var info = new WSUserInfo()
                {
                    Id   = userId,
                    Name = userName
                };

                //Here you able to pass your own subclass instead of WSUserInfo. Note: If you bind your own subclass instead of WSUserInfo, all your Web Socket controllers should be use your passed subclass
                await InvokeWSAsync(context, info, abortStatus);
            }
            catch (Exception ex)
            {
                Logger.LogError(ex, "An error on opening connection of WebSocket to the server");
            }
        }
コード例 #4
0
 /// <summary>
 /// Handles lidgren connection close event (fires Closed event).
 /// </summary>
 public override void OnConnectionClose()
 {
     if (!gracefulClosing && !attemptingReconnection)
     {
         ConnectionInterrupted?.Invoke();
         attemptingReconnection = true;
         PausedConnectionResponse response = new PausedConnectionResponse
         {
             ReconnectHost = Host,
             ReconnectPort = Port
         };
         while (!gracefulClosing && failures < RetryAttempts)
         {
             response.FailedAttempts = failures;
             ConnectionPaused?.Invoke(response);
             if (response.Abort)
             {
                 break;
             }
             NetConnection newConnection = Client.Connect(response.ReconnectHost, response.ReconnectPort);
             try
             {
                 newConnection.WaitForConnectionToOpen();
                 RestoreConnection(newConnection, response);
                 ConnectionRestored?.Invoke();
                 return;
             }
             catch (ConnectionOpenException)
             {
                 failures++;
             }
         }
         ConnectionAborted?.Invoke();
         AbortConnection();
     }
 }