前面两篇文章使用了Ajax long polling和WebSocket两种常用的Web实时通信方式构建了简单的聊天程序。

但是,由于浏览器的兼容问题,不是所有的环境都可以使用WebSocket这种比较好的方式。也就是说,根据浏览器或者环境的不同,客户端和服务端可能需要使用不同的通信方式。

Socket.IO简介

为了解决上面的问题,Socket.IO就出现了。

Socket.IO是一个基于Nodejs的,用于实时通信的一个软件包(包括client端和server端),Socket.IO完全由JavaScript实现。

Socket.IO设计的目标是支持任何的浏览器,任何设备。在接口方面,Socket.IO统一了通信的API,在内部实现上支持WebSocket,AJAX long-polling, AJAX multipart streaming, Forever Iframe等方式。也就是说,Socket.IO会根据环境来选择适合的通信方式。

在Socket.IO中,还有namespace和room的概念,可以方便的对socket进行分组,方便的实现一些例如聊天室的应用。

关于更多Socket.IO相关的内容,请参考该链接

好吧,又是聊天程序,这次是Socket.IO版本。

实现

在实现方面,客户端直接使用Socket.IO 的client,服务器端使用Nodejs。

客户端

客户端首先创建一个socket对象,这个socket对象会监听"new_message"和"user_status"事件。

var socket;

function initSocket(){
socket = io("http://" + location.host); socket.emit("add_client", $("#clientNameSpan").text()); socket.on("new_message", function(data){
console.log(data);
data = eval("(" + data + ")");
if (data.sender == $("#clientNameSpan").text()){
$("#inbox").append("<div class='chatItemS'><span class='msg mSend'><span class='sender'>"+data.sender+": </span>"+data.msg+"</span></div>");
}
else {
$("#inbox").append("<div class='chatItemR'><span class='msg mRecv'><span class='sender'>"+data.sender+": </span>"+data.msg+"</span></div>");
}
$("#inbox").scrollTop($("#inbox")[0].scrollHeight);
}); socket.on("user_status", function(data){
$("#clientCount").text("Online User: "+data.length);
$("#clients").children().remove();
for(var i = 0; i<data.length; i++){
$("#clients").append("<span id='client'>"+data[i]["clientName"]+"</span>")
}
})
}

服务端

对于服务端,首先是一些静态文件、页面的处理。

// get the static files
app.get("/", function(req, res){
res.sendFile(__dirname + "/index.html");
}); app.get("/static/jquery-1.11.3.js", function(req, res){
res.sendFile(__dirname + "/static/jquery-1.11.3.js");
}); app.get("/static/json2.js", function(req, res){
res.sendFile(__dirname + "/static/json2.js");
}); app.get("/static/style.css", function(req, res){
res.sendFile(__dirname + "/static/style.css");
});

另外,服务端主要的功能就是接收消息,然后广播消息。

服务端会根据socket id和用户名记录所有的用户,并存放在一个数组中。每当有用户加入或者用户退出,服务端就通过"user_status"事件将用户数组发送给客户端,这样客户端就能展示当前在先用户数。

// save all the client {"sid": socket.id, "clientName": client}
var clients = [] io.on("connection", function(socket){ socket.on("add_client", function(client){
console.log(client+" jion the chat"); var clientObj = {};
clientObj["sid"] = socket.id;
clientObj["clientName"] = client; clients.push(clientObj);
io.emit("user_status", clients)
}); socket.on("new_message", function(msg){
console.log("Server got message: "+msg);
console.log("Send message using: "+socket.conn.transport.name);
io.emit("new_message", msg);
}); socket.on("disconnect", function(){
for(var i = 0; i<clients.length; i++){
if(clients[i]["sid"] == socket.id){
console.log(clients[i]["clientName"]+" leave the chat");
clients.splice(i, 1);
break;
}
}
io.emit("user_status", clients);
}); });

运行效果

首先是一个login页面,在服务端会将用户名跟socket id绑定,用来进行简单的用户统计。

Console端打印了服务器收到的消息,以及用户的join/leave情况。

当用户状态改变后,页面会收到"user_status"事件,然后更新用户状态栏。

Socket.IO兼容性测试

前面提到了Socket.IO的优势就是统一了接口,对用户屏蔽了底层,同时能够支持不同的设备,选择最优的通信方式。

下面就对Socket.IO的兼容性进行一些简单的测试,主要看看IE7-10。

首先,注意服务端的下面一段代码,用于显示当前传递消息的通信方式:

console.log("Send message using: "+socket.conn.transport.name);

IE10

我本机安装的是IE10,通过服务端console可以看到,在IE10中Socket.IO会选择"WebSocket"为最终通信方式。

IE9/IE8

打开IE,通过F12进入下面页面,然后设置为IE9。

通过测试可以看到,Socket.IO在IE9中可以正常工作,由于IE9不支持“WebSocket”,所以Socket.IO最终选择了"Polling"为最终通信方式。

通过上面的设置切换到IE8模式,由于IE8不支持“WebSocket”,所以Socket.IO就会将通信方式切换到了“Polling”。

IE7

通过同样的步骤测试,Socket.IO在IE7中使用polling方式正常工作。

IE7中唯一遇到的问题是“JSON.stringify”方法不支持,所以通过下面方式对IE7进行了hack:

<!--[if IE 7]>
<script src="/static/json2.js"></script>
<![endif]-->

总结

从例子中可以看到,使用了Socket.IO后,我们只需要了解Socket.IO提供的API,而不需要关心使用哪种通信方式,使用起来简单、方便。

文中对Socket.IO在IE上的兼容性做了一些简单的测试,结果还是很满意的,对于不支持WebSocket的环境,Socket.IO自动切换到了polling方式,用户不用去关心环境的差异了。

Socket.IO作为一个跨环境,多种连接方式自动切换的工具,进一步简化了Web实时通信方面应用的开发。

Ps:通过此处可以下载例子的源码。

from:http://www.cnblogs.com/wilber2013/p/4814838.html

备注:看了好多例子,对我来说只有这个才是真正的兼容

【转】Web实时通信之Socket.IO ,真正的兼容ie的更多相关文章

  1. Web实时通信之Socket.IO

    前面两篇文章使用了Ajax long polling和WebSocket两种常用的Web实时通信方式构建了简单的聊天程序. 但是,由于浏览器的兼容问题,不是所有的环境都可以使用WebSocket这种比 ...

  2. Socket.IO 概述

    为了防止无良网站的爬虫抓取文章,特此标识,转载请注明文章出处.LaplaceDemon/SJQ. http://www.cnblogs.com/shijiaqi1066/p/3826251.html ...

  3. 基于 socket.io, 简单实现多平台类似你猜我画 socket 数据传输

    一.前言 socket.io 实现了实时双向的基于事件的通讯机制,是基于 webSocket 的封装,但它不仅仅包括 webSocket,还对轮询(Polling)机制以及其它的实时通信方式封装成了通 ...

  4. koa+mysql+vue+socket.io全栈开发之web api篇

    目标是建立一个 web QQ的项目,使用的技术栈如下: 后端是基于koa2 的 web api 服务层,提供curd操作的http接口,登录验证使用的是 json web token,跨域方案使用的是 ...

  5. 基于Node.js+socket.IO创建的Web聊天室

    这段时间进了一个新的项目组,项目是用Appcan来做一个跨平台的移动运维系统,其中前台和后台之间本来是打算用WebSocket来实现的,但写好了示例后发现android不支持WebSocket,大为受 ...

  6. node socket.io web

    soket.io & web http://socket.io/get-started/chat/ 新建一個文件夾 soketWeb ; 在sokertWeb 文件夾內新建一個 package ...

  7. 使用Node.js的socket.io模块开发实时web程序

    首发:个人博客,更新&纠错&回复 今天的思维漫游如下:从.net的windows程序开发,摸到nodejs的桌面程序开发,又熟悉了一下nodejs,对“异步”的理解有了上上周对操作系统 ...

  8. HTML5 Web socket和socket.io

    what is websockets Two-way communication over ont TCP socket, a type of PUSH technology HTML5的新特性,用于 ...

  9. Socket.IO介绍:支持WebSocket、用于WEB端的即时通讯的框架

    一.基本介绍 WebSocket是HTML5的一种新通信协议,它实现了浏览器与服务器之间的双向通讯.而Socket.IO是一个完全由JavaScript实现.基于Node.js.支持WebSocket ...

随机推荐

  1. go语言web开发框架_Iris框架讲解(五):MVC包使用

    在Iris框架中,封装了mvc包作为对mvc架构的支持,方便开发者遵循mvc的开发原则进行开发. iris框架支持请求数据.模型.持久数据分层处理,并支持各层级模块代码绑定执行. MVC即:model ...

  2. GoWeb开发_Iris框架讲解(四):Iris框架设置操作

    路由组的使用 在实际开发中,我们通常都是按照模块进行开发,同一模块的不同接口url往往是最后的一级url不同,具有相同的前缀url.因此,我们期望在后台开发中,可以按照模块来进行处理我们的请求,对于这 ...

  3. 51nod1489(dfs)

    题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1489 题意:中文题诶- 思路:dfs 首先我们要通过攻击第1 ...

  4. 洛谷P3533 [POI2012]RAN-Rendezvous

    P3533 [POI2012]RAN-Rendezvous 题目描述 Byteasar is a ranger who works in the Arrow Cave - a famous rende ...

  5. 自定义标签报 无法为TAG [my2:hello]加载标记处理程序类[null]

    今天练习jsp自定义标签的时候,等我写好全部和检查万无一失的时候.执行然后报错了 无法为TAG [my2:hello]加载标记处理程序类[null] 我反复检查代码,发现代码也没什么问题.后面通过百度 ...

  6. Java快速向数据库中插入大量数据 比如10万条以上

    String sql = "insert into table *****"; //必须要有这句,要不然效果不明显 con.setAutoCommit(false); ps = c ...

  7. > Task :app:transformDexArchiveWithExternalLibsDexMergerForDebug FAILED

    > Task :app:transformDexArchiveWithExternalLibsDexMergerForDebug FAILED D8: Cannot fit requested ...

  8. EIGRP-6-EIGRP数据包

    EIGRP在与邻居路由器进行通信时,使用以下7种不同类型的数据包:   Hello包 确认包 更新包 查询包 响应包 SIA查询包 SIA响应包   更新包,查询包,响应包,SIA查询包和SIA响应包 ...

  9. Python 列表list 和 字符串str 互转

    一.列表list转字符串str 命令(python2.x):''.join(list) 命令(python2.x):''.join(str(s) for s in list) 其中,引号中是字符之间的 ...

  10. 20-----定位 (Position)

    定位 定位有三种: 1.相对定位 2.绝对定位 3.固定定位 这三种定位,每一种都暗藏玄机,所以我们要一一单讲. 相对定位 相对定位:相对于自己原来的位置定位 现象和使用: 1.如果对当前元素仅仅设置 ...