前一段时间写了一个简单的聊天室,是群聊的方式。博客地址: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 点对点聊天实现思路总结的更多相关文章

  1. ASP.NET SingalR + MongoDB 实现简单聊天室(一):搭建基本框架

    ASP.NET SingalR不多介绍.让我介绍不如看官网,我这里就是直接上源代码,当然代码还是写的比较简单的,考虑的也少,希望各位技友多多提意见. 先简单介绍聊天室功能: 用户加入聊天室,自动给用户 ...

  2. Activemq mqtt 点对点聊天实现(转载)

    我这想到一个点对点聊天的方法,不用没割人都建立一个topic了,思路还是自定义一个分发策略,具体如下: 1.  建立一个topic,所有人都用匹配订阅的方式订阅以该topic为头的topic,例如:所 ...

  3. Linux 网络编程详解三(p2p点对点聊天)

    //p2p点对点聊天多进程版--服务器(信号的使用) #include <stdio.h> #include <stdlib.h> #include <string.h& ...

  4. AngularJS使用OData请求ASP.NET Web API资源的思路

    本篇整理AngularJS使用OData请求ASP.NET Web API资源的思路. 首先给ASP.NET Web API插上OData的翅膀,通过NuGet安装OData. 然后,给control ...

  5. Angular 2的HTML5 pushState在ASP.NET Core上的解决思路

    Angular 2的HTML5 pushState在ASP.NET Core上的解决思路 正如Angular 2在Routing & Navigation中所提及的那样,Angular 2是推 ...

  6. ASP.NET SingalR + MongoDB 实现简单聊天室(三):实现用户群聊,总结完善

    前两篇已经介绍的差不多了,本篇就作为收尾. 使用hub方法初始化聊天室的基本步骤和注意事项 首先确保页面已经引用了jquery和singalR.js还有对应的hubs文件,注意,MVC框架有时会将jq ...

  7. ASP.NET SingalR + MongoDB 实现简单聊天室(二):实现用户信息、聊天室初始化,聊天信息展示完善

    第一篇已经介绍了一大半了,下面就是详细业务了,其实业务部分要注意的地方有几个,剩下的就是js跟html互动处理. 首先在强调一下,页面上不可缺少的js:jquery,singalR.js,hubs . ...

  8. ASP.NET 大文件下载的实现思路及代码

    文件下载是一个网站最基本的功能,ASP.NET网站的文件下载功能实现也很简单,但是如果遇到大文件的下载而不做特殊处理的话,那将会出现不可预料的后果.本文就基于ASP.NET提供大文件下载的实现思路及代 ...

  9. 使用SignalR+Asp.net创建实时聊天应用程序

    一.概述: 使用 ASP.NET 那么 SignalR 2 创建一个实时聊天应用程序.将 SignalR 添加 MVC 5 应用程序中,并创建聊天视图发送并显示消息. 在Demo中,将学习Signal ...

随机推荐

  1. CentOS7部署.Net Core2.0站点(中)

    继续上篇的内容,本篇来学习下nginx的配置和守护进程supervisor的使用. 一.Nginx安装及配置 (1)安装nginx sudo yum install epel-release #添加源 ...

  2. Java并发编程:深入剖析ThreadLocal (总结)

    ThreadLocal好处 Java并发编程的艺术解释好处是:get和set方法的调用可以不用在同一个方法或者同一个类中. 问答形式总结: 1. ThreadLocal类的作用 ThreadLocal ...

  3. js权威指南学习笔记(四)对象

    1.创建对象 (1).通过对象直接量的方式创建 说明:对象直接量是由若干名/值对组成的映射表,名/值对中间用冒号分隔,名/值对之间用逗号分隔,整个映射表用花括号括起来. 如:       5 5   ...

  4. AngularJs动态添加元素和删除元素

    动态添加元素和删除元素 //通过$compile动态编译html var html="<div ng-click='test()'>我是后添加的</div>" ...

  5. QQ 聊天机器人小薇 2.0.0 发布!

    本次发布主要加入了支持讨论组聊天,并增强了稳定性.另外,官方小薇 QQ 机器人已经下线,大家要体验的话请 自建私服~ 简介 XiaoV(小薇)是一个用 Java 写的 QQ 聊天机器人 Web 服务, ...

  6. poj 1679 The Unique MST (判定最小生成树是否唯一)

    题目链接:http://poj.org/problem?id=1679 The Unique MST Time Limit: 1000MS   Memory Limit: 10000K Total S ...

  7. 如何使用idea把web项目打成war包

    如果是maven项目,打成war包很容易,如果是web项目,需要这样子 1. 2. 3. output directory是war包的目录 4.重新选择 第一步的操作,选择build即可.

  8. Dapper批量添加

    Public void Add() {  List<PPQuery> lists = GetDataByFile(tempFilePath); private static readonl ...

  9. Ubuntu14.04下如何安装Python爬虫框架Scrapy

    按照官方文档的说明,安装scrapy 需要以下程序或者库: (1).Python 2.7 (2).lxml. Most linux distributions ships PRepackaged ve ...

  10. centos中从源程序升级python方法

    http://www.cnblogs.com/sky20081816/p/3441920.html 1 .wget http://python.org/ftp/python/2.7.3/Python- ...