.net core实现WebSocket通讯

首次发布:2019-11-20 10:32
以下是Startup类下的核心代码 这里用的是.net core 2.0 如果更高版本 也差不多稍微改动一点就可以
public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc();
}

// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
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())
            {
                //do something 
                WebSocket webSocket = await context.WebSockets.AcceptWebSocketAsync();
                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)
{
    var buffer = new byte[1024 * 4];
    WebSocketReceiveResult result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
    while (!result.CloseStatus.HasValue)
    {
        await webSocket.SendAsync(new ArraySegment<byte>(buffer, 0, result.Count), result.MessageType,
result.EndOfMessage, CancellationToken.None);

        result = await webSocket.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
    }
    await webSocket.CloseAsync(result.CloseStatus.Value, result.CloseStatusDescription, CancellationToken.None);
}

以下是Html代码
<!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测试页</h1>
    <p id="stateLabel">准备连接...</p>
    <div>
        <label for="connectionUrl">WebSocket服务器URL:</label>
        <input id="connectionUrl" />
        <button id="connectButton" type="submit">连接</button>
    </div>
    <div>
        <label for="sendMessage">消息发送:</label>
        <input id="sendMessage" disabled />
        <button id="sendButton" type="submit" disabled>发送</button>
        <button id="closeButton" disabled>关闭Socket</button>
    </div>

    <p>注意:当连接到默认服务器(即地址栏中的服务器;)时,消息“ ServerClose”将导致服务器关闭连接。同样,消息“ ServerAbort”将导致服务器在不关闭握手的情况下强行终止连接</p>

    <h2>通讯日志</h2>
    <table style="width: 800px">
        <thead>
            <tr>
                <td style="width: 100px">发送</td>
                <td style="width: 100px">接收</td>
                <td>数据</td>
            </tr>
        </thead>
        <tbody id="commsLog"></tbody>
    </table>

    <script>
        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 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 = "关闭";
                        disable();
                        connectionUrl.disabled = false;
                        connectButton.disabled = false;
                        break;
                    case WebSocket.CLOSING:
                        stateLabel.innerHTML = "关闭中...";
                        disable();
                        break;
                    case WebSocket.CONNECTING:
                        stateLabel.innerHTML = "连接中...";
                        disable();
                        break;
                    case WebSocket.OPEN:
                        stateLabel.innerHTML = "打开";
                        enable();
                        break;
                    default:
                        stateLabel.innerHTML = "未知的WebSocket状态: " + socket.readyState;
                        disable();
                        break;
                }
            }
        }
        closeButton.onclick = function () {
            if (!socket || socket.readyState != WebSocket.OPEN) {
                alert("socket没有连接");
            }
            socket.close(1000, "从客户端关闭");
        }
        sendButton.onclick = function () {
            if (!socket || socket.readyState != WebSocket.OPEN) {
                alert("socket未连接");
            }
            var data = sendMessage.value;
            socket.send(data);
            commsLog.innerHTML += '<tr>' +
                '<td class="commslog-client">客户端</td>' +
                '<td class="commslog-server">服务端</td>' +
                '<td class="commslog-data">' + data + '</td>'
            '</tr>';
        }
        connectButton.onclick = function () {
            stateLabel.innerHTML = "连接中";
            socket = new WebSocket(connectionUrl.value);
            socket.onopen = function (event) {
                updateState();
                commsLog.innerHTML += '<tr>' +
                    '<td colspan="3" class="commslog-data">连接已打开</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">服务端</td>' +
                    '<td class="commslog-client">客户端</td>' +
                    '<td class="commslog-data">' + event.data + '</td>'
                '</tr>';
            };
        };
    </script>
</body>
</html>
完整代码下载地址链接:https://pan.baidu.com/s/1sDNtsTOLuJK9WZ_UUrn2PQ 提取码:j76b