内容简介:在有两种方式可以实现这样的功能:两种方案的选择:
在 原生js实现文件上传并显示进度条 一文中,我们实现了一个Excel上传功能,并且显示了服务端实时处理进度 (正在处理第N行...)
,不用让用户一直傻等而不知道什么情况,这样极大的提高了用户的体验
有两种方式可以实现这样的功能:
js websocket
两种方案的选择:
传统的长轮询也能实现消息实时,就是定时向服务器发送请求获取消息,但是这样对服务器压力比较大,而 websocket
基于 http
进行一次握手功能,后面就不走 http
了
在 .net
中, SignalR
用来实现服务器和客户端双向通信的一个框架,是对 websocket
的很好的一个封装,所以我选择了它。
当然,其他语言肯定都是支持 websocket
通信的,不仅仅局限于 .net
,像 nodejs
的 socket.io
SignalR
SignalR
是 .net
中的一个服务器和客户端双向通信的一个框架,面向web端的即时通讯, SignalR
更简单,对 websocket
通信进行了封装
SignalR
没有连接限制,取决于服务器配置,浏览器客户端有限制,chrome一般是5个 websocket
连接
可以做什么
- 站内实时聊天、消息通知
- web页面实时数据的展示
- 自适应通信协议,如果浏览器或服务器支持
websocket
,就使用websocket
通信协议,否则就降级,使用长轮询服务器一般需要手动开启
-
.net core
跨平台,在2.2版本已经正式内置了SignalR
.net core
服务端配置
startup
中 ConfigureServices
方法内部添加 SignalR
服务 services.AddSignalR();
, Configure
中配置具体的 Hub
(路由器、中转):
app.UseSignalR(routes => { routes.MapHub<TestHub>("/testHub"); //可以多个map }); app.UseMvc(); //注意UseSignalR需要在UseMvc()之前 复制代码
这样 SignalR
服务器端就开发完成了,网页、 Java 、.Net客户端都可以连接的
Hub 消息处理中心
public class TestHub : Hub { public TestHub() { } public async Task SendMessage(string message, string name) { #region Client //this.Context.ConnectionId //每个连接一个connectionId 表示唯一客户端 //this.Clients.Client().SendAsync(); //指定发送消息 //this.Clients.Clients() #endregion //给多个client发消息 #region Group //this.Clients.Group(); //给某个组发消息 //this.Clients.Groups() //给多个组发消息 //this.Groups.AddToGroupAsync() //将指定连接加入组 //this.Groups.RemoveFromGroupAsync() //将指定连接移除组 #endregion await Clients.All.SendAsync("onMsg", DateTime.Now, message); } //上下线消息 连接、断开事件 //客户端连接上 public override Task OnConnectedAsync() { return base.OnConnectedAsync(); } //客户端断开 public override Task OnDisconnectedAsync(Exception exception) { string connectionId = this.Context.ConnectionId; return base.OnDisconnectedAsync(exception); } } 复制代码
以上可以看到 SignalR
封装了很多常用方法 (发送指定消息、群发...)
,我们可以很简单的使用达到目的
web端引入 SignalR
的 js
对应类库,调用服务端对应的方法即可
var connection = new signalR.HubConnectionBuilder().withUrl("/testHub").build(); connection.on("onMsg", function (data, message) { console.log(data); var li = document.createElement('li'); li.textContent = `${data}:${message}`; document.getElementById("content").appendChild(li); }); connection.start().then(function () { }).catch(function (err) { }) function sendMsg() { var msg = document.getElementById('txt').value; connection.invoke("SendMessage", msg, "xiaoqiu"); //connection.stop(); } 复制代码
开了两个浏览器访问,基本的效果如图:
到这里,我们完全可以做一个聊天室了,当然,需要优化的地方会更多了
Controller中调用SignalR服务
在构造函数注入 IHubContext<>
就可以直接使用了,非常方便:
private readonly IHubContext<TestHub> _hubContext; public HomeController(IHubContext<TestHub> hubContext) { _hubContext = hubContext; } public async Task<IActionResult> Notify() { //拿不到当前Hub的clientId 线程是唯一的 await _hubContext.Clients.All.SendAsync("onMsg", "from controller msg"); return Ok(); } 复制代码
一般不直接和客户端进行Hub通信,Controller中调用Hub可以做中转,做多应用接入,自定义功能、权限等等
上一文中,我们显示Excel试试处理进度,大致代码如下:
[HttpPost] public async Task<JsonResult> Import() { var connectionId = Request.Form["connectionId"].ToString(); //拿到当前连接的Id var importer = new ExcelImporter(); //自定义的委托,处理业务的参数 importer.OnImportingEvent += (sender, arg) => { var response = new { isSuccess = arg.IsSuccess, //当前数据行是否处理(导入转换)成功 total = arg.TotalRow, //当前导入的数据总行数 rowNumber = arg.RowNumber, //当前处理的行数 msg = arg.Msg, //处理消息 time = arg.Time, //处理时间 isComplete = false //是否全部处理(转换)完毕 }; //推送消息,通知到客户端 _globalHub.InvokeByIDAsync(connectionId, "importMessage", response); }; } //前端的connection处理,监听对应的方法 connection.on('importMessage',function(notice){ //根据返回的参数进行相应的逻辑处理展示... }) 复制代码
到这里, SignalR
的基本用法已经介绍完毕,欢迎补充!
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- WebSocket 前后端实时消息推送
- TradingView + WebSocket 实时推送 K 线脱坑指南
- 基于websocket的实时通告功能,推送在线用户,新登录用户
- 一步步教你用Prometheus搭建实时监控系统系列(二)——详细分析拉取和推送两种不同模式
- iOS 推送通知及推送扩展
- 安卓统一推送联盟明日开启推送通道测试
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。