(一)SignalR(.net 中的用法)

SignalR实现了服务端主动向客户端响应信息,以及一个客户端向其他客户端主动推送消息,相比于websocket他支持了windows7以及windows server2012,对于低版本的浏览器也更加兼容了

实现原理,当客户端推送第一次和服务端建立链接后,服务端将客户端的长链接保存起来,服务端之后的消息都是通过呢个长连接进行信息的相互发送

后端逻辑

1:在nuget中引入:Microsoft.AspNet.SignalR

2:在项目中新建一个文件夹,在文件夹里面新建两个文件

SignalR 集线器(用来广播消息的类),继承Hub类

OWIN Startup 类(作用是指定SignalR在生成管道的路径,开启跨域的操作),命名空间上带有[assembly: OwinStartup(typeof(sigrservice.Common.Startup1))]的特性

3:对单个客户端页面的推送

Clients.Client("connectionId").showMessageffff(content, "hhh", "kkk");

4:对多个客户端页面的推送

Clients.Clients(array).showMessageffff(content, "hhh", "kkk");//string[] array,array是一个数组

5:集线器类

[HubName("messageHubHss")]
public class MyHub1 : Hub
{
public static List<Clj> cljs = new List<Clj>();

// 向所有客户端发送信息
public void LiaoTian(string s, string yy, string zz)
{
GlobalHost.ConnectionManager.GetHubContext<MyHub1>().Clients.All.showMessageffff(s + yy + zz, "hhh", "kkk");
}
// 向自己所在的客户端发送信息
public void CallSelf(string content)
{
Clients.Caller.showMessageffff(content, "hhh", "kkk");
}
//向自己以外的所有其他客户端发送信息
public void CallOther(string content)
{
Clients.Others.showMessageffff(content, "hhh", "kkk");
}

#region 发送给指定的用户
//发送给指定连接
public void CallOne(string toName, string content)
{
#region 
//给某个用户打开的所有页面发送信息
//Clients.Group(toName).showMessageffff(content, "hhh", "kkk");
#endregion

#region  给多个用户打开的所有用户发送信息(张三打开2个页面,李四打开3个页面,那么5个页面都会收到信息)
string[] aa = { "zhangsan", "lisi" };
Clients.Groups(aa).showMessageffff(content, "hhh", "kkk");
#endregion

}

//客户端和服务端建立链接后要做的事情
public override Task OnConnected()
{
string username = Context.QueryString["userName"]; //将用户名作为一个组名来存储,这样相同用户的所有ConnectionId都存到一个组里面了,方便以后对指定的用户发送信息
Groups.Add(Context.ConnectionId, username);
return base.OnConnected();
}
#endregion

}

 6:建立OWIN Startup 类

[assembly: OwinStartup(typeof(sigrservice.Common.Startup1))]

namespace sigrservice.Common
{
public class Startup1
{
public void Configuration(IAppBuilder app)
{
//集线器是对持久连接类再一次的进行封装,集线器类都继承自Hub,集线器类可以让我们使用RPC(远程链接,长连接)的方式进行交互。
app.UseCors(CorsOptions.AllowAll);//引用跨域
//app.MapSignalR();此方法的作用是将 SignalR 集线器默认映射到“/signalr”处的应用生成器管道
app.MapSignalR("/MySignalr", new HubConfiguration());//可以修改生成管道

}
}
}

7:前端向服务端推送消息的方式可以通过api以调用接口的形式推送,也可以不经过api接口推送

经过接口推送的方式为:

[Route("Getvalts")]
[HttpGet]
public string Getval(string id)
{
var hui = GlobalHost.ConnectionManager.GetHubContext<MyHub1>();
hui.Clients.All.showMessageffff(id + "222", "hhh", "kkk");
return "value";
}

前端逻辑

1: 推送信息的页面

先引入3个js,并且是后端的远程js(可能客户端和服务端不在同一台服务器)

<script src="http://localhost:57147/Scripts/jquery-3.4.1.min.js"></script>
<script src="http://localhost:57147/Scripts/jquery.signalR-2.4.2.js"></script>
<script src="http://localhost:57147/MySignalr/Hubs"></script>

<script>
jQuery.support.cors = true;
$(function () {
$.connection.hub.url = "http://localhost:57147/MySignalr";
var hub = $.connection.messageHubHss;//对应MyHub1里面得[HubName("messageHubHss")](messageHubHss)集线器名称

$.connection.hub.qs = { 'userName': "zhangsan" };//初次链接传到服务端的参数,userName一个标识自己的sigr链接的名称,用来存储,服务端就通过呢个标识来进行推送消息

//接收后端推送过来的消息

hub.client.showMessageffff = function (msg, h, k) {//支持多个参数,不用像websocket在对一个字符串解析了
$("#sss").append(msg + " " + h + " " + k) + "</br>"
}
$.connection.hub.logging = true;
$.connection.hub.start();

// //点击按钮后进行消息推送,直推通过集线器管道进行响应,不调用接口
// $.connection.hub.start()
// .done(function () {
// $("#only").click(function () {
// hub.server.sallOne2("lisi", $('#t2').val()); //将信息推送到指定的客户端
// });
//});
})

//以调用接口的方式进行消息推送
//var hui = GlobalHost.ConnectionManager.GetHubContext<MyHub1>();
//hui.Clients.All.showMessageffff(id + "222");进行消息推送
function Clicka() {
$.ajax({
type: "GET",
url: "http://localhost:82/api/Test/Getvalts",
data: { id: "ssffff" },
dataType: "text",
success: function (data) {
//alert(data)
}
});
}
</script>

<body>
<div>
<div>
<span id="sss"></span>
</div>

@*以调用api的方式进行推送*@
<a href="javascript:void(0);" onclick="Clicka()">api发送</a>
内容:<input id="t2" type="text" /><br /><br />
@*推送给所有人,直推通过集线器管道进行响应,不调用接口*@
<input id="b1" type="button" value="推送给所有人" onclick="$.connection.messageHubHss.invoke('LiaoTian',$('#t2').val(),'xx','yy');" /><br /><br />
@*只推送给自己,直推通过集线器管道进行响应,不调用接口*@
<input id="myself" type="button" value="推送给自己" onclick="$.connection.messageHubHss.invoke('CallSelf',$('#t2').val());" /><br /><br />
@*推送给自己以外的所有人,直推通过集线器管道进行响应,不调用接口*@
<input id="other" type="button" value="推送给其他人" onclick="$.connection.messageHubHss.invoke('CallOther',$('#t2').val());" /><br /><br />
@*推送给指定的人,$.connection.hub.start().done(function () {})放到指定函数执行,不调用接口*@
@*<input id="only" type="button" value="推送给指定的人" /><br /><br />*@
<input id="only" type="button" value="推送给指定的人,直推通过集线器管道进行响应,不调用接口" onclick="$.connection.messageHubHss.invoke('CallOne','lisi',$('#t2').val());" /><br /><br />
</div>
</body>

2: 接收信息的页面

引入3个远程的服务端的js

<script src="http://localhost:57147/Scripts/jquery-3.4.1.min.js"></script>
<script src="http://localhost:57147/Scripts/jquery.signalR-2.4.2.js"></script>
<script src="http://localhost:57147/MySignalr/Hubs"></script>

<script>
jQuery.support.cors = true;
$(function () {
/* $.connection.hub.url = "http://localhost:82/MySignalr";*/
$.connection.hub.url = "http://localhost:57147/MySignalr";
//对应MyHub1里面得[HubName("messageHubHss")](messageHubHss)
var hub = $.connection.messageHubHss;
$.connection.hub.qs = { 'userName': 'lisi' };//userName一个标识自己的sigr链接的名称,用来存储,服务端就通过呢个标识来进行推送消息

//接收后端推送过来的消息
hub.client.showMessageffff = function (msg, h, k) {//支持多个参数,不用像websocket在对一个字符串解析了
var ss=msg + " " + h + " " + k+"</br>"
$("#sss").append(ss)
}
$.connection.hub.logging = true;
$.connection.hub.start();
})

</script>

<body>
<div>
<span id="sss"></span>
</div>

</body>

非服务器iis对最大长连接的限制个数为10,修改呢个限制的方法是在iis的应用程序池-设置应用程序池默认设置-进程模型-最大工作进程数进行修改

posted @   yingxianqi  阅读(561)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示