前言

交流群:195866844

目录:

用SignalR 2.0开发客服系统[系列1:实现群发通讯]

用SignalR 2.0开发客服系统[系列2:实现聊天室]

真的很感谢大家的支持,今天发表系列3,我们的正菜马上就要来了..

开发环境

开发工具:VS2013 旗舰版

数据库:未用

操作系统:WIN7旗舰版

正文开始

首先我们来看看实现的效果:

所用到的方法和类(重要):

其实细心的朋友应该早就发现了,在上篇博客我们就已经用到了这个方法:

  1. //调用指定连接对象的JS
  2. Clients.Client(连接对象的唯一标识).addMessage("");
  3.  
  4. //调用指定集合中所有连接对象的JS
  5. Clients.Clients(集合).addMessage("")

下面上代码:

首先实体类:

很简单,只有一个用户类

  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel.DataAnnotations;
  4. using System.Linq;
  5. using System.Web;
  6.  
  7. namespace SignalRTest
  8. {
  9. /// <summary>
  10. /// 用户类
  11. /// </summary>
  12. public class UserInfo
  13. {
  14. [Key]
  15. public string ContextID { get; set; }
  16. public string Name { get; set; }
  17.  
  18. }
  19.  
  20. }

Hub的源码(同样,注释很全,我就不单独的拿出来讲了):

  1. using Microsoft.AspNet.SignalR;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Web;
  6. using System.Threading.Tasks;
  7. using Microsoft.AspNet.SignalR.Hubs;
  8. using Newtonsoft.Json;
  9.  
  10. namespace SignalRTest
  11. {
  12. [HubName("ptopHub")]
  13. public class PTPHub : Hub
  14. {
  15. public static List<UserInfo> UserList = new List<UserInfo>();
  16. //public static List<RoomInfo> RoomList = new List<RoomInfo>();
  17.  
  18. /// <summary>
  19. /// 重写链接事件
  20. /// </summary>
  21. /// <returns></returns>
  22. public override Task OnConnected()
  23. {
  24. // 查询用户。
  25. var user = UserList.SingleOrDefault(u => u.ContextID == Context.ConnectionId);
  26.  
  27. //判断用户是否存在,否则添加进集合
  28. if (user == null)
  29. {
  30. user = new UserInfo()
  31. {
  32. Name = "",
  33. ContextID = Context.ConnectionId
  34. };
  35. UserList.Add(user);
  36.  
  37. }
  38.  
  39. return base.OnConnected();
  40. }
  41. /// <summary>
  42. /// 获取用户名和自己的唯一编码
  43. /// </summary>
  44. /// <param name="name"></param>
  45. public void GetName(string name)
  46. {
  47. // 查询用户。
  48. var user = UserList.SingleOrDefault(u => u.ContextID == Context.ConnectionId);
  49. if (user != null)
  50. {
  51. user.Name = name;
  52. Clients.Client(Context.ConnectionId).showID(Context.ConnectionId);
  53. }
  54.  
  55. GetUserList();
  56. }
  57. /// <summary>
  58. /// 重写断开的事件
  59. /// </summary>
  60. /// <returns></returns>
  61. public override Task OnDisconnected()
  62. {
  63. var user =UserList.Where(u => u.ContextID == Context.ConnectionId).FirstOrDefault();
  64.  
  65. //判断用户是否存在,存在则删除
  66. if (user != null)
  67. {
  68. //删除用户
  69. UserList.Remove(user);
  70.  
  71. }
  72. //更新所有用户的列表
  73. GetUserList();
  74. return base.OnDisconnected();
  75. }
  76.  
  77. /// <summary>
  78. /// 更新所有用户的在线列表
  79. /// </summary>
  80. private void GetUserList()
  81. {
  82.  
  83. var itme = from a in UserList
  84. select new { a.Name, a.ContextID };
  85. string jsondata = JsonConvert.SerializeObject(itme.ToList());
  86. Clients.All.getUserlist(jsondata);
  87.  
  88. }
  89. /// <summary>
  90. /// 发送消息
  91. /// </summary>
  92. /// <param name="contextID"></param>
  93. /// <param name="Message"></param>
  94. public void SendMessage(string contextID, string Message)
  95. {
  96. var user = UserList.Where(u => u.ContextID == contextID).FirstOrDefault();
  97.  
  98. //判断用户是否存在,存在则发送
  99. if (user != null)
  100. {
  101. //给指定用户发送,把自己的ID传过去
  102. Clients.Client(contextID).addMessage(Message + " " + DateTime.Now,Context.ConnectionId);
  103. //给自己发送,把用户的ID传给自己
  104. Clients.Client(Context.ConnectionId).addMessage(Message + " " + DateTime.Now, contextID);
  105. }
  106. else
  107. {
  108. Clients.Client(Context.ConnectionId).showMessage("该用户已离线");
  109. }
  110. }
  111.  
  112. }
  113. }

前端HTML+JS(上次有朋友吐槽JS没注释 - -,实在不好意思,呃..这次加上了..):

  1. <!DOCTYPE html>
  2. <html xmlns="http://www.w3.org/1999/xhtml">
  3. <head>
  4. <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
  5. <title>点对点聊天</title>
  6. <script src="Scripts/jquery-1.10.2.min.js"></script>
  7. <script src="Scripts/jquery.signalR-2.0.0.min.js"></script>
  8. <!--这里要注意,这是虚拟目录,也就是你在OWIN Startup中注册的地址-->
  9. <script src="signalr/hubs"></script>
  10. <script type="text/javascript">
  11. var Clients = [];
  12. $(function () {
  13. chat = $.connection.ptopHub;
  14. //注册提示信息方法
  15. chat.client.showMessage = function (Message) {
  16. alert(Message);
  17. }
  18. //注册显示信息的方法
  19. chat.client.addMessage = function (Message,contextID) {
  20. if ($.inArray(contextID,Clients) == -1) {
  21. AddRoom(contextID);
  22. }
  23. $("#" + contextID).find("ul").each(function () {
  24. $(this).append('<li>' + Message + '</li>')
  25. })
  26. }
  27. //注册查询房间列表的方法
  28. chat.client.getUserlist = function (data) {
  29. if (data) {
  30. var jsondata = $.parseJSON(data);
  31. $("#roomlist").html(" ");
  32. for (var i = 0; i < jsondata.length; i++) {
  33. var html = ' <li>用户名:' + jsondata[i].Name + '<button roomname="' + jsondata[i].ContextID + '" onclick="PtoPSendStart(this)">与他聊天</button></li>';
  34. $("#roomlist").append(html);
  35. }
  36. }
  37. }
  38. //注册显示个人信息的方法
  39. chat.client.showID = function (data) {
  40. $("#ConID").html(data);
  41. Clients.push(data);
  42. }
  43. // 获取用户名称。
  44. $('#username').html(prompt('请输入您的名称:', ''));
  45. //连接成功后获取自己的信息
  46. $.connection.hub.start().done(function () {
  47. chat.server.getName($('#username').html());
  48. });
  49.  
  50. });
  51. //开始聊天
  52. function PtoPSendStart(data) {
  53. var val = $(data).attr('roomname');
  54. AddRoom(val);
  55. }
  56. //显示聊天窗口
  57. function AddRoom(val) {
  58. Clients.push(val)
  59. var html = '<div style="float:left; margin-left:30px; border:double" id="' + val + '" roomname="' + val + '"><button onclick="RemoveRoom(this)">退出</button>\
  60. ' + val + '房间\
  61. 聊天记录如下:<ul>\
  62. </ul>\
  63. <input type="text" /> <button onclick="SendMessage(this)">发送</button>\
  64. </div>'
  65. $("#RoomList").append(html);
  66.  
  67. }
  68. //发送消息
  69. function SendMessage(data) {
  70. var message = $(data).prev().val();
  71. var room = $(data).parent();
  72. var username = $("#username").html();
  73. message = username + ":" + message;
  74. var roomname = $(room).attr("roomname");
  75. chat.server.sendMessage(roomname, message);
  76. }
  77.  
  78. </script>
  79. </head>
  80. <body>
  81. <div>
  82. <div>名称:<p id="username"></p></div>
  83. <div>用户唯一编码:<p id="ConID"></p></div>
  84. </div>
  85. <div style="float:left;border:double">
  86. <div>在线用户列表</div>
  87. <ul id="roomlist"></ul>
  88. </div>
  89. <div id="RoomList">
  90. </div>
  91. </body>
  92. </html>

至此就完成了基本的点对点聊天的功能,真心很感谢大家的支持,希望能对大家有帮助.

我的Q :524808775 加我请注明来源 - -,我们共同讨论.

我会坚持写完本系列..

用SignalR 2.0开发客服系统[系列3:实现点对点通讯]的更多相关文章

  1. 用SignalR 2.0开发客服系统[系列1:实现群发通讯]

    前言 交流群:195866844 先说一下我为什么会写这个博客吧,(首先说一下,我是一个小菜鸟,讲的不好请指导 - -,)  前段时间公司的项目涉及到在B/S上使用即时通讯,(其实就是做一个B/S的客 ...

  2. 用SignalR 2.0开发客服系统[系列4:负载均衡的情况下使用SignalR]

    前言 交流群:195866844 目录: 用SignalR 2.0开发客服系统[系列1:实现群发通讯] 用SignalR 2.0开发客服系统[系列2:实现聊天室] 用SignalR 2.0开发客服系统 ...

  3. 用SignalR 2.0开发客服系统[系列5:使用SignalR的中文简体语言包和其他技术点]

    前言 交流群:195866844 目录: 用SignalR 2.0开发客服系统[系列1:实现群发通讯] 用SignalR 2.0开发客服系统[系列2:实现聊天室] 用SignalR 2.0开发客服系统 ...

  4. 用SignalR 2.0开发客服系统[系列2:实现聊天室]

    前言 交流群:195866844 上周发表了 用SignalR 2.0开发客服系统[系列1:实现群发通讯] 这篇文章,得到了很多帮助和鼓励,小弟在此真心的感谢大家的支持.. 这周继续系列2,实现聊天室 ...

  5. php开发客服系统(持久连接+轮询+反向ajax 转载 http://www.tuicool.com/articles/2mU7v2R)

    php开发客服系统( 下载源码 ) 用户端(可直接给客户发送消息) 客服端(点击用户名.即可给该用户回复消息) 讲两种实现方式: 一:iframe + 服务器推技术comet(反向ajax,即服务器向 ...

  6. php开发客服系统(持久连接+轮询+反向ajax)

    欢迎在php严程序 - php教程学习AJAX教程, 本节课讲解:php开发客服系统(持久连接+轮询+反向ajax) php开发客服系统(下载源码) 用户端(可直接给客户发送消息)客服端(点击用户名. ...

  7. Linux + .net core 开发升讯威在线客服系统:同时支持 SQL Server 和 MySQL 的实现方法

    前段时间我发表了一系列文章,开始介绍基于 .net core 的在线客服系统开发过程. 有很多朋友一直提出希望能够支持 MySQL 数据库,考虑到已经有朋友在用 SQL Server,我在升级的过程中 ...

  8. Linux + .net core 开发升讯威在线客服系统:首个经过实际验证的高性能版本

    业余时间用 .net core 写了一个在线客服系统.并在博客园写了一个系列的文章,写介绍这个开发过程: .net core 和 WPF 开发升讯威在线客服系统:目录 https://blog.she ...

  9. .net core 和 WPF 开发升讯威在线客服系统:把 .Net Framework 打包进安装程序

    本系列文章详细介绍使用 .net core 和 WPF 开发 升讯威在线客服与营销系统 的过程. 系列文章目录: https://blog.shengxunwei.com/Home/Post/44a3 ...

随机推荐

  1. 通俗易懂的来讲讲DOM

    DOM是所有前端开发每天打交道的东西,但是随着jQuery等库的出现,大大简化了DOM操作,导致大家慢慢的“遗忘”了它的本来面貌.不过,要想深入学习前端知识,对DOM的了解是不可或缺的,所以本文力图系 ...

  2. bootstrap-fileinput 简单使用

    bootstrap-fileinput 是一款图片/文件上传 bootstrap 插件,简单示例代码: <!DOCTYPE html> <html> <head> ...

  3. MySQL 系列(四)主从复制、备份恢复方案生产环境实战

    第一篇:MySQL 系列(一) 生产标准线上环境安装配置案例及棘手问题解决 第二篇:MySQL 系列(二) 你不知道的数据库操作 第三篇:MySQL 系列(三)你不知道的 视图.触发器.存储过程.函数 ...

  4. 使用NUnit为游戏项目编写高质量单元测试的思考

    0x00 单元测试Pro & Con 最近尝试在我参与的游戏项目中引入TDD(测试驱动开发)的开发模式,因此单元测试便变得十分必要.这篇博客就来聊一聊这段时间的感悟和想法.由于游戏开发和传统软 ...

  5. 《LoadRunner12七天速成宝典》来了

    看到自己的新书又要发行了,算算从09年第一本书开始,不知不觉已经是第四本书了(帮朋友合写的书不算),每次写完之后都会说太累了,不想再写了,但是却又次次反悔,吞下食言的苦果.如果非要说第四本书的感受,那 ...

  6. 获取 dhcp IP 过程分析 - 每天5分钟玩转 OpenStack(91)

    前面我们已经讨论了 DHCP agent 的配置以及 namespace 如何隔离 dnsmasq 服务,本节将以 cirros-vm1 为例分析获取 DHCP IP 的详细过程. 在创建 insta ...

  7. 【SAP业务模式】之ICS(四):组织单元的配置

    SAP的ICS业务后台配置主要有以下几个配置点: 1.组织单元的配置(公司代码.销售组织.工厂.采购组织等): 2.主数据的部分: 3.订单和开票的定价过程: 4.开票输出类型: 5.公司间发票的配置 ...

  8. docker4dotnet #1 – 前世今生 & 世界你好

    作为一名.NET Developer,这几年看着docker的流行实在是有些眼馋.可惜的是,Docker是基于Linux环境的,眼瞧着那些 java, python, node.js, go 甚至连p ...

  9. JAVA代码验证身份证信息

    java验证身份证信息代码 转自:http://www.blogjava.net/xylz/archive/2011/01/05/342330.html import java.util.Calend ...

  10. 【Java并发编程实战】----- AQS(一):简介

    在前面博客中,LZ讲到了ReentrantLock.ReentrantReadWriteLock.Semaphore.CountDownLatch,他们都有各自获取锁的方法,同时相对于Java的内置锁 ...