SignalR实现服务器与客户端的实时通信
初学SignalR使用总结-基于浏览器的在线聊天功能开发
最近闲来没事研究了一下在线聊天技术,发现微软一个比较好的东西(SignalR),该东西实现的效果感觉很了不起,可以通过程序去控制世界各个角落访问你网站的使用者浏览你的web页面,打破了浏览器的请求响应模式。
SignalR最典型的例子就是实现基于浏览器的在线聊天功能,SignalR是微软的东西,目前需要.net framework 4.5以上版本,本人使用vs2012基本满足,浏览器方面已经支持IE8及以上版本下面上代码:
首先让你的项目支持SignalR,打开vs2012工具菜单,选择库程序包管理器下面的管理net解决方案的nuget包菜单,联机搜索SignalR安装即可。
本人使用的.net MVC3版本。
安装完成后新建一个ChatHub类,SignalR关键类,代码如下:
using Microsoft.AspNet.SignalR;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Web;
namespace Kzrcw2014.MyClasses
{
public class SignalRHub:Hub
{
//声明静态变量存储当前在线用户
public static class UserHandler
{
public static Dictionary<string, string> ConnectedIds = new Dictionary<string, string>();
}
//用户进入页面时执行的(连接操作)
public void userConnected(string name)
{
//进行编码,防止XSS攻击
name = HttpUtility.HtmlEncode(name);
string message = "用户 " + name + " 登录";
//发送信息给其他人
Clients.Others.addList(Context.ConnectionId, name);
Clients.Others.hello(message);
//发送信息给自己,并显示上线清单
Clients.Caller.getList(UserHandler.ConnectedIds.Select(p => new { id = p.Key, name = p.Value }).ToList());
//新增目前使用者上线清单
UserHandler.ConnectedIds.Add(Context.ConnectionId, name);
}
//发送信息给所有人
public void sendAllMessage(string message)
{
message = HttpUtility.HtmlEncode(message);
var name = UserHandler.ConnectedIds.Where(p => p.Key == Context.ConnectionId).FirstOrDefault().Value;
message = name + "说:" + message;
Clients.All.sendAllMessge(message);
}
//发送信息给特定人
public void sendMessage(string ToId, string message)
{
message = HttpUtility.HtmlEncode(message);
var fromName = UserHandler.ConnectedIds.Where(p => p.Key == Context.ConnectionId).FirstOrDefault().Value;
message = fromName + " <span style='color:red'>悄悄对你说</span>:" + message;
Clients.Client(ToId).sendMessage(message);
}
//当使用者断线时执行
public override Task OnDisconnected()
{
//当使用者离开时,移除在清单内的ConnectionId
Clients.All.removeList(Context.ConnectionId);
UserHandler.ConnectedIds.Remove(Context.ConnectionId);
return base.OnDisconnected();
}
}
}
页面代码如下:
var userID = "";
$(function () {
//回车查询
var $inp = $('input:text');
$inp.bind('keydown', function (e) {
var key = e.which;
if (key == 13) {
$('#send').click();
}
});
userID = $("#UserName").val();
//建立與Server端的Hub的物件,注意Hub的開頭字母一定要為小寫
var chat = $.connection.chatHub;
//取得所有上線清單
chat.client.getList = function (userList) {
var li = "";
$.each(userList, function (index, data) {
li += "<li id='" + data.id + "'>" + data.name + "</li>";
});
$("#list").html(li);
}
//新增一筆上線人員
chat.client.addList = function (id, name) {
var li = "<li id='" + id + "'>" + name + "</li>";
$("#list").append(li);
}
//移除一筆上線人員
chat.client.removeList = function (id) {
$("#" + id).remove();
}
//全體聊天
chat.client.sendAllMessge = function (message) {
$("#messageList").append("<li>" + message + "</li>");
}
//密語聊天
chat.client.sendMessage = function (message) {
$("#messageList").append("<li>" + message + "</li>");
}
chat.client.hello = function (message) {
$("#messageList").append("<li>" + message + "</li");
}
//將連線打開
$.connection.hub.start().done(function () {
//當連線完成後,呼叫Server端的userConnected方法,並傳送使用者姓名給Server
chat.server.userConnected(userID);
});;
$("#send").click(function () {
var to = $("#box").val();
//當to為all代表全體聊天,否則為私密聊天
if (to == "all") {
chat.server.sendAllMessage($("#message").val());
} else {
chat.server.sendMessage(to, $("#message").val());
}
$("#message").val('');
});
$("#list li").live("click", function () {
var $this = $(this);
var id = $this.attr("id");
var text = $this.text();
//防止重複加入密語清單
if ($("#box").has("." + id).length > 0)
return false;
var option = "<option></option>"
$("#box").append(option).find("option:last").val(id).text(text).attr({ "selected": "selected" }).addClass(id);
});
});
</script>
<fieldset style="display:none">
<legend>系统使用交流及问题在线提交</legend>
<div id="messageBox">
<ul id="messageList"></ul>
</div>
<div id="chatList">
<p>当前在线</p>
<ul id="list">
</ul>
</div>
<div id="bar">
<div style="margin-top: 6px; float: left;">
<select id="box">
<option value="all">所有人</option>
</select>
</div>
<div style="margin: 5px; float: left;">
<input id="message" type="text" value="" />
</div>
<div style="margin: 5px; float: left;">
<input type="button" id="send" value="发 送" class="btn btn-success" />
</div>
</div>
<input type="hidden" id="UserName" value="@ViewBag.UserId"/>
</fieldset>
源码下载地址:http://www.kwstu.com/ResourcesView/SignalR_2014310111024681