.NetCore WebSocket简单实现

xiaoxiao2021-02-28  19

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

一、服务端

新建了一个handler

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<byte>(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<AddressMatchProgressModel> infolist = new List<AddressMatchProgressModel>();                     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<byte>(x); await this.socket.SendAsync(outgoing, WebSocketMessageType.Text, true, CancellationToken.None); } //var incoming = await this.socket.ReceiveAsync(seg, CancellationToken.None); //var outgoing = new ArraySegment<byte>(buffer, 0, incoming.Count); //await this.socket.SendAsync(outgoing, WebSocketMessageType.Text, true, CancellationToken.None); } } static async Task Acceptor(HttpContext hc, Func<Task> n) { if (!hc.WebSockets.IsWebSocketRequest) return; var socket = await hc.WebSockets.AcceptWebSocketAsync(); var h = new SocketHandler(socket); await h.EchoLoop(); } /// <summary> /// branches the request pipeline for this SocketHandler usage /// </summary> /// <param name="app"></param> public static void Map(IApplicationBuilder app) { app.UseWebSockets(); app.Use(SocketHandler.Acceptor); } } }

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

3.startup.cs添加路由

 二、客户端

客户端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("<div class='progress onepro' ><div id='" + gid + "' class='progress-bar' role='progressbar' aria-valuenow='60' aria-valuemin='0' aria-valuemax='100' style='width: 0%;'></div></div ><div id='" + gid + "_span' class='infospan'>" + fileName + "处理中</div ><div class='clearfloat'></div>"); } $("#" + gid).css("width", progress + "%").val("aria-valuenow", progress); if (progress == "100") { $("#" + gid + "_span").html(fileName + '处理完成,<a class="downloada" οnclick="clickdown('' + gid + '')">下载</a>'); } 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; } }
转载请注明原文地址: https://www.6miu.com/read-2650228.html

最新回复(0)