public async override Task <WebsocketSessionPeer> JoinSession(HttpContext context, string sessionType, string sessionKey) { WebsocketSession targetSession = GetSessionByKey(sessionKey); if (targetSession == null) { targetSession = this.CreateSession(sessionType, sessionKey); } if (targetSession.GetPeers().Count > 0) { throw new Exception("Unable to join Progress session that already has a subscriber."); } WebSocket socket = await context.WebSockets.AcceptWebSocketAsync(); WebsocketSessionPeer peer = targetSession.AddPeer(socket); targetSession.SetAttribute("hostId", peer.Token.PeerId); // alert requester of their own token WebsocketSessionPeerToken hostToken = peer.Token; WebsocketSessionGreeting greeting = new WebsocketSessionGreeting { SessionKey = sessionKey, HostToken = hostToken, Token = peer.Token }; WebsocketSessionMessageResponse greetingResponse = CreateWebsocketResponseMessage(WebsocketSessionMessageType.Greeting, greeting); SendMessage(peer, greetingResponse); return(peer); }
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 virtual async Task EndSession(string sessionKey) { WebsocketSession session = GetSessionByKey(sessionKey); await session.CloseAsync(WebSocketCloseStatus.NormalClosure, "Closed by the Session Service.", CancellationToken.None); WebsocketSession removedSession; Sessions.TryRemove(sessionKey, out removedSession); KeyValuePair <string, IProcessArtifact[]> preparedSession = GetPreparedSession(sessionKey); if (!preparedSession.Equals(default(KeyValuePair <string, IProcessArtifact[]>))) { PreparedSessions.TryRemove(preparedSession); } }
public async Task UpdateProgress(string sessionKey, int value, int total = -1, string stepId = "") { WebsocketSessionFileProgress response = new WebsocketSessionFileProgress { SessionKey = sessionKey, UnitsCompleted = value, UnitTotal = total, StepID = stepId }; WebsocketSessionUpdate[] updates = CreateProgressUpdates(WebsocketSessionUpdateStatus.Progress, response); WebsocketSession session = GetSessionByKey(sessionKey); string hostId = session.GetAttributeValue <string>("hostId"); WebsocketSessionMessageResponse updateResponse = CreateWebsocketResponseMessage(WebsocketSessionMessageType.StatusUpdates, updates); SendMessage(sessionKey, hostId, updateResponse); }
public virtual async Task SendBinaryToPeers(string sessionKey, WebSocket socket, ArraySegment <byte> buffer) { WebsocketSession session = this.GetSessionByKey(sessionKey); if (session == null) { throw new Exception("Unknown Session requested: " + sessionKey); } foreach (var pair in session.GetPeers()) { if (pair.Value.Socket != socket && pair.Value.Socket.State == WebSocketState.Open) { await SendBinary(pair.Value.Socket, buffer); } } }
public virtual async Task SendMessageToPeers(string sessionKey, WebSocket socket, string message) { WebsocketSession session = this.GetSessionByKey(sessionKey); if (session == null) { throw new Exception("Unknown Session requested: " + sessionKey); } foreach (var pair in session.GetPeers()) { if (pair.Value.Socket != socket && pair.Value.Socket.State == WebSocketState.Open) { await SendMessage(pair.Value.Socket, message); } } }
public async Task SendMessage(string sessionKey, IEnumerable <string> socketIds, string message) { WebsocketSession session = this.GetSessionByKey(sessionKey); if (session == null) { throw new Exception("Unknown Session requested: " + sessionKey); } foreach (var pair in session.GetPeers()) { if (socketIds.Contains(pair.Key) && pair.Value.Socket.State == WebSocketState.Open) { await SendMessage(pair.Value.Socket, message); } } }
public async Task SendMessage(string sessionKey, string socketId, string message) { WebsocketSession session = this.GetSessionByKey(sessionKey); if (session == null) { throw new Exception("Unknown Session requested: " + sessionKey); } WebsocketSessionPeer sessionSocket = session.GetPeerById(socketId); if (sessionSocket == null) { throw new Exception("Unknown Socket requested: " + socketId); } await SendMessage(sessionSocket.Socket, message); }
public async Task SendMessage(string sessionKey, IEnumerable <WebSocket> sockets, string message) { List <Task> tasks = new List <Task>(); WebsocketSession session = this.GetSessionByKey(sessionKey); if (session == null) { throw new Exception("Unknown Session requested: " + sessionKey); } foreach (var pair in session.GetPeers()) { if (sockets.Contains(pair.Value.Socket) && pair.Value.Socket.State == WebSocketState.Open) { tasks.Add(SendMessage(pair.Value.Socket, message)); } } await Task.WhenAll(tasks); }
protected virtual WebsocketSession CreateSession(string sessionType, string sessionKey) { KeyValuePair <string, IProcessArtifact[]> preparedSession = GetPreparedSession(sessionKey); if (preparedSession.Equals(default(KeyValuePair <string, IProcessArtifact[]>))) { throw new Exception("Unknown Session: " + sessionKey); } WebsocketSession targetSession = new WebsocketSession(); targetSession.SessionKey = sessionKey; targetSession.SessionType = WebsocketSession.GetSessionType(sessionType); Sessions.TryAdd(sessionKey, targetSession); targetSession.SetAttributes(preparedSession.Value); PreparedSessions.TryRemove(preparedSession); return(targetSession); }
public virtual async Task <WebsocketSessionPeer> JoinSession(HttpContext context, string sessionType, string sessionKey) { WebsocketSession targetSession = GetSessionByKey(sessionKey); if (targetSession == null) { targetSession = this.CreateSession(sessionType, sessionKey); } WebSocket socket = await context.WebSockets.AcceptWebSocketAsync(); WebsocketSessionPeer sessionSocket = targetSession.AddPeer(socket); string hostId = sessionSocket.Token.PeerId; if (targetSession.GetPeers().Count == 1) { targetSession.SetAttribute("hostId", hostId); } else { hostId = targetSession.GetAttributeValue <string>("hostId"); } // alert requester of their own token, the hosts token and other existing peers WebsocketSessionPeerToken hostToken = targetSession.GetPeerById(hostId).Token; WebsocketSessionPeerToken[] participants = targetSession.GetPeers().Where(pair => pair.Value.Token.PeerId != sessionSocket.Token.PeerId).Select(pair => pair.Value.Token).ToArray(); WebsocketSessionGreeting greeting = new WebsocketSessionGreeting { SessionKey = sessionKey, HostToken = hostToken, Token = sessionSocket.Token, Peers = participants }; WebsocketSessionMessageResponse greetingResponse = CreateWebsocketResponseMessage(WebsocketSessionMessageType.Greeting, greeting); SendMessage(sessionSocket, greetingResponse); return(sessionSocket); }
private Task ProcessMessageRequest(WebsocketSessionMessageRequest request, string sessionKey, WebsocketSessionPeer peer) { // get a reference to the session WebsocketSession session = GetSessionByKey(sessionKey); // handle the different types of messages; string message = ""; switch (request.Type) { case WebsocketSessionMessageType.Introduction: string hostId = session.GetAttributeValue <string>("hostId"); WebsocketSessionPeerToken token = System.Text.Json.JsonSerializer.Deserialize <Models.WebsocketSessionPeerToken>(request.Message); peer.Token.DisplayName = token.DisplayName; peer.Token.IconUrl = token.IconUrl; if (token.PeerId == hostId) { // if host, no need to request access; just grant access; WebsocketSessionUpdate[] updates = CreatePeerUpdates(WebsocketSessionUpdateStatus.AccessGranted, peer.Token); WebsocketSessionMessageResponse hostAlertResponse = CreateWebsocketResponseMessage(WebsocketSessionMessageType.StatusUpdates, updates); SendMessage(sessionKey, hostId, hostAlertResponse); return(Task.CompletedTask); } message = request.Message; break; case WebsocketSessionMessageType.StatusUpdates: case WebsocketSessionMessageType.ByteArray: case WebsocketSessionMessageType.Text: message = request.Message; break; case WebsocketSessionMessageType.Reaction: if (request.TargetMessageId == null) { throw new Exception("Reaction must provide TargetMessageId value."); } break; default: throw new Exception("Unknown Message Type: " + request.Type); } List <WebsocketSessionMessageResponse> messages = session.GetAttributeValue <List <WebsocketSessionMessageResponse> >("messages"); WebsocketSessionMessageResponse messageResponse = new WebsocketSessionMessageResponse() { MessageId = messages.Count, MessageType = request.Type, Message = message, SenderId = peer.Token.PeerId, Recipients = request.Recipients }; messages.Add(messageResponse); if (request.Recipients == null || request.Recipients.Length == 0) { SendMessageToPeers(sessionKey, peer.Token.PeerId, messageResponse); } else { SendMessage(sessionKey, request.Recipients, messageResponse); } return(Task.CompletedTask); }
public virtual string GetKey(WebsocketSession session) { return(Sessions.FirstOrDefault(pair => pair.Value == session).Key); }