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

            if (!context.Request.Path.HasValue)
            {
                return;
            }
            string path = context.Request.Path;

            string[] pathArray  = path.Split("/");
            string   sessionKey = pathArray[1];

            if (string.IsNullOrEmpty(sessionKey))
            {
                return;
            }

            WebsocketSessionPeer peer = await SessionService.JoinSession(context, "stream", sessionKey);

            await Receive(peer.Socket, async (result, buffer) =>
            {
                if (result.MessageType == WebSocketMessageType.Text)
                {
                    await((WebsocketSessionService)SessionService).ReceiveMessage(sessionKey, peer, result, buffer);
                    return;
                }
                else if (result.MessageType == WebSocketMessageType.Binary)
                {
                    await SessionService.ReceiveBinary(sessionKey, peer, result, buffer);
                    return;
                }
                else if (result.MessageType == WebSocketMessageType.Close)
                {
                    WebsocketSession targetSession = SessionService.GetSessionByKey(sessionKey);
                    string hostId = targetSession.GetAttributeValue <string>("hostId");

                    // if the host quit, kill the session
                    if (peer.Token.PeerId == hostId)
                    {
                        await SessionService.EndSession(sessionKey);
                        return;
                    }

                    // otherwise, disconnect and alert host that someone has disconnected
                    await targetSession.RemovePeer(peer.Token.PeerId);
                    Models.WebsocketSessionUpdate[] updates         = WebsocketSessionService.CreatePeerUpdates(Models.WebsocketSessionUpdateStatus.Disconnect, peer.Token);
                    Models.WebsocketSessionMessageResponse response = WebsocketSessionService.CreateWebsocketResponseMessage(Models.WebsocketSessionMessageType.StatusUpdates, updates);
                    SessionService.SendMessageToPeers(sessionKey, peer.Token.PeerId, response);
                }
            });

            await _next.Invoke(context);
        }
 public WebsocketSessionMiddleware(RequestDelegate next, ILogger <WebsocketSessionMiddleware> logger, WebsocketSessionService socketSessionService)
 {
     _next          = next;
     Logger         = logger;
     SessionService = socketSessionService;
 }