实时web应用方案——SignalR(.net core)
何为实时
先从理论上解释一下两者的区别。
大多数传统的web应用是这样的:客户端发起http请求到服务端,服务端返回对应的结果。像这样:
也就是说,传统的web应用都是客户端主动发起请求到服务端。
那么实时web应用呢?它不需要主动发起请求,服务端可以主动推送信息到客户端。
举栗子的话,实时聊天工具、web游戏等都可以算是实时应用。
什么是SignalR
如果想做一个实时应用,最好用web socket。很早以前我也写过web socket的实现方式,但不够全面,这里再补上一篇。
来说说signalR,它是一款开源的实时框架,可以使用三种方式实现通信(long polling、server sent events、web socket)。它很好的整合了底层技术,让我们可以不用关注底层技术实现而把精力聚焦在业务实现上。一个完整的signalR包括客户端和服务端,服务端支持net core/net framework,还支持大部分客户端,比如浏览器和桌面应用。
回落机制
为了兼容不同浏览器(客户端)和服务端,signalR采用了回落机制,使得它可以根据情况协商使用不同的底层传输方式。假如浏览器不支持web socket,就自动降级使用sse,再不行就long polling。当然,也可以禁用这种机制,指定其中一种。
三种通信方式
long polling(长轮询)
长轮询是客户端发起请求到服务端,服务器有数据就会直接返回。如果没有数据就保持连接并且等待,一直到有新的数据返回。如果请求保持到一段时间仍然没有返回,这时候就会超时,然后客户端再次发起请求。
这种方式优点就是简单,缺点就是资源消耗太多,基本是不考虑的。
server sent events(sse)
如果使用了sse,服务器就拥有了向客户端推送的能力,这些信息和流信息差不多,期间会保持连接。
这种方式优点还是简单,也支持自动重连,综合来讲比long polling好用。缺点也很明显,不支持旧的浏览器不说,还只能发送本文信息,而且浏览器对sse还有连接数量的限制(6个)。
web socket
web socket允许客户端和服务端同时向对方发送消息(也就是双工通信),而且不限制信息类型。虽然浏览器同样有连接数量限制(可能是50个),但比sse强得多。理论上最优先使用。
进入正题
开始之前,还需要了解RPC和Hub的概念。
RPC:全程Remote Procedure Call,字面意思远程服务调用,可以像调用本地方法一样调用远程服务。前端可以调用后端方法,后端也可以调用前端方法。
Hub:基于RPC,接受从客户端发过来的消息,也同时负责把服务端的消息发送给客户端。客户端可以调用Hub里面的方法,服务端可以通过Hub调用客户端里面的方法。
好了,概念已经理解清楚了,接下来上代码。
在项目里新增Hub类:
using Microsoft.AspNetCore.SignalR;
using System.Threading.Tasks; namespace SignalRDemo.Server
{
public class SignalRHub : Hub
{
/// <summary>
/// 客户连接成功时触发
/// </summary>
/// <returns></returns>
public override async Task OnConnectedAsync()
{
var cid = Context.ConnectionId; //根据id获取指定客户端
var client = Clients.Client(cid); //向指定用户发送消息
await client.SendAsync("Self", cid); //像所有用户发送消息
await Clients.All.SendAsync("AddMsg", $"{cid}加入了聊天室");
}
}
}
为了让外部可以访问,我们还需要一个控制器。在控制器里声明随便建一个:
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.SignalR;
using SignalRDemo.Server;
using System.Threading.Tasks; namespace SignalRDemo.Controllers
{
public class HomeController : Controller
{
private readonly IHubContext<SignalRHub> _countHub; public HomeController(IHubContext<SignalRHub> countHub)
{
_countHub = countHub;
} /// <summary>
/// 发送信息
/// </summary>
/// <param name="msg"></param>
/// <param name="id"></param>
/// <returns></returns>
public async Task Send(string msg, string id)
{
await _countHub.Clients.All.SendAsync("AddMsg", $"{id}:{msg}");
}
}
}
再然后进入StartUp设置端点:
endpoints.MapHub<SignalRHub>("/hub");
完成以后,配置signalr客户端:
setupConn = () => {
conn = new signalR.HubConnectionBuilder()
.withUrl("/hub")
.build();
conn.on("AddMsg", (obj) => {
$('#msgPanel').append(`<p>${obj}</p>`);
});
conn.on("Finished", () => {
conn.stop();
$('#msgPanel').text('log out!');
});
conn.on("Self", (obj) => {
$('#userId').text(obj);
});
conn.start()
.catch(err => console.log(err));
}
要注意withUrl里面的路径就是之前设置好的端点。
运行效果:

Hub还支持组操作,比如:
//将用户添加到A组
await Groups.AddToGroupAsync(Context.ConnectionId, "GroupA");
//将用户踢出A组
await Groups.RemoveFromGroupAsync(Context.ConnectionId, "GroupA");
//向A组所有成员广播消息
await Clients.Group("GroupA").SendAsync("AddMsg", "群组消息");
更多操作请参考官方文档。
本文演示demo的源码见git,地址:https://gitee.com/muchengqingxin/SignalRDemo.git
实时web应用方案——SignalR(.net core)的更多相关文章
- 常见的Web实时消息交互方式和SignalR
标签: WebSocket SignalR 前言 1. Web消息交互技术 1.1 常见技术 1.2 WebSocket介绍 1.3 WebSocket示例 2. Signal 2.1 SignalR ...
- SignalR来做实时Web聊天
本章和大家分享的内容是使用Signal R框架创建个简易的群聊功能,主要讲解如何在.Net的MVC中使用这个框架,由于这个项目有官方文档(当然全英文),后面也不打算写分享篇了,主要目的是让朋友们在需要 ...
- 【转】常见的Web实时消息交互方式和SignalR
https://www.cnblogs.com/Wddpct/p/5650015.html 前言 1. Web消息交互技术1.1 常见技术1.2 WebSocket介绍1.3 WebSocket示例 ...
- 使用SignalR实时Web应用程序
实时Web应用程序能够实时地将服务器端内容推送到连接的客户端.对于ASP.NET开发人员,ASP.NET SignalR是一个向其应用程序添加实时Web功能的库.它利用了多种传输方式,根据客户端和服务 ...
- 【转】SignalR来做实时Web聊天
本章和大家分享的内容是使用Signal R框架创建个简易的群聊功能,主要讲解如何在.Net的MVC中使用这个框架,由于这个项目有官方文档(当然全英文),后面也不打算写分享篇了,主要目的是让朋友们在需要 ...
- [ASP.NET] 使用 ASP.NET SignalR 添加实时 Web
ASP.NET SignalR 是为 ASP.NET 开发人员提供的一个库,可以简化开发人员将实时 Web 功能添加到应用程序的过程.实时 Web 功能是指这样一种功能:当所连接的客户端变得可用时服务 ...
- 使用WebSocket构建实时WEB
为了防止无良网站的爬虫抓取文章,特此标识,转载请注明文章出处.LaplaceDemon/SJQ. http://www.cnblogs.com/shijiaqi1066/p/3795075.html ...
- 使用SuperWebSocket 构建实时 Web 应用
Web 应用的信息交互过程通常是客户端通过浏览器发出一个请求,服务器端接收和审核完请求后进行处理并返回结果给客户端,然后客户端浏览器将信息呈现出来,这种机制对于信息变化不是特别频繁的应用尚能相安无事, ...
- 实时Web与WebSocket实践
引言:实时Web越来越被重视,Google.Facebook等大公司也逐渐开始提供实时性服务.实时Web将是未来最热门的话题之一. 本文选自<基于MVC的JavaScript Web富应用开发 ...
随机推荐
- 10 . Python之面向对象
面向对象编程--Object Oriented Programming,简称OOP,是一种程序设计思想.OOP把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数. 面向对象初识别 面向过程v ...
- 远程vps管理工具巧利用,如何短时间内提高vps管理效率!
假设你手上有1000台vps,那有没有一个免费的工具来进行有效的管理呢? 答案是有的,这里推荐一个非常好用的工具:IIS7远程桌面,免费版支持5台服务器登录,vps登录情况一目了然,高级版支持不限量台 ...
- 多服务器 vps 管理方法,十款远程桌面软件测评分析
作为运维工作者,从几年前巨大的工作量到如今有了极大的改善,这些年试用的远程桌面管理软件不在少数. 远程桌面是微软公司为了方便网络管理员管理维护服务器而推出的一项服务.从windows 2000 ser ...
- Unity 游戏框架搭建 2019 (五十六/五十七) 需求分析-架构中最重要的一环&从 EmptyGO 到 Manager Of Managers
我们的项目开始立项的时候,最常见的一个情况就是:几个人的小团队,一开始什么也不做,就开始写代码,验证逻辑,游戏就开始写起来了.而公司的一些所谓的领导层面一开始就把游戏定义为我们要做一个大作.这个事情本 ...
- 说了这么多次 I/O,但你知道它的原理么
O 软件目标 设备独立性 现在让我们转向对 I/O 软件的研究,I/O 软件设计一个很重要的目标就是设备独立性(device independence).啥意思呢?这意味着我们能够编写访问任何设备的应 ...
- Java实现 LeetCode 383 赎金信
383. 赎金信 给定一个赎金信 (ransom) 字符串和一个杂志(magazine)字符串,判断第一个字符串ransom能不能由第二个字符串magazines里面的字符构成.如果可以构成,返回 t ...
- Java实现 蓝桥杯 历届试题 城市建设
问题描述 栋栋居住在一个繁华的C市中,然而,这个城市的道路大都年久失修.市长准备重新修一些路以方便市民,于是找到了栋栋,希望栋栋能帮助他. C市中有n个比较重要的地点,市长希望这些地点重点被考虑.现在 ...
- Spring-AOP之工作实践(一)
案例一.角色校验 项目中,对某些方法需要用户具备指定角色权限才能执行. /** * 角色校验注解 */ @Retention(RetentionPolicy.RUNTIME) @Target(Elem ...
- 谈谈Spring中的对象跟Bean,你知道Spring怎么创建对象的吗?
本系列文章: 读源码,我们可以从第一行读起 你知道Spring是怎么解析配置类的吗? 配置类为什么要添加@Configuration注解? 推荐阅读: Spring官网阅读 | 总结篇 Spring杂 ...
- xlwings--Python for Excel
xlwings 中文文档 xlwings,让excel飞起来! xlwings 的使用教程