public static async Task <WebSocketConnectionSummary> ExecuteAndCaptureFramesAsync(this IWebSocketConnection self) { var frames = new List <WebSocketFrame>(); var closeResult = await self.ExecuteAsync(frame => frames.Add(frame.Copy())); return(new WebSocketConnectionSummary(frames, closeResult)); }
private async Task Echo(HttpContext context, IWebSocketConnection webSocket, ILogger logger) { var lastFrameOpcode = WebSocketOpcode.Continuation; var closeResult = await webSocket.ExecuteAsync(frame => { if (frame.Opcode == WebSocketOpcode.Ping || frame.Opcode == WebSocketOpcode.Pong) { // Already handled return(Task.CompletedTask); } LogFrame(logger, lastFrameOpcode, ref frame); // If the client send "ServerClose", then they want a server-originated close to occur string content = "<<binary>>"; if (frame.Opcode == WebSocketOpcode.Text) { // Slooooow content = Encoding.UTF8.GetString(frame.Payload.ToArray()); if (content.Equals("ServerClose")) { logger.LogDebug($"Sending Frame Close: {WebSocketCloseStatus.NormalClosure} Closing from Server"); return(webSocket.CloseAsync(new WebSocketCloseResult(WebSocketCloseStatus.NormalClosure, "Closing from Server"))); } else if (content.Equals("ServerAbort")) { context.Abort(); } } if (frame.Opcode != WebSocketOpcode.Continuation) { lastFrameOpcode = frame.Opcode; } logger.LogDebug($"Sending {frame.Opcode}: Len={frame.Payload.Length}, Fin={frame.EndOfMessage}: {content}"); return(webSocket.SendAsync(frame)); }); if (webSocket.State == WebSocketConnectionState.CloseReceived) { // Close the connection from our end await webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure); logger.LogDebug("Socket closed"); } else if (webSocket.State != WebSocketConnectionState.Closed) { logger.LogError("WebSocket closed but not closed?"); } }
/// <summary> /// Runs the WebSocket receive loop, using the provided message handler. /// </summary> /// <param name="messageHandler">The callback that will be invoked for each new frame</param> /// <returns>A <see cref="Task{WebSocketCloseResult}"/> that will complete when the client has sent a close frame, or the connection has been terminated</returns> public static Task <WebSocketCloseResult> ExecuteAsync(this IWebSocketConnection self, Action <WebSocketFrame, object> messageHandler, object state) => self.ExecuteAsync((frame, s) => { messageHandler(frame, s); return(Task.CompletedTask); }, state);
/// <summary> /// Runs the WebSocket receive loop, using the provided message handler. /// </summary> /// <param name="messageHandler">The callback that will be invoked for each new frame</param> /// <returns>A <see cref="Task{WebSocketCloseResult}"/> that will complete when the client has sent a close frame, or the connection has been terminated</returns> public static Task <WebSocketCloseResult> ExecuteAsync(this IWebSocketConnection self, Func <WebSocketFrame, Task> messageHandler) => self.ExecuteAsync((frame, _) => messageHandler(frame), null);
/// <summary> /// Runs the WebSocket receive loop, using the provided message handler. /// </summary> /// <param name="messageHandler">The callback that will be invoked for each new frame</param> /// <returns>A <see cref="Task{WebSocketCloseResult}"/> that will complete when the client has sent a close frame, or the connection has been terminated</returns> public static Task <WebSocketCloseResult> ExecuteAsync(this IWebSocketConnection self, Action <WebSocketFrame> messageHandler) => self.ExecuteAsync((frame, _) => { messageHandler(frame); return(Task.CompletedTask); }, null);