Asp-Net-Core学习笔记:3.使用SignalR实时通信框架开发聊天室
SignalR牛刀小试
在MVP杨老师的博客里看到这么个东西,我还以为是NetCore3才推出的新玩意,原来是已经有很多年的历史了,那看来还是比较成熟的一个技术了。
简介
SignalR是一个.NET Core/.NET Framework的开源实时框架,SignalR的可使用Web Socket, Server Sent Events 和 Long Polling作为底层传输方式。
SignalR基于这三种技术构建,抽象于它们之上,它让你更好的关注业务问题而不是底层传输技术问题。
以上介绍来自博客,SignalR分为客户端和服务端,服务端运行在AspNetCore上,客户端支持前端、桌面端和移动端,我去查了一下,连Flutter也有相应的支持库。
几个概念
回落机制
SignalR支持三种底层传输技术,根据客户端的兼容性可以自动协商传输类型。如图

Web Socket是最好的最有效的传输方式,如果浏览器或Web服务器不支持它的话,就会降级使用SSE,实在不行就用Long Polling。
RPC
不用解释太多,Remote Procedure Call,SignalR采用RPC范式来进行服务端和客户端之间的通信。
Hub
Hub是SignalR的一个组件,运行在服务端,它是一个通信用的组件, Hub使用RPC接受从客户端发来的消息,也能把消息发送给客户端 。

关于横向扩展
SignalR针对多种底层通信方式有了 Sticky Sessions (粘性会话) 这种解决方案,可以保证一个客户端在一次会话中的请求都分配给同一个服务器,具体以后需要的时候再研究。
开始使用
我要做的是一个聊天室,所以只需要写一个简单的服务就可以了。
首先要创建AspNetCore项目,注册SignalR服务:
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddSignalR();
}
创建ChatService类:
public class ChatService
{
private readonly List<ChatMessage> _messages;
private readonly IHubContext<ChatHub> _context;
public List<ChatMessage> Messages { get => _messages; }
public ChatService(IHubContext<ChatHub> context)
{
_context = context;
_messages = new List<ChatMessage>();
}
}
消息实体类:
public class ChatMessage
{
public string UserName { get; set; }
public string Content { get; set; }
public DateTime SendedTime { get; set; }
public string ClientName { get; set; }
}
关键的来了,编写Hub:
使用SendAsync可以进行远程调用
public class ChatHub : Hub {
private readonly ChatService _chatService;
public ChatHub(ChatService chatService) {
_chatService = chatService;
}
public async Task GetMessages(string connectionId) {
var data = _chatService.Messages;
await Clients.Client(connectionId).
SendAsync("GetMessages", data);
}
public async Task SendMessage(string userName, string content, string clientName) {
var msg = new Models.ChatMessage {
UserName = userName,
Content = content,
SendedTime = DateTime.Now,
ClientName = clientName
};
_chatService.Messages.Add(msg);
await Clients.All.SendAsync("SendMessage", msg);
}
public override Task OnConnectedAsync() {
GetMessages(Context.ConnectionId);
return base.OnConnectedAsync();
}
}
注册依赖注入和中间件
依赖注入
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddSignalR();
services.AddSingleton<CountService>();
services.AddSingleton<ChatService>();
}
中间件
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseStaticFiles();
app.UseRouting();
app.UseEndpoints(endpoints =>{
endpoints.MapControllers();
endpoints.MapHub<ChatHub>("/chat");
});
}
客户端
为了方便我就用网页来做。
首先写个简单的聊天界面布局,这里就不贴代码了没啥技术含量,效果大概这样:

首先要安装signalr.js,通过npm安装即可。
然后需要编写js:
function setupConnection() {
connection = new signalR.HubConnectionBuilder()
.withUrl("/chat")
.build();
connection.on("SendMessage", message => {
console.log(message);
addMsg(message.userName, message.sendedTimeStr, message.content, message.clientName);
});
connection.on("GetMessages", data => {
console.log(data);
for (var i = 0; i < data.length; i++) {
let message = data[i];
addMsg(message.userName, message.sendedTimeStr, message.content, message.clientName);
}
});
connection.on("Finished", () => {
connection.stop();
console.log("finished.")
});
connection.start()
.catch(err => console.error(err.toString()));
}
通过以下代码可以远程调用服务器的方法:
connection.invoke("SendMessage", username, content, '网页客户端');
然后就可以打开多个浏览器测试了。
这是我在手机上的截图

PS:为了把这个部署到服务器,我还买了个新的阿里云服务器。。
参考资料
- 杨老师博客:https://www.cnblogs.com/cgzl/p/9515516.html
- https://juejin.im/post/5c1c7b9c6fb9a049d23606a8
- AspNetCore应用部署:https://article.itxueyuan.com/dX28oy
- 启动配置:https://www.cnblogs.com/Hai--D/p/5842842.html
欢迎交流
交流问题请在微信公众号后台留言,每一条信息我都会回复哈~
- 微信公众号:画星星高手
- 打代码直播间:https://live.bilibili.com/11883038
- 知乎:https://www.zhihu.com/people/dealiaxy
- 专栏:https://zhuanlan.zhihu.com/deali
- 简书:https://www.jianshu.com/u/965b95853b9f
Asp-Net-Core学习笔记:3.使用SignalR实时通信框架开发聊天室的更多相关文章
- Asp.Net Core学习笔记:入门篇
Asp.Net Core 学习 基于.Net Core 2.2版本的学习笔记. 常识 像Django那样自动检查代码更新,自动重载服务器(太方便了) dotnet watch run 托管设置 设置项 ...
- ASP.NET Core 学习笔记 第五篇 ASP.NET Core 中的选项
前言 还记得上一篇文章中所说的配置吗?本篇文章算是上一篇的延续吧.在 .NET Core 中读取配置文件大多数会为配置选项绑定一个POCO(Plain Old CLR Object)对象,并通过依赖注 ...
- Asp.net core 学习笔记 SignalR
refer : https://kimsereyblog.blogspot.com/2018/07/signalr-with-asp-net-core.html https://github.com/ ...
- ASP.NET Core 学习笔记 第一篇 ASP.NET Core初探
前言 因为工作原因博客断断续续更新,其实在很早以前就有想法做一套关于ASP.NET CORE整体学习度路线,整体来说国内的环境的.NET生态环境还是相对比较严峻的,但是干一行爱一行,还是希望更多人加入 ...
- asp.net.core学习笔记1:swagger的使用和webapi接收Jobject对象
环境:asp.net.core 3.1 (一觉醒来官方已经不推荐3.0了,于是没有任何core经验,也只能开始了3.1的开发学习) 由于现有项目前后端分离.微服务化日趋流行,所以上手不采用web应用( ...
- Asp.net Core学习笔记
之前记在github上的,现在搬运过来 变化还是很大的,感觉和Nodejs有点类似,比如中间件的使用 ,努力学习ing... 优点 不依赖IIS 开源和跨平台 中间件支持 性能优化 无所不在的依赖注入 ...
- ASP.NET Core 学习笔记 第三篇 依赖注入框架的使用
前言 首先感谢小可爱门的支持,写了这个系列的第二篇后,得到了好多人的鼓励,也更加坚定我把这个系列写完的决心,也能更好的督促自己的学习,分享自己的学习成果.还记得上篇文章中最后提及到,假如服务越来越多怎 ...
- ASP.NET Core 学习笔记 第四篇 ASP.NET Core 中的配置
前言 说道配置文件,基本大多数软件为了扩展性.灵活性都会涉及到配置文件,比如之前常见的app.config和web.config.然后再说.NET Core,很多都发生了变化.总体的来说技术在进步,新 ...
- Asp.net core 学习笔记 ( Data protection )
参考 : http://www.cnblogs.com/xishuai/p/aspnet-5-identity-part-one.html http://cnblogs.com/xishuai/p/a ...
- Asp.net core (学习笔记 路由和语言 route & language)
https://docs.microsoft.com/en-us/aspnet/core/mvc/controllers/routing?view=aspnetcore-2.1 https://doc ...
随机推荐
- Liunx运维(二)-文件与目录操作
文档目录: 一.pwd:显示当前位置 二.cd:切换目录 三.tree:树形结构显示目录 四.mkdir 创建目录 五.touch:创建空文件或改变文件时间戳 六.ls:显示目录下内容相关属性信息 七 ...
- P5733 【深基6.例1】自动修正
1.题目介绍 2. 题解 2.1 字符串大小写转换 思路 str[i] -= 'a' -'A'; 注意这里转换方式,即减去偏移量(ASCII码表中,'a'在'A'前面,如果记不得偏移量,就直接写'a' ...
- [java] - servlet路径跳转
Index.jsp <a href="servlet/HelloServlet">servlet/HelloServlet</a><br> &l ...
- SpringBoot03:首页国际化
页面国际化 有的时候,我们的网站会去涉及中英文甚至多语言的切换,这时候我们就需要学习国际化! 1.配置文件编写 首先在resources资源文件下新建一个i18n目录,存放国际化配置文件 新建一个lo ...
- Go-使用本地时间解析时间字符串
字符串 ==> time.Time package main import ( "fmt" "log" "time" ) func m ...
- [转帖]PostgreSQL数据库的版本历史及关键变化
https://cloud.tencent.com/developer/article/2311843 举报 PostgreSQL是一个强大的开源关系型数据库,它的发展历程充满了创新和卓越的设计.让我 ...
- [转帖]echo “新密码”|passwd --stdin 用户名
https://www.cnblogs.com/rusking/p/6912809.html --stdin This option is used to indicate that passwd s ...
- [转帖]Linux 防火墙开放特定端口 (iptables)
查看状态: iptables -L -n 下面添加对特定端口开放的方法: 使用iptables开放如下端口 /sbin/iptables -I INPUT -p tcp --dport 8000 -j ...
- [转帖][译]ARM大小核架构白皮书
https://zhuanlan.zhihu.com/p/33411449 ARM big.LITTLE Processing with ARM Cortex-A15 & Cortex-A7 ...
- [转帖] Linux文本命令技巧(下)
https://www.cnblogs.com/codelogs/p/16060108.html 简介# 前一篇介绍了Linux中一些基本的文本命令与使用技巧,但是结合场景过少,本篇结合工作中一些常见 ...