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