private async Task Echo(GameSocket gameSocket, CancellationToken cancellationToken) { var buffer = new byte[1024 * 4]; var result = await gameSocket.ReceiveAsync(new ArraySegment <byte>(buffer), cancellationToken); while (!result.CloseStatus.HasValue) { await gameSocket.SendAsync(new ArraySegment <byte>(buffer, 0, result.Count), result.MessageType, result.EndOfMessage, cancellationToken); result = await gameSocket.ReceiveAsync(new ArraySegment <byte>(buffer), cancellationToken); } await gameSocket.CloseAsync(result.CloseStatus.Value, result.CloseStatusDescription, cancellationToken); }
private async Task Echo(HttpContext context, GameSocket gameSocket, ILogger logger) { var buffer = new byte[1024 * 4]; var result = await gameSocket.ReceiveAsync(buffer.AsMemory(), CancellationToken.None); LogFrame(logger, gameSocket, result, buffer); while (result.MessageType != GameSocketMessageType.Close) { // If the client send "ServerClose", then they want a server-originated close to occur string content = "<<binary>>"; if (result.MessageType == GameSocketMessageType.Text) { content = Encoding.UTF8.GetString(buffer, 0, result.Count); if (content.Equals("ServerClose")) { await gameSocket.CloseAsync(GameSocketCloseStatus.NormalClosure, "Closing from Server", CancellationToken.None); logger.LogDebug($"Sent Frame Close: {GameSocketCloseStatus.NormalClosure} Closing from Server"); return; } else if (content.Equals("ServerAbort")) { context.Abort(); } } await gameSocket.SendAsync(new ArraySegment <byte>(buffer, 0, result.Count), result.MessageType, result.EndOfMessage, CancellationToken.None); logger.LogDebug($"Sent Frame {result.MessageType}: Len={result.Count}, Fin={result.EndOfMessage}: {content}"); result = await gameSocket.ReceiveAsync(buffer.AsMemory(), CancellationToken.None); LogFrame(logger, gameSocket, result, buffer); } await gameSocket.CloseAsync(gameSocket.CloseStatus.Value, gameSocket.CloseStatusDescription, CancellationToken.None); }
internal async Task CleanupAsync() { switch (_gameSocket.State) { case GameSocketState.Closed: // Closed gracefully, no action needed. case GameSocketState.Aborted: // Closed abortively, no action needed. break; case GameSocketState.CloseReceived: // Echo what the client said, if anything. await _gameSocket.CloseAsync(_gameSocket.CloseStatus ?? GameSocketCloseStatus.NormalClosure, _gameSocket.CloseStatusDescription ?? string.Empty, _cancellationToken); break; case GameSocketState.Open: case GameSocketState.CloseSent: // No close received, abort so we don't have to drain the pipe. _gameSocket.Abort(); break; default: throw new NotSupportedException($"Unsupported {nameof(GameSocketState)} value: {_gameSocket.State}."); } }