1. 参考资料
2. 程序A : 没有使用中间件 (https://www.cnblogs.com/u-drive/p/9833634.html)

using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using System; using System.Net.WebSockets; using System.Threading; using System.Threading.Tasks; namespace AspNetCoreWithWebSocketDemo { public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration; } public IConfiguration Configuration { get; } // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.AddMvc(); } public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseBrowserLink(); app.UseDeveloperExceptionPage(); } else { app.UseExceptionHandler("/Home/Error"); } app.UseStaticFiles(); //Be sure to configure before mvc middleware. app.UseWebSockets(); app.Use(async (context, next) => { if (context.WebSockets.IsWebSocketRequest) { using (IServiceScope scope = app.ApplicationServices.CreateScope()) { WebSocket webSocket = await context.WebSockets.AcceptWebSocketAsync(); Console.WriteLine("接收到玩家链接" + context.Request.HttpContext.Connection.RemoteIpAddress.ToString()); //The AcceptWebSocketAsync method upgrades the TCP connection to a WebSocket connection and provides a WebSocket object. Use the WebSocket object to send and receive messages await Echo(context, webSocket); } } else { //Hand over to the next middleware await next(); } }); app.UseMvc(routes => { routes.MapRoute( name: "default", template: "{controller=Home}/{action=Index}/{id?}"); }); } private async Task Echo(HttpContext context, WebSocket webSocket) //Echo 响应的意思 { var buffer = new byte[1024 * 4]; WebSocketReceiveResult result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None); string receiveText = System.Text.Encoding.Default.GetString(buffer); Console.WriteLine($"收到客户端的信息 {context.Request.HttpContext.Connection.RemoteIpAddress}:{context.Request.HttpContext.Connection.RemotePort} {receiveText}" ); while (!result.CloseStatus.HasValue) { string s = DateTime.Now.ToString(); byte[] sendContext = System.Text.Encoding.Default.GetBytes(s); //await webSocket.SendAsync(new ArraySegment<byte>(buffer, 0, result.Count), result.MessageType, result.EndOfMessage, CancellationToken.None); await webSocket.SendAsync(new ArraySegment<byte>(sendContext, 0, sendContext.Length), WebSocketMessageType.Text, true, CancellationToken.None); result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None); } await webSocket.CloseAsync(result.CloseStatus.Value, result.CloseStatusDescription, CancellationToken.None); Console.WriteLine($"客户端断开链接"); } } }

@{ Layout = null; } <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title></title> <style> table { border: 0 } .commslog-data { font-family: Consolas, Courier New, Courier, monospace; } .commslog-server { background-color: red; color: white } .commslog-client { background-color: green; color: white } </style> </head> <body> <h1>WebSocket Test Page</h1> <p id="stateLabel">Ready to connect...</p> <div> <label for="connectionUrl">WebSocket Server URL:</label> <input id="connectionUrl" /> <button id="connectButton" type="submit">Connect</button> </div> <div> <label for="sendMessage">Message to send:</label> <input id="sendMessage" disabled /> <button id="sendButton" type="submit" disabled>Send</button> <button id="closeButton" disabled>Close Socket</button> </div> <p>Note: When connected to the default server (i.e. the server in the address bar ;)), the message "ServerClose" will cause the server to close the connection. Similarly, the message "ServerAbort" will cause the server to forcibly terminate the connection without a closing handshake</p> <h2>Communication Log</h2> <table style="width: 800px"> <thead> <tr> <td style="width: 100px">From</td> <td style="width: 100px">To</td> <td>Data</td> </tr> </thead> <tbody id="commsLog"></tbody> </table> <script> var connectionForm = document.getElementById("connectionForm"); var connectionUrl = document.getElementById("connectionUrl"); var connectButton = document.getElementById("connectButton"); var stateLabel = document.getElementById("stateLabel"); var sendMessage = document.getElementById("sendMessage"); var sendButton = document.getElementById("sendButton"); var sendForm = document.getElementById("sendForm"); var commsLog = document.getElementById("commsLog"); var socket; var scheme = document.location.protocol == "https:" ? "wss" : "ws"; var port = document.location.port ? (":" + document.location.port) : ""; connectionUrl.value = scheme + "://" + document.location.hostname + port; function updateState() { function disable() { sendMessage.disabled = true; sendButton.disabled = true; closeButton.disabled = true; } function enable() { sendMessage.disabled = false; sendButton.disabled = false; closeButton.disabled = false; } connectionUrl.disabled = true; connectButton.disabled = true; if (!socket) { disable(); } else { switch (socket.readyState) { case WebSocket.CLOSED: stateLabel.innerHTML = "Closed"; disable(); connectionUrl.disabled = false; connectButton.disabled = false; break; case WebSocket.CLOSING: stateLabel.innerHTML = "Closing..."; disable(); break; case WebSocket.CONNECTING: stateLabel.innerHTML = "Connecting..."; disable(); break; case WebSocket.OPEN: stateLabel.innerHTML = "Open"; enable(); break; default: stateLabel.innerHTML = "Unknown WebSocket State: " + socket.readyState; disable(); break; } } } closeButton.onclick = function () { if (!socket || socket.readyState != WebSocket.OPEN) { alert("socket not connected"); } socket.close(1000, "Closing from client"); } sendButton.onclick = function () { if (!socket || socket.readyState != WebSocket.OPEN) { alert("socket not connected"); } var data = sendMessage.value; socket.send(data); //commsLog.innerHTML += '<tr>' + // '<td class="commslog-client">Client</td>' + // '<td class="commslog-server">Server</td>' + // '<td class="commslog-data">' + data + '</td>' //'</tr>'; } connectButton.onclick = function () { stateLabel.innerHTML = "Connecting"; socket = new WebSocket(connectionUrl.value); socket.onopen = function (event) { updateState(); commsLog.innerHTML += '<tr>' + '<td colspan="3" class="commslog-data">Connection opened</td>' + '</tr>'; }; socket.onclose = function (event) { updateState(); commsLog.innerHTML += '<tr>' + '<td colspan="3" class="commslog-data">Connection closed. Code: ' + event.code + '. Reason: ' + event.reason + '</td>' + '</tr>'; }; socket.onerror = updateState; socket.onmessage = function (event) { commsLog.innerHTML += '<tr>' + '<td class="commslog-server">Server</td>' + '<td class="commslog-client">Client</td>' + '<td class="commslog-data">' + event.data + '</td>' '</tr>'; }; }; </script> </body>