private static async Task ProcessMessageAsync(WebSocket webSocket, Participant participant, SudokuGameProcessor gameProcessor, CancellationToken cancellationToken) { var buffer = new byte[1024 * 4]; while (!cancellationToken.IsCancellationRequested || webSocket.State == WebSocketState.Open) { var rawMessage = new List <byte>(); WebSocketReceiveResult result; do { try { result = await webSocket.ReceiveAsync(new ArraySegment <byte>(buffer), cancellationToken); } catch (Exception e) { Console.WriteLine(e); return; } rawMessage.AddRange(buffer); } while (!result.EndOfMessage); var strMessage = Encoding.UTF8.GetString(rawMessage.ToArray()); var receivedCell = JsonConvert.DeserializeObject <CellDto>(strMessage); gameProcessor.SetCellValue(receivedCell, participant); } }
private static async Task SendAllCellsAsync(WebSocket webSocket, SudokuGameProcessor gameProcessor, CancellationToken cancellationToken) { var cells = gameProcessor.FilledCells; var serializedCells = JsonConvert.SerializeObject(cells); var binCells = Encoding.UTF8.GetBytes(serializedCells); try { await webSocket.SendAsync(new ArraySegment <byte>(binCells), WebSocketMessageType.Text, true, cancellationToken); } catch (Exception e) { Console.WriteLine(e); } }
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env, SudokuGameProcessor gameProcessor) { var webSocketOptions = new WebSocketOptions { KeepAliveInterval = TimeSpan.FromSeconds(120), ReceiveBufferSize = 4 * 1024 }; app.UseWebSockets(webSocketOptions); gameProcessor.GenerateRandomPuzzle(); app.Use(async(context, next) => { if (context.Request.Path == "/board") { if (context.WebSockets.IsWebSocketRequest) { var webSocket = await context.WebSockets.AcceptWebSocketAsync(); gameProcessor.CellUpdated += async(sender, cell) => { var cells = new[] { cell }; var strCells = JsonConvert.SerializeObject(cells); var binCells = Encoding.UTF8.GetBytes(strCells); try { await webSocket.SendAsync(new ArraySegment <byte>(binCells), WebSocketMessageType.Text, true, CancellationToken.None); } catch (Exception e) { Console.WriteLine(e); } }; gameProcessor.GameCompleted += async(sender, winner) => { await SendAllCellsAsync(webSocket, gameProcessor, CancellationToken.None); }; var participant = new Participant { Id = context.Request.Cookies["user-id"] != null ? Guid.Parse(context.Request.Cookies["user-id"]) : Guid.Empty, Name = context.Request.Cookies["user-name"] }; await SendAllCellsAsync(webSocket, gameProcessor, CancellationToken.None); await ProcessMessageAsync(webSocket, participant, gameProcessor, CancellationToken.None); } else { context.Response.StatusCode = 400; } } else if (context.Request.Path == "/winner") { if (context.WebSockets.IsWebSocketRequest) { var webSocket = await context.WebSockets.AcceptWebSocketAsync(); gameProcessor.GameCompleted += async(sender, participant) => { var strParticipant = JsonConvert.SerializeObject(participant); var binParticipant = Encoding.UTF8.GetBytes(strParticipant); try { await webSocket.SendAsync(new ArraySegment <byte>(binParticipant), WebSocketMessageType.Text, true, CancellationToken.None); } catch (Exception e) { Console.WriteLine(e); } }; var buffer = new byte[1024 * 4]; while (webSocket.State == WebSocketState.Open) { try { await webSocket.ReceiveAsync(new ArraySegment <byte>(buffer), CancellationToken.None); var message = Encoding.UTF8.GetString(buffer); Console.WriteLine(message); } catch (Exception e) { Console.WriteLine(e); return; } } } else { context.Response.StatusCode = 400; } } else { await next(); } }); }