.NetCore WebSocket简单实现

项目需要使用.net core的webapi后台处理一个大文件,同时向客户端实时返回处理进度。所以实现了一个简单demo,记录一下。

一、服务端

  1. 新建了一个handler

.NetCore WebSocket简单实现_第1张图片

2.SocketHandler.cs内容如下

using DotnetCoreWebAPI.Common;
using DotnetCoreWebAPI.Models;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Newtonsoft.Json;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Net.WebSockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace DotnetCoreWebAPI.Handler
{
    public class SocketHandler
    {
        public const int BufferSize = 4096;
        public string basestringjson = string.Empty;

        WebSocket socket;

        SocketHandler(WebSocket socket)
        {
            this.socket = socket;
        }

        async Task EchoLoop()
        {
            var buffer = new byte[BufferSize];
            var seg = new ArraySegment(buffer);


            while (this.socket.State == WebSocketState.Open)
            {
                var incoming = await this.socket.ReceiveAsync(seg, CancellationToken.None);
                string receivemsg = Encoding.UTF8.GetString(buffer, 0, incoming.Count);
                if (receivemsg == "get")
                {
                    string stringJson = "";

                    List infolist = new List();
                    Hashtable newtable = CommonInfo.ProgressInfo;
                    if (newtable != null)
                    {
                        try
                        {
                            foreach (DictionaryEntry i in newtable)
                            {
                                AddressMatchProgressModel pgmodel = new AddressMatchProgressModel();
                                pgmodel = (AddressMatchProgressModel)i.Value;
                                infolist.Add(pgmodel);
                            }
                        }
                        catch (Exception ex)
                        {
                            Console.WriteLine(ex.Message);
                        }
                    }
                    stringJson = JsonConvert.SerializeObject(infolist);


                    string userMsg = stringJson;
                    byte[] x = Encoding.UTF8.GetBytes(userMsg);
                    var outgoing = new ArraySegment(x);
                    await this.socket.SendAsync(outgoing, WebSocketMessageType.Text, true, CancellationToken.None);
                }
                //var incoming = await this.socket.ReceiveAsync(seg, CancellationToken.None);
                //var outgoing = new ArraySegment(buffer, 0, incoming.Count);
                //await this.socket.SendAsync(outgoing, WebSocketMessageType.Text, true, CancellationToken.None);

            }
        }

        static async Task Acceptor(HttpContext hc, Func n)
        {
            if (!hc.WebSockets.IsWebSocketRequest)
                return;

            var socket = await hc.WebSockets.AcceptWebSocketAsync();
            var h = new SocketHandler(socket);
            await h.EchoLoop();
        }

        /// 
        /// branches the request pipeline for this SocketHandler usage
        /// 
        /// 
        public static void Map(IApplicationBuilder app)
        {
            app.UseWebSockets();
            app.Use(SocketHandler.Acceptor);
        }
    }
}

(ps:这里遇到了一个小问题 ,记录一下。我在另一个地方处理大文件的,并把处理进度实时更新在一个全局变量hashtable里,然后在websocket服务端获取这个变量的值,从而得到处理进度主动推送给客户端。问题是hashtable在不断的写入同时在读取,有时候便会出现movenext异常了。所以这里将全局变量hashtable赋值给了一个新的hashtable,这样就可以保证在websocket服务端获取进度数据的时候,这个hasntable的值是不会在遍历的过程中变化的。)

3.startup.cs添加路由

.NetCore WebSocket简单实现_第2张图片

 二、客户端

客户端js脚本写的

//启动websocket
                function startWebsocket() {
                    var ws = new WebSocket("ws://localhost:9957/ws");
                    ws.onopen = function (evt) {
                        console.log("Connection open ...");
                        isOpenWebSocket = true;
                        ws.send("get");
                    };
                    ws.onmessage = function (evt) {
                        isOpenWebSocket = true;
                        console.log("Received Message: " + evt.data);
                        var data = $.parseJSON(evt.data);
                        if (data.length > 0) {

                            var allfinish = true;
                            for (var num in data) {
                                var gid = data[num].Gid;
                                var fileName = data[num].UploadFileName;
                                var progress = data[num].Progress;
                                if ($("#" + gid).length <= 0) {
                                    //当前进度条不存在
                                    $("#progressbox").append("
" + fileName + "处理中
"); } $("#" + gid).css("width", progress + "%").val("aria-valuenow", progress); if (progress == "100") { $("#" + gid + "_span").html(fileName + '处理完成,下载'); } else { allfinish = false; } } if (allfinish) { //进度全部100% ws.close(); isOpenWebSocket = false; } else { ws.send("get"); } } else { //进度数据不存在,断开连接 ws.close(); isOpenWebSocket = false; } //ws.send(""); }; ws.onclose = function (evt) { isOpenWebSocket = false; console.log("Connection closed."); }; ws.onerror = function (evt) { write("Error: " + evt.data); }; //强制关闭浏览器 调用websocket.close(),进行正常关闭 window.onunload = function () { ws.close(); isOpenWebSocket = false; } }

你可能感兴趣的:(.Net,Core)