SignalR Self Host+MVC等多端消息推送服务(一)

2025-05-29 0 23

一、概述

由于项目需要,最近公司项目里有个模块功能,需要使用到即时获得审批通知;原本的设计方案是使用ajax对服务器进行定时轮询查询,刚刚开始数据量和使用量不大的时候还好,后来使用量的增加和系统中各种业务的复杂度增加,服务器的压力也越来越大,于是我想使用消息推送的方式替换掉ajax轮询查询,当有审批提交时,调用推送方法,将消息推送到下一审批人那,这样就减低了服务器的压力。

Signal 是微软支持的一个运行在.NET平台上的 html websocket 框架。它出现的主要目的是实现服务器主动推送消息到客户端页面,这样客户端就不必重新发送请求或使用轮询技术来获取消息。而且SignalR的兼容性也是很强大的,这里不在多言。既然选择了SignalR,那么就开始干吧!

我的想法是将SignalR做成一个自托管的服务,和我们的b/s项目分离出来,这样的好处是,1、推送服务不依赖于iis,就算iis挂了,我们的推送服务还可以正常运行;2、我们可以多平台调用这个推送服务,多个项目都可以同时使用;

二、创建服务端

废话不多说了,我也是第一次写博客,介绍完业务场景和构思,我们就开始撸码吧。

1、用VS创建一个名为 "SignalRProject" 的解决方案;

SignalR Self Host+MVC等多端消息推送服务(一)

2、在 SignalRProject解决方案下新建一个名为Server的控制台

SignalR Self Host+MVC等多端消息推送服务(一)

3、在程序包管理器控制台,输入如下命令

?

1
Install-Package Microsoft.AspNet.SignalR.SelfHost

SignalR Self Host+MVC等多端消息推送服务(一)

4、输入如下命令:

?

1
Install-Package Microsoft.Owin.Cors

SignalR Self Host+MVC等多端消息推送服务(一)

5、在Server控制台中添加UserInfo类,代码如下

?

1

2

3

4

5

6

7

8

9

10

11
using System;

namespace Server

{

public class UserInfo

{

public string ConnectionId { get; set; }

public string UserName { get; set; }

public DateTime LastLoginTime { get; set; }

}

}

SignalR Self Host+MVC等多端消息推送服务(一)

6、在Server控制台中添加ChatHub类,代码如下

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127
using Microsoft.AspNet.SignalR;

using Microsoft.AspNet.SignalR.Hubs;

using System;

using System.Collections.Generic;

using System.Linq;

using System.Threading.Tasks;

namespace Server

{

[HubName("IMHub")]

public class ChatHub : Hub

{

// 静态属性

public static List<UserInfo> OnlineUsers = new List<UserInfo>(); // 在线用户列表

/// <summary>

/// 登录连线

/// </summary>

/// <param name="userId">用户Id</param>

/// <param name="userName">用户名</param>

public void Register(string userName)

{

var connnectId = Context.ConnectionId;

if (OnlineUsers.Count(x => x.ConnectionId == connnectId) == 0)

{

if (OnlineUsers.Any(x => x.UserName == userName))

{

var items = OnlineUsers.Where(x => x.UserName == userName).ToList();

foreach (var item in items)

{

Clients.AllExcept(connnectId).onUserDisconnected(item.ConnectionId, item.UserName);

}

OnlineUsers.RemoveAll(x => x.UserName == userName);

}

//添加在线人员

OnlineUsers.Add(new UserInfo

{

ConnectionId = connnectId,

UserName = userName,

LastLoginTime = DateTime.Now

});

}

// 所有客户端同步在线用户

Clients.All.onConnected(connnectId, userName, OnlineUsers);

}

/// <summary>

/// 发送私聊

/// </summary>

/// <param name="toUserId">接收方用户连接ID</param>

/// <param name="message">内容</param>

public void SendPrivateMessage(string toUserName, string message)

{

var fromConnectionId = Context.ConnectionId;

var toUser = OnlineUsers.FirstOrDefault(x => x.UserName == toUserName);

var fromUser = OnlineUsers.FirstOrDefault(x => x.ConnectionId == fromConnectionId);

if (toUser != null )

{

Clients.Client(toUser.ConnectionId).receivePrivateMessage(fromUser.UserName, message);

Clients.Client(toUser.ConnectionId).receivePrivateMessage(message);

}

else

{

//表示对方不在线

Clients.Caller.absentSubscriber();

}

}

public void Send(string name, string message)

{

//Clients.All { get; } // 代表所有客户端

//Clients.AllExcept(params string[] excludeConnectionIds); // 除了参数中的所有客户端

//Clients.Client(string connectionId); // 特定的客户端,这个方法也就是我们实现端对端聊天的关键

//Clients.Clients(IList<string> connectionIds); // 参数中的客户端

//Clients.Group(string groupName, params string[] excludeConnectionIds); // 指定客户端组,这个也是实现群聊的关键所在

//Clients.Groups(IList<string> groupNames, params string[] excludeConnectionIds);参数中的客户端组

//Clients.User(string userId); // 特定的用户

//Clients.Users(IList<string> userIds); // 参数中的用户

Console.WriteLine("ConnectionId:{0}, InvokeMethod:{1}", Context.ConnectionId, "Send");

Clients.All.addMessage(name, message);

}

/// <summary>

/// 连线时调用

/// </summary>

/// <returns></returns>

public override Task OnConnected()

{

Console.WriteLine("客户端连接,连接ID是:{0},当前在线人数为{1}", Context.ConnectionId, OnlineUsers.Count+1);

return base.OnConnected();

}

/// <summary>

/// 断线时调用

/// </summary>

/// <param name="stopCalled"></param>

/// <returns></returns>

public override Task OnDisconnected(bool stopCalled)

{

var user = OnlineUsers.FirstOrDefault(u => u.ConnectionId == Context.ConnectionId);

// 判断用户是否存在,存在则删除

if (user == null)

{

return base.OnDisconnected(stopCalled);

}

Clients.All.onUserDisconnected(user.ConnectionId, user.UserName); //调用客户端用户离线通知

// 删除用户

OnlineUsers.Remove(user);

Console.WriteLine("客户端断线,连接ID是:{0},当前在线人数为{1}", Context.ConnectionId, OnlineUsers.Count);

return base.OnDisconnected(stopCalled);

}

public override Task OnReconnected()

{

return base.OnReconnected();

}

}

}

SignalR Self Host+MVC等多端消息推送服务(一)

7、在Server控制台中添加Startup类,代码如下

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15
using Microsoft.Owin.Cors;

using Owin;

namespace Server

{

public class Startup

{

public void Configuration(IAppBuilder app)

{

//允许CORS跨域

app.UseCors(CorsOptions.AllowAll);

app.MapSignalR();

}

}

}

SignalR Self Host+MVC等多端消息推送服务(一)

8、修改Server控制台中添加Program类,代码如下

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18
using Microsoft.Owin.Hosting;

using System;

namespace Server

{

class Program

{

static void Main(string[] args)

{

string url = "http://localhost:10086";//设定 SignalR Hub Server 对外的接口

using (WebApp.Start(url))//启动 SignalR Hub Server

{

Console.WriteLine("Server running on {0}", url);

Console.ReadLine();

}

}

}

}

SignalR Self Host+MVC等多端消息推送服务(一)

9、F5运行起来

然后浏览器中访问http://localhost:10086/signalr/hubs

结果如下:

SignalR Self Host+MVC等多端消息推送服务(一)

见上图内容就基本完成了,今天先讲到着,时间不早了,先休息了,后续有时间再将后面的文章补上

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持快网idc。

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

快网idc优惠网 建站教程 SignalR Self Host+MVC等多端消息推送服务(一) https://www.kuaiidc.com/99596.html

相关文章

发表评论
暂无评论