一、在 ASP.NET Core 中使用 SignalR
2024-09-05 13:01:41
一、介绍
SignalR 是一个用于实现实时网站的 Microsoft .NET 库。它使用多种技术来实现服务器与客户端间的双向通信,服务器可以随时将消息推送到连接的客户端。
二、新建Core MVC项目并安装
三、添加 SignalR 客户端库
在“解决方案资源管理器” 中,右键单击项目,然后选择“添加” >“客户端库”
在“添加客户端库” 对话框中,对于“提供程序” ,选择“unpkg” 。
对于“库” ,输入 @aspnet/signalr@1
,然后选择不是预览版的最新版本。
选择“选择特定文件” ,展开“dist/browser” 文件夹,然后选择“signalr.js” 和“signalr.min.js” 。
将“目标位置” 设置为 wwwroot/lib/signalr/ ,然后选择“安装” 。
四、创建 SignalR 中心即操作中心。
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
封装了很多常用方法(发送指定消息、群发...)
,我们可以很简单的使用达到目的
创建 Hubs 文件夹 。
在 Hubs 文件夹中,使用以下代码创建 ChatHub.cs 文件 :
using Microsoft.AspNetCore.SignalR;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks; namespace Ban.Hubs
{
public class ChatHub:Hub
{
/// <summary>
/// /服务端方法 发送消息--发送给所有连接的客户端
/// </summary>
/// <param name="user"></param>
/// <param name="message"></param>
/// <returns></returns>
public async Task SendMessage(string user,string message)
{
//ReceiveMessage 为客户端方法,让所有客户端调用这个方法
await Clients.All.SendAsync("ReceiveMessage",user,message);
} /// <summary>
/// 客户端连接的时候调用
/// </summary>
/// <returns></returns>
public override Task OnConnectedAsync()
{
Trace.WriteLine("客户端连接成功");
return base.OnConnectedAsync();
}//所有链接的客户端都会在这里 /// <summary>
/// 连接终止时调用。
/// </summary>
/// <returns></returns>
public override Task OnDisconnectedAsync(Exception exception)
{
Trace.WriteLine("连接终止");
return base.OnDisconnectedAsync(exception);
} }
}
六、配置 SignalR
必须配置 SignalR 服务器,以将 SignalR 请求传递到 SignalR。
startup
中ConfigureServices
方法内部添加SignalR
服务services.AddSignalR();
,Configure
中配置具体的Hub
(路由器、中转):
app.UseSignalR(routes =>
{
routes.MapHub<TestHub>("/testHub"); //可以多个map
}); app.UseMvc(); //注意UseSignalR需要在UseMvc()之前
这样SignalR
服务器端就开发完成了,网页、Java、.Net客户端都可以连接的
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using test.Hubs; //3、引用 处理客户端 - 服务器通信的高级管道
namespace test
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.AddSignalR();//1、添加服务
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
}
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseSignalR(routes => //2、引用
{
routes.MapHub<ChatHub>("/chatHub");
});
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
}
}
七、添加 SignalR 客户端代码(创建index控制器和视图)
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Index</title>
</head>
<body>
<div class="container">
<div class="row"> </div>
<div class="row">
<div class="col-6"> </div>
<div class="col-6">
User..........<input type="text" id="userInput" />
<br />
Message...<input type="text" id="messageInput" />
<input type="button" id="sendButton" value="Send Message" />
</div>
</div>
<div class="row">
<div class="col-12">
<hr />
</div>
</div>
<div class="row">
<div class="col-6"> </div>
<div class="col-6">
<ul id="messagesList"></ul>
</div>
</div>
</div>
<script src="~/lib/signalr/dist/browser/signalr.js"></script>
<script type="text/javascript">
"use strict";
var connection = new signalR.HubConnectionBuilder().withUrl("/chatHub").build();
//在建立连接之前禁用发送按钮
document.getElementById("sendButton").disabled = true;
//接受消息
connection.on("ReceiveMessage", function (user, message) {
var msg = message.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
var encodedMsg = user + " says " + msg;
var li = document.createElement("li");
li.textContent = encodedMsg;
document.getElementById("messagesList").appendChild(li);
});
//开始链接
connection.start().then(function () {
document.getElementById("sendButton").disabled = false;
}).catch(function (err) {
return console.error(err.toString());
});
//发送消息
document.getElementById("sendButton").addEventListener("click", function (event) {
var user = document.getElementById("userInput").value;
var message = document.getElementById("messageInput").value;
connection.invoke("SendMessage", user, message).catch(function (err) {
return console.error(err.toString());
});
event.preventDefault();
});
</script>
</body>
</html>
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();
}
最新文章
- oracle数据库表的导入导出cmd命令大全
- org.apache.hadoop.hbase.TableNotDisabledException 解决方法
- poj1182 食物链(种类并查集)详解
- 开启MYSQL远程连接权限
- php模块memcache和memcached区别分析
- android媒体--图库与API层MediaPlayer的交互
- 团队作业10——beta阶段项目复审
- 棋盘的完美覆盖问题,c++代码实现
- 在虚拟机中安装Centos系统
- 个人常用的移动端浅灰底index.html
- SQL 聚集函数(聚组函数)的使用 注意事项
- java clone()
- nginx 限制并发访问及请求频率
- MySQL查看、创建和删除索引的方法
- 如果你在it院校学习累了,你能干什么?
- 关于java中BufferedReader的read()及readLine()方法的使用心得
- 1063. Set Similarity
- SpringMvc整合Mybatis并使用声明式事务
- linux目录结构介绍
- CentOS 7 安装Docker CE
热门文章
- javascript注
- java中的同步和异步
- 论文学习 :Learning a Deep Convolutional Network for Image Super-Resolution 2014
- 【C++ STL 优先队列priority_queue】
- CentOS 6、CentOS7 防火墙开放指定端口
- centos6.5+jdk1.7+mysql5.6+tomcat8.0部署jpress
- 【ABAP系列】SAP ABAP中ALV使用HTML的例子
- 【Python】我的第一个完整的小说爬虫
- finereport点击图表钻取到明细表包括参数传递
- docker 一些命令