ASP.NET SingalR 点对点聊天实现思路总结
前一段时间写了一个简单的聊天室,是群聊的方式。博客地址:http://www.cnblogs.com/panzi/p/4980346.html。还有一种需求就是常见的尤其是培训机构的主页面,经常会有1对1咨询聊天窗口。那么用singalR如何实现1对1聊天呢。
其实很简单。我们先看看SingalR里的IHubConnectionContext接口代码:
public interface IHubConnectionContext<T>
{
//所有连接服务器的用户
T All { get; }
//除了一部分用户
T AllExcept(params string[] excludeConnectionIds);
//这个就是我们要用的点对点,针对单个用户发送消息
T Client(string connectionId);
//群发消息
T Clients(IList<string> connectionIds);
//按组群发消息
T Group(string groupName, params string[] excludeConnectionIds);
//多组群发消息
T Groups(IList<string> groupNames, params string[] excludeConnectionIds);
//用户
T User(string userId);
T Users(IList<string> userIds);
}
这里我们就用 T Client(string connectionId); 这个方法。调用方式为 Clients.Client("connectionId").clientFun(msg); //(clientFun为自定义客户端接收消息方法名)具体细节不在描述,这里比较关键的就是,如何知道对方的ConnectionId,因为ConnectionId是自动生成的而且,每次刷新页面都会变,SingalR本身又不带统计在线用户的方法,所以,这个需要自己去实现。思路很清晰,这里先用 静态List做用户在线列表信息存储。代码如下:
/// <summary>
/// 简单用户统计model
/// </summary>
public class HubUser
{
/// <summary>
/// 连接服务器之后,自动生成的connectionId
/// </summary>
public string ConnectionId { get; set; }
/// <summary>
/// 客户端用户的主键ID
/// 一般和业务相关的用户ID
/// </summary>
public string ClientUserId { get; set; }
/// <summary>
/// 聊天所在组
/// </summary>
public string GroupId { get; set; }
}
public sealed class OnlineUserPool
{
private static Lazy<List<HubUser>> _onlineUser = new Lazy<List<HubUser>>();
public static List<HubUser> OnlineUser { get { return _onlineUser.Value; } } /// <summary>
/// 添加用户,一般在用户 连接服务器或者用户重新连接的时候
/// </summary>
/// <param name="user"></param>
public static void AddUser(HubUser user)
{
DeleteUser(user);
_onlineUser.Value.Add(user);
}
/// <summary>
/// 删除某个在线用户
/// </summary>
/// <param name="clientUserId"></param>
/// <param name="connectionId"></param>
public static void DeleteUser(HubUser user, bool unConnected = true)
{
var onlineUser = IsOnline(user);
if (onlineUser != null)
{
_onlineUser.Value.Remove(onlineUser);
}
}
public static HubUser IsOnline(HubUser user)
{
if (user == null) { throw new ArgumentNullException(); }
string clientUserId = user.ClientUserId;
string connectionId = user.ConnectionId;
if (!string.IsNullOrEmpty(clientUserId))
{
return _onlineUser.Value.FirstOrDefault(x => x.ClientUserId == clientUserId);
}
else
{
return _onlineUser.Value.FirstOrDefault(x => x.ConnectionId == connectionId);
}
}
/// <summary>
/// 获取在线总数
/// </summary>
/// <returns></returns>
public static long GetUserCount()
{
return _onlineUser.Value.Count;
}
}
可以看到 OnlineUserPool 类实现了往静态列表添加用户,删除用户等一系列操作。
添加用户操作需要,在用户接入到聊天室的时候执行:
public Task Join(ZjMessage message)
{
message.connectionId = Context.ConnectionId;
//就是用户加入的时候
OnlineUserPool.AddUser(new HubUser
{
ClientUserId = message.userid,
ConnectionId = Context.ConnectionId
});
message.msg = "当前已经有:" + OnlineUserPool.GetUserCount() + " 人在线";
return Clients.All.receiveMessage(new { type = "join", msg = message });
}
删除用户操作就在重写OnDisconnect方法里执行,需要根据ConnectionId删除
public override Task OnDisconnected(bool stopCalled)
{
ZjMessage message = new ZjMessage(Context.ConnectionId);
//用户离开
//用户断线,需要将该用户从列表中删除,(应该考虑短暂失去连接的可能性,不能直接从列表删除。)
OnlineUserPool.DeleteUser(new HubUser
{
ConnectionId = Context.ConnectionId
});
return Clients.All.receiveMessage(new { type = "left", msg = message });
}
所以,当你想点对点发送消息的时候,将对方userId传送到服务器,然后服务器从在线列表里面查询出相应的connectionID,然后将消息推送到该connectionID的用户,就实现了在线两个人聊天了。当然,用静态列表的方式也不是很好,如果用户量庞大,会不会出什么问题呢,我具体没研究过。一般的方案,是放在专门的缓存服务器存储,或者NOSQL数据库存储也可以吧,方案有很多,由于没有具体做过也不敢多费口舌。这个思路是没问题的,当然也会有更好的方法吧。
ASP.NET SingalR 点对点聊天实现思路总结的更多相关文章
- ASP.NET SingalR + MongoDB 实现简单聊天室(一):搭建基本框架
ASP.NET SingalR不多介绍.让我介绍不如看官网,我这里就是直接上源代码,当然代码还是写的比较简单的,考虑的也少,希望各位技友多多提意见. 先简单介绍聊天室功能: 用户加入聊天室,自动给用户 ...
- Activemq mqtt 点对点聊天实现(转载)
我这想到一个点对点聊天的方法,不用没割人都建立一个topic了,思路还是自定义一个分发策略,具体如下: 1. 建立一个topic,所有人都用匹配订阅的方式订阅以该topic为头的topic,例如:所 ...
- Linux 网络编程详解三(p2p点对点聊天)
//p2p点对点聊天多进程版--服务器(信号的使用) #include <stdio.h> #include <stdlib.h> #include <string.h& ...
- AngularJS使用OData请求ASP.NET Web API资源的思路
本篇整理AngularJS使用OData请求ASP.NET Web API资源的思路. 首先给ASP.NET Web API插上OData的翅膀,通过NuGet安装OData. 然后,给control ...
- Angular 2的HTML5 pushState在ASP.NET Core上的解决思路
Angular 2的HTML5 pushState在ASP.NET Core上的解决思路 正如Angular 2在Routing & Navigation中所提及的那样,Angular 2是推 ...
- ASP.NET SingalR + MongoDB 实现简单聊天室(三):实现用户群聊,总结完善
前两篇已经介绍的差不多了,本篇就作为收尾. 使用hub方法初始化聊天室的基本步骤和注意事项 首先确保页面已经引用了jquery和singalR.js还有对应的hubs文件,注意,MVC框架有时会将jq ...
- ASP.NET SingalR + MongoDB 实现简单聊天室(二):实现用户信息、聊天室初始化,聊天信息展示完善
第一篇已经介绍了一大半了,下面就是详细业务了,其实业务部分要注意的地方有几个,剩下的就是js跟html互动处理. 首先在强调一下,页面上不可缺少的js:jquery,singalR.js,hubs . ...
- ASP.NET 大文件下载的实现思路及代码
文件下载是一个网站最基本的功能,ASP.NET网站的文件下载功能实现也很简单,但是如果遇到大文件的下载而不做特殊处理的话,那将会出现不可预料的后果.本文就基于ASP.NET提供大文件下载的实现思路及代 ...
- 使用SignalR+Asp.net创建实时聊天应用程序
一.概述: 使用 ASP.NET 那么 SignalR 2 创建一个实时聊天应用程序.将 SignalR 添加 MVC 5 应用程序中,并创建聊天视图发送并显示消息. 在Demo中,将学习Signal ...
随机推荐
- 提示"No 'Access-Control-Allow-Origin' header"及Spring 中解决跨域问题
问题描述 No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://12 ...
- 流畅的python和cookbook学习笔记(八)
1.函数的默认参数必须不可变 如果函数的默认参数为可变的对象,那么默认参数在函数外被修改也会影响到函数本身的. >>> def spam(a, b=None): # b要为不可变参数 ...
- 在CentOS 7下更改yum源与更新系统
在CentOS 7下更改yum源与更新系统. [1] 首先备份/etc/yum.repos.d/CentOS-Base.repo cp /etc/yum.repos.d/CentOS-Base.rep ...
- influxdb 端口、数据结构、写数据
InfluxDB 是一个开源,分布式,时间序列,事件,可度量和无外部依赖的数据库. InfluxDB有三大特性: Time Series (时间序列):你可以使用与时间有关的相关函数(如最大,最小,求 ...
- 设计模式入门,单件模式,c++代码实现
// test05.cpp : Defines the entry point for the console application.// #include "stdafx.h" ...
- unity3d之控制人物转向移动并播放动画
tip:transition 勾选Has Exit Time B动画播放完毕后就可以自己返回A不用代码控制.因为想做一个小人静止时 隔两秒会摆动小手的特效. 附上代码参考: using UnityEn ...
- windows 2003 安装 MVC 环境 404错误,无法找到该页
在windows server 2003 IIS6 系统安装 DotNet 4.0 + MVC3 环境后, .cshtml 文件依然无法运行,404错误 解决方案:查看处理程序隐射,如果没有.csht ...
- if(!IsPostBack)
作用: Page.IsPostBack 是用来检查目前网页是否为第一次加载,当使用者第一次浏览这个网页时Page.IsPostBack 会传回False,不是第一次浏览这个网页时就传回True:所以当 ...
- 日常捕获的野生知识 - javascript获取屏幕大小
刚刚接触JavaScript,涉及到 document , window 的一些基本知识不是很了解,今天为了一个屏幕大小折腾了半天,幸好找到了很好的例子学习. 代码如下: <html> & ...
- 【Supervised Learning】支持向量机SVM (to explain Support Vector Machines (SVM) like I am a 5 year old )
Support Vector Machines 引言 内核方法是模式分析中非常有用的算法,其中最著名的一个是支持向量机SVM 工程师在于合理使用你所拥有的toolkit 相关代码 sklearn-SV ...