信号机中彩色消息推送模式的实现代码
在上一篇signor文章中,演示了如何通过signor实现简单的聊天室功能。基于简单即美的原则,我们也将在SignalR中谈论用户和组的概念。了解这些基础知识将有助于更好地开发基于SignalR的应用。通过了解用户和群组,进一步拓展用户和群组的管理以及消息推送的各种方式,为全面接入SignalR做好准备。
1.用户
在SignalR中,一个用户代表一个连接,一个用户代表一个连接,“系统用户”可以创建多个连接标识,通过一个功能中枢,可以将消息发送给一个用户的所有连接;比如一个“系统用户”有多个连接,分别是Web连接、AndroId手机客户端连接、IOS手机客户端连接或其他客户端连接。“系统用户”分别登录这些客户端,同时创建多个连接;默认情况下,这些连接通过ClaimTypes.NameIdentifier与ClaimsPrincipal的用户标识相关联。
* *注意:用户标识符区分大小写。为了实现一个客户的多个连接,这个例子还简单实现了一个基于ClaimsIdentity的登录界面,这是一个惊喜。
1.1用户连接管理
为了直观地观察到用户可以有多个连接,需要建立一个本地静态对象来存储用户连接
公共类微信: Hub { public dictionary string,Liststring UserList { get设置;}=new Dictionarystring,Liststring();公共无效发送(聊天消息正文){客户端。All.SendAsync('Recv ',body);}公共覆盖Task OnConnectedAsync(){ var userName=this。上下文。用户。身份。名称;var connectionId=this。上下文。连接标识;if(!用户列表。contains key(userName)){ userrist[userName]=new Liststring();用户列表[用户名]。添加(连接标识);} else if(!用户列表[用户名]。包含(连接标识)){用户列表[用户名]。添加(连接标识);}控制台。WriteLine('哇,有人进来了:{0}、{1}、{2} '、this.context.useridentifier、this . context . user . identity . name、this . context . connectionid);返回基地。onConnectedAsync();}公共覆盖任务OnDisconnectedAsync(异常异常){ var userName=this。上下文。用户。身份。名称;var connectionId=this。上下文。连接标识;if(用户列表。包含密钥(用户名)){如果(用户列表[用户名]。包含(连接标识)){用户列表[用户名]。移除(连接标识);}}控制台。WriteLine('妈的,有人跑了:{0} ',这个。context . ConnectionId);返回基地。OnDisconnectedAsync(异常);}}上面的代码包含一个内部成员UserList,用于存储用户的每个连接。当用户建立SignalR连接时,当前连接存储在用户列表中,当连接断开时,当前连接从用户列表中删除。这样,实现了简单的用户连接管理。
在上面的代码中,当前用户昵称基于varusername=this . context . user . identity . name;为了获得这个用户昵称,我们实现了一个简单的UserIdentity登录,然后将用户信息写入Cookie,最后传递varusername=this。context . user . identity . name;获取当前登录用户的昵称(熟悉ID登录流程的同学应该不陌生,其实我很少使用ID认证)
1.2向单个用户发送消息
[授权(角色='用户')][http set('发送用户')]公共异步任务结果发送用户([FromBody]用户信息视图模型){聊天消息=新聊天消息(){类型=1,内容=模型。内容,用户名=型号。用户名};if(this . ChatHub . UserList . Contains KeY(模型。UserName)){ var connections=this . ChatHub . UserList[model。用户名]。first();等待这个。SendAsync('Recv ',新对象[]{ message });}返回Json(新{ Code=0 });}在UserController中,定义了上面的接口SendToUser,客户端传入用户昵称和消息,然后服务器会根据ChatHub查询目标用户的连接信息。用户列表成员,最后通过SendAsync将消息推送到目标客户端连接。
2.分组
分组的概念类似于聊天室。每个房间都是独立的分组。用户可以选择加入A室或b室,如果业务允许,一个用户也可以加入多个群组(房间)。通过分组管理用户,可以实现一个或多个聊天室。用户可以加入群或从群中删除用户(类似于离开房间)。这里的用户和真正的“系统用户”是并发的。
* *注意:断开连接后重新启动连接时,SignalR将不会保留组成员身份,必须重新加入组。
下面的代码演示了如何进行分组操作,主要包括三个方面:
2.1加入分组
公共异步任务地址组同步(字符串组名){等待组。AddToGroupAsync(这个。Context.ConnectionId,group name);}2.2离开群组
公共异步任务移除自组异步(字符串组名){等待组。RemoveFromGroupAsync(这。Context.ConnectionId,group name);}2.3向指定的数据包发送消息
公共异步任务发送组同步(字符串组名,聊天消息消息){等待客户端。组(组名)。SendAsync(groupName,new object[]{ message });}分组操作非常简单,几乎是一行代码。不得不说微软的封装真的很好。
3.信号员推送信息的其他方式
通过以上对用户和群组的学习,再扩展其他方式推送消息的学习,非常容易理解和上手。在SignalR内部推送消息的方式也有很多。他们是
3.1全部(从所有站点推送)
3.2其他(推全站排除自己)
3.3其他组(指定分组推送并排除自己)
3.4例外情况(除指定列表外的所有人)
3.5演示代码
Liststring黑名单=new list string();public async task other send async(chat message body){//向当前连接到集线器的所有连接发送消息相当于广播await clients . all . send async(' recv ',body);//将消息await clients . caller . send async(' recv ',body)发送到当前连接对象;//向除当前连接的客户端await clients . others . send async(' recv ',body)以外的所有其他连接的客户端发送消息;//查找当前连接的所有客户端(不包括自己),如果已经加入该组,将消息awaitclients推给他们。other sing group(' group name ')。sendasync ('recv ',body);//发送消息通知客户。allexcept(黑名单)。将async ('recv ',body)发送给黑名单以外的所有人;}4.一个简单的例子
这个示例代码包含两个简单的接口
4.1登录
4.2以各种方式发送消息
结束语
最近在做一个开源项目,还在试用阶段。我打算写一个WIKI,看看大家是否感兴趣。这个SingalR系列只能不定期更新。不好意思。
演示代码下载
已管理到GitHub存储库
https://github.com/lianggx/Examples/tree/master/SignalR/Ron.信号传感器2
以上就是本文的全部内容。希望对大家的学习有帮助,支持我们。
版权声明:信号机中彩色消息推送模式的实现代码是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。