今天看了下websocket的知识,了解到这是html5新增的特性,主要用于实时web的通信。之前客户端获取服务端的数据,是通过客户端发出请求,服务端进行响应的模式,或者通过ajax每隔一段时间从后台发出请求,然后更新页面的信息,这种轮询的方式使得用户感觉页面是“实时响应”的,这样做虽然简单但未免有些暴力,另外每次请求都会有TCP三次握手并且附带了http头信息,服务器表示压力很大,这就造成了性能上和延迟的问题。

        后来的技术方案中又出现了长轮询、Comet、浏览器插件(flash)和Java等来实现服务器往客户端推送消息,但都有一些弊端。

        WebSocket的出现,意味着另一种解决方案,其提供了基于TCP的双向的、全双工(发送数据的同时也能够接受数据,两者同步进行)的socket连接。使用websocket,一旦服务端和客户端之间完成握手,信息就可以随意往来两端,而不用附件那些无用的http头信息,降低了带宽的占用,提高了性能,降低了延时。但其缺陷是浏览器的支持不够,比如IE,到了IE10才支持。

        现在就通过一个简单的例子来讲讲其运用过程,先上下效果图:

         项目的环境:.NET 4.5 +MVC 4 +JQuery+HTML5+VS2013+IE11     

核心的实现过程,分以下几步:

1、websocket的创建、发送消息、接受消息、关闭

2、服务端的响应

        下面针对上面的步骤,具体讲解下:

1、websocket的创建、发送消息、接受消息、关闭

websocket里包含的几个重要事件如下图: onopen onmessage onerror onclose;

           websocket的创建: 这时连接会发送到服务端后台代码,进行客户端和服务端的握手,如果握手成功,则会触发onopen事件,表示连接建立;如果连接失败,就会执行onerror事件,随后执行onclose事件。当客户端获取到服务端推送的消息后,就会执行onmessage事件。

    try{
if ("WebSocket" in window) { //判断浏览器是否支持WebSocket
socket = new WebSocket("ws://localhost:13458/Socket/SocketHandler.ashx"); //socket连接服务端地址
}
}
catch(ex)
{
log("您的浏览器不支持WebSocket,请切换到更高版本 或用chrome firefox");
return;
} //相应的socket事件
//socket建立连接
socket.onopen = function () {
//连接成功,将消息广播出去
isSocketConnect = true;
$("#btnWs").val("断开");
sendSocketMessage(Event,"进入聊天室");
}
//socket得到服务端广播的消息
socket.onmessage = function (event) {
Log(event.data);
}
//socket连接关闭
socket.onclose = function () {
Log("socket closed!");
}
//socket连接出现错误
socket.onerror = function (event) {
Log("socket connect error");
}

           

          当然客户端也可以往服务端发送消息,发送事件便是socket.send(data);data代表发送给服务端的数据:具体代码如下

if (socket.readyState == WebSocket.OPEN) {
if ($("#txtMsg").val() == "") {
if (!msg) {
return; //空文本不发送消息
}
}
//如果未输入用户名,根据当前时间生成游客昵称
if ($("#userName").val() == "") {
var d = new Date();
$("#userName").val("游客" + d.getMinutes() + "_" + d.getSeconds() + "_" + d.getMilliseconds());
}
if (!msg) {
msg = "" + $("#userName").val() + ":" + "<div class='divChat'>" + $("#txtMsg").val() + "</div>";
}
else {
msg = "" + $("#userName").val() + " " + msg;
}
socket.send(msg);
$("#txtMsg").val(""); //清空已输入的数据
$("#txtMsg").focus();
}

        2、服务端的响应

        这里我们添加一般处理程序来进行响应和推送客户端消息,其中有一点要处理的是 我们要实现即时多人聊天,就要把客户端发过来的消息广播到其他客户端,这里实现原理也很简单,就是把所有的连接用list存起来,然后遍历list集合,将消息发送给各个客户端。具体实现代码如下:

    public class SocketHandler : IHttpHandler
{
//用来存储当前所有连接的客户单
public static List<WebSocket> WebSocketList;
public void ProcessRequest(HttpContext context)
{
if (WebSocketList == null)
{
WebSocketList = new List<WebSocket>();
}
HttpContext.Current.AcceptWebSocketRequest(async (contexts) =>
{
WebSocket socket = contexts.WebSocket;
while (true)
{
ArraySegment<byte> buffer = new ArraySegment<byte>(new byte[1024]);
CancellationToken token;
WebSocketReceiveResult result = await socket.ReceiveAsync(buffer, token);
//获取客户端发过来的消息
string clientMessage = Encoding.UTF8.GetString(buffer.Array, 0, result.Count); if (socket.State == WebSocketState.Open)
{
//重新组织消息,发送给客户端
clientMessage = DateTime.Now.ToString() + " " + clientMessage;
buffer = new ArraySegment<byte>(Encoding.UTF8.GetBytes(clientMessage));
//如果该客户端为初次加入,添加到用户列表;
if (!WebSocketList.Contains(socket))
{
WebSocketList.Add(socket);
}
//将消息进行广播
foreach (WebSocket item in WebSocketList)
{
await item.SendAsync(buffer, WebSocketMessageType.Text, true, CancellationToken.None);
}
}
if (socket.State == WebSocketState.CloseReceived)
{
//客户断开的时候,要从列表中移除
WebSocketList.Remove(socket);
}
}
});
}

         参考资料:使用 HTML5 WebSocket 构建实时 Web 应用

         源码下载

         ps:离职了,找工作中……广州/深圳  围观简历

         喜欢就动动手指支持下!您的支持是我最大动力!

html5+js+.Net的即时多人聊天的更多相关文章

  1. 使用node.js实现多人聊天室(socket.io、B/S)

    通过B/S架构实现多人聊天,客户端连接服务器,发送信息,服务器接收信息之后返回给客户端. 主要是通过socket.io实现浏览器和服务器之间进行实时,双向和基于事件的通信. socket.io官方文档 ...

  2. 使用 HTML5 webSocket API实现即时通讯的功能

    project下载地址:http://download.csdn.net/detail/wangshuxuncom/6430191 说明: 本project用于展示怎样使用 HTML5 webSock ...

  3. SignalR 实现Web多人聊天室

      ASP .NET SignalR 是一个ASP .NET 下的类库,可以在ASP .NET 的Web项目中实现实时通信.什么是实时通信的Web呢?就是让客户端(Web页面)和服务器端可以互相通知消 ...

  4. Html5+js测试题(开发版)

    ------------------------------------------------ 1. 谈谈你对js闭包的理解: 使用闭包主要是为了设计私有的方法和变量.闭包的优点是可以避免全局变量的 ...

  5. Html5+js测试题【完整版】

    一.闭包的理解:使用闭包主要是为了设计私有的方法和变量.闭包的优点是可以避免全局变量的污染,缺点是闭包会常驻内存,会增大内存使用量,使用不当很容易造成内存泄露.闭包三个特性: 1.函数嵌套函数 ; 2 ...

  6. android asmack 注册 登陆 聊天 多人聊天室 文件传输

    XMPP协议简介 XMPP协议(Extensible Messaging and PresenceProtocol,可扩展消息处理现场协议)是一种基于XML的协议,目的是为了解决及时通信标准而提出来的 ...

  7. Spring整合DWR comet 实现无刷新 多人聊天室

    用dwr的comet(推)来实现简单的无刷新多人聊天室,comet是长连接的一种.通常我们要实现无刷新,一般会使用到Ajax.Ajax 应用程序可以使用两种基本的方法解决这一问题:一种方法是浏览器每隔 ...

  8. 只要三步,使用html5+js实现像素风头像生成器

    只要三步,使用html5+js实现像素风头像生成器 html5的画布给我们带来了很大的空间,其实像素风格头像生成器只是用到了画方块的方法.画一个像素头像,只要三步,1.解决像素点,2.解决像素点之间的 ...

  9. [Web][高中同学毕业分布去向网站+服务器上挂载]二、敲定思路与方向(HTML5+JS(JQuery+ECharts))

    高中同学毕业分布网站:敲定思路 一.背景 第一集:http://www.cnblogs.com/Twobox/p/8368121.html 中大体确定了自己的 大体目标.大体思路. 但是 . 在今天的 ...

随机推荐

  1. Mysql索引会失效的几种情况分析(转)

    出处:http://www.jb51.net/article/50649.htm 索引并不是时时都会生效的,比如以下几种情况,将导致索引失效: 1.如果条件中有or,即使其中有条件带索引也不会使用(这 ...

  2. dns记录类型(转)

    NS:(Domain Name System,域名系统),因特网上作为域名和IP地址相互映射的一个分布式数据库,能够使用户更方便的访问互联网,而不用去记住能够被机器直接读取的IP数串.通过主机名,最终 ...

  3. Give $20/month and provide 480 hours of free education

    Hi , Hope all is well. Summer is right around the corner, and the Khan Academy team is excited to sp ...

  4. [label][WorldPress] 一个很方便查找定位WorldPress源代码位置的网址

    作为 WordPress 的新手,根本不熟悉那些函数究竟是什么作用的,所以就必须要去看源代码. 要去查看源代码,那么你就必须要熟悉 WordPress 下面文件的作用,以及那个文件中定义了有哪些函数? ...

  5. Postgres-XL9.5r1.6 搭建

    Postgres-XL9.5r1.6 安装部署1,环境准备 关闭防护墙 关闭selinux 下载依赖 yum install -y flex bison readline-devel zlib-dev ...

  6. linux bash变量替换(# ## % %% / //)

    VAR=hahaha echo ${VAR#*h} # ahaha 从前向后匹配删除 VAR=hahaha echo ${VAR##*h} # a 贪婪模式,从前向后匹配删除所有 VAR=hahaha ...

  7. /usr/bin/curl: Argument list too long的解决方法

    使用curl发送http请求时,会出现-bash: /usr/bin/curl: Argument list too long的错误,此时,可用采用httpie代替curl发送请求: pip inst ...

  8. WinForm 窗体应用程序(初步)之三

    进程: 进程,简单的说,就是让你的程序启动另一个程序. 1.Process.Start("calc");//启动计算器 弊端:只认识系统自带的程序,如果写错系统会崩溃. 2. // ...

  9. ubuntu emacs的安装

    在终端依次输入这三条命令即可 sudo add-apt-repository ppa:ubuntu-elisp/ppa sudo apt-get update sudo apt-get install ...

  10. 解决 UnicodeEncodeError: 'ascii' codec can't encode characters in position 问题

    在开头加上 import sys reload(sys) sys.setdefaultencoding( "utf-8" ) Python自然调用ascii编码解码程序去处理字符流 ...