C# SignalR 实时通讯 聊天室
来源:互联网 发布:无线传感器软件 编辑:程序博客网 时间:2024/06/10 21:22
一.SignalR简介
SignalR:当所连接的客户端变得可用时服务器代码可以立即向其推送内容,而不是让服务器等待客户端请求新的数据。实现实时服务器与客户端通信。是一个开源.NET 库生成需要实时用户交互或实时数据更新的 web 应用程序。
SignalR的出现,让页面通过javascript可以很简单的调用后端服务的方法,而在后端也可以很简单的直接调用javascript所实现的方法,前后端可以进行实时通信。实现了服务器主动推送(Push)消息到客户端页面,这样客户端就不必重新发送请求或使用轮询技术来获取消息。
注意:SignalR 会自动管理连接。客户端和服务器之间的连接是持久性的,不像传统的 HTTP 连接。
二.SignalR传输方式
SignalR会根据当前浏览器自动选择适当的传输方式。在最坏的情况下,SignalR会选择使用长轮询(Long Polling).
SignalR会依照下列顺序来判定使用那种传输方式:
- 1.如果浏览器是 Internet Explorer8 或更早版本,则使用长轮询。
- 2.如果配置了 JSONP(即连接启动时 jsonp 参数设置为 true),则使用长轮询。
- 3.如果要建立跨域连接(即 SignalR 终结点和宿主页不在相同的域中),并且满足以下条件,则会使用 WebSocket:
- 3.1客户端支持 CORS(跨域资源共享)
- 3.2客户端支持 WebSocket
- 3.3服务器支持 WebSocket
- 如果这些条件中的任何一条不满足,将使用长轮询.
- 4.如果未配置 JSONP 并且连接没有跨域,只要客户端和服务器都支持的话,将使用 WebSocket。
- 5.如果客户端或服务器不支持 WebSocket,则尽量使用服务器发送事件。Forever Frame。
- 7.如果 Forever Frame 失败,则使用长轮询。
长轮询(long polling)与传统Ajax的不同之处:
- 1.服务器端会阻塞请求直到有数据传递或超时才返回。
- 2.客户端 JavaScript 响应处理函数会在处理完服务器返回的信息后,再次发出请求,重新建立连接。
- 3.当客户端处理接收的数据、重新建立连接时,服务器端可能有新的数据到达;这些信息会被服务器端保存直到客户端重新建立连接,客户端会一次把当前服务器端所有的信息取回。
三.SignalR使用(个人理解)
下面是聊天室的主要代码:
C#代码:
using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Web.Mvc;//工具 -> 库程序包管理器 -> 程序包管理器控制台 输入下面命令 //install-package Microsoft.AspNet.SignalR -Version 1.1.4 using Microsoft.AspNet.SignalR;using System.Threading.Tasks;using Microsoft.AspNet.SignalR.Hubs;namespace SignalR.Controllers{ [HubName("ChatRoomHub")] public class ChatHub : Hub { static List<UserEntity> users = new List<UserEntity>(); /// <summary> /// 添加用户 /// </summary> /// <param name="nickName"></param> public void UserEnter(string nickName) { UserEntity userEntity = new UserEntity { NickName = nickName, ConnectionId = Context.ConnectionId }; users.Add(userEntity); Clients.All.NotifyUserEnter(nickName, users);//调用前台NotifyUserEnter方法 } /// <summary> /// 发送消息 /// </summary> /// <param name="nickName"></param> /// <param name="message"></param> public void SendMessage(string nickName, string message) { Clients.All.NotifySendMessage(nickName, message);//调用前台NotifySendMessage方法 } /// <summary> /// 断开(刷新页面可以触发此方法) /// </summary> /// <returns></returns> public override Task OnDisconnected() { var currentUser = users.FirstOrDefault(u => u.ConnectionId == Context.ConnectionId); if (currentUser != null) { users.Remove(currentUser); Clients.Others.NotifyUserLeft(currentUser.NickName, users);//调用前台NotifyUserLeft方法 } return base.OnDisconnected(); } } public class UserEntity { public string NickName { get; set; } public string ConnectionId { get; set; } } public class BaseController : Controller {
/// <summary> /// 聊天室 /// </summary> /// <returns></returns> public ActionResult BroadcastTest() { return View(); } }}
前台主要JavaScript代码:
<script type="text/javascript"> var userNickName;//昵称 var notification;//消息 jQuery(document).ready(function () { //没有用户名弹出输入框 while (!userNickName) { userNickName = window.prompt("请输入昵称!"); } var chatHub = $.connection.ChatRoomHub;//对应后台的类ChatHub //添加用户 chatHub.client.NotifyUserEnter = function (nickName, users) { buildUserTemplate(users); } //用户离开 chatHub.client.NotifyUserLeft = function (nickName, users) { buildUserTemplate(users); } //处理消息内容 chatHub.client.NotifySendMessage = function (nickName, message) { var userAvatar = 'http://forum.csdn.net/PointForum/ui/scripts/csdn/Plugin/001/face/29.gif'; //判断消息归属 if (nickName == userNickName) { $("#div_msg").append("<div style='text-align:right;'>" + "<div float:right> <span style='margin-right:10px'>" + nickName + "</span>" + "<img src='" + userAvatar + "' style='height:30px;width:30px;position:relative'/>" + "<div class='demo clearfix fr'>" + "<span class='triangle'></span>" + "<div class='article' style='word'>" + message + "</div></div></div></div><div class='clear-float'/>"); } else { $("#div_msg").append("<div>" + "<img src='" + userAvatar + "' style='height:30px;width:30px;position:relative'/>" + "<span style='left:10px;position:relative'>" + nickName + "</span>" + "<div class='demo clearfix'>" + "<span class='triangle'></span>" + "<div class='article'>" + message + "</div></div></div>"); } //消息弹出框 if (Notification.permission == "granted") { notification = new Notification(nickName, { body: message, icon: userAvatar, renotify: true, tag: 1, noscreen: true }); notification.onclick = function () { notification.close(); }; } else if (Notification.permission != "denied") { Notification.requestPermission(function (permission) { notification = new Notification(nickName, { body: message, icon: userAvatar, renotify: true, tag: 1, noscreen: true }); notification.onclick = function () { notification.close(); }; }); } var objDiv = document.getElementById("div_msgbody"); objDiv.scrollTop = objDiv.scrollHeight; } $.connection.hub.start().done(function () { chatHub.server.userEnter(userNickName); }); //聊天框发送消息 $("#message").keydown(function (event) { if (event.keyCode == 13) { if ($("#message").val() != "") { chatHub.server.sendMessage(userNickName, $("#message").val()); $("#message").val(""); } } }); //发送按钮 $("#btn_Send").click(function () { if ($("#message").val() != "") { chatHub.server.sendMessage(userNickName, $("#message").val()); $("#message").val(""); } }); //用户列表 function buildUserTemplate(users) { $("#lab_total").text(users.length); var userTemplate = "<ul style='list-style:none;'>" $.each(users, function (e, v) { var userAvatar = 'http://forum.csdn.net/PointForum/ui/scripts/csdn/Plugin/001/face/29.gif'; userTemplate += "<li style='padding-top:5px;'>" + "<img class='round-img-list' src='" + userAvatar + "'/>" + "<label style='color:#666666;margin-left:10px'>" + v.NickName + "</label>" + "</li>"; }); userTemplate += "</ul>"; $("#div_member").html(userTemplate); } }); </script>
完整SignalR的源码(包括聊天室,进度条)(我用的vs2013):
百度网盘:链接: https://pan.baidu.com/s/1gf7s5oB 密码: mdi2
最后:
1、Clients.All.NotifySendMessage(nickName, message);调用的是前台JschatHub.client.NotifySendMessage = function (nickName, message) {}这段代码。
2、javascript中,注意使用client和server关键字来调用前端方法和后端方法。
聊天室例子:
下面是进度条例子:
广播例子:
相关文章:http://www.cnblogs.com/frozenzhang/p/5406773.html
- C# SignalR 实时通讯 聊天室
- ASP.NET SignalR 2.0 SignalR的高频实时通讯
- SignalR 2.0 系列:SignalR的高频实时通讯
- 第五章SignalR的实时高频通讯
- ASP.NET MVC4使用SignalR实现实时通讯
- SignalR 2简单聊天室
- Nodejs实时通讯 在线聊天室(Socket.io)_收藏
- asp.net signalR 专题—— 第一篇 你需要好好掌握的实时通讯利器
- asp.net signalR 专题—— 第一篇 你需要好好掌握的实时通讯利器
- c#实现实时通讯的方式
- 使用Service Bus + SignalR 实现聊天室
- Asp.net MVC4 + signalR 聊天室实现
- SignalR——聊天室的实现
- 【SignalR学习系列】3. SignalR实时高刷新率程序
- 【SignalR学习系列】3. SignalR实时高刷新率程序
- websocket 聊天室(及时通讯)
- 使用 SignalR 实现实时的提醒
- WPF+SignalR实现用户列表实时刷新
- [日推荐]『表情集市』斗图必备
- 1.4算法研究-全排列
- SPOJ-COT-Count on a tree
- Dubbo配置以及使用总结
- java中使用异或的方式对文件进行加密解密
- C# SignalR 实时通讯 聊天室
- [转]ExtJS学习------Ext.window属性详解
- 简单的频道管理(第一步)
- DirectX9学习(一)
- 使用spring jdbc查询对象
- 写给立志做码农的大学生
- Spring实战之二:装配Bean
- Java NIO系列教程(七) FileChannel
- linux 管道、消息队列、共享内存的对比