webSocket 是 html5 规范新引入的功能, 用于解决浏览器与后台服务器双向通讯的问题, 使用 WebSocket 技术, 后台可以随时向前端推送消息, 以保证前后台状态统一, 在传统的无状态 HTTP 协议中, 这是 "无法做到" 的.
传统服务端推 (server push) 技术
WebSocket 提出之前, 为了解决后台推送消息到前台的需求, 提出了一些解决方案, 这些方案使用已有的技术 (如 ajax,iframe,flashplayer,java applet ...), 通过一些变通的处理来实现.
简单轮询
最简单的是前台轮询, 每隔一段时间去请求后台, 以获取最新状态, 这种方式最容易实现, 但效果也最差, 频繁盲目的调用后台, 带来不必要的开销, 且实时性无法保障, 后台出现更新, 前端需要在下一次轮询时才知道.
长轮询
为了解决这些弊端, 进化出长轮询技术, 轮询请求会在后台阻塞, 相当于保持一个长连接, 直到后台出现更新或者超时才返回, 这样就可以保证更新的及时性, 前端得到请求后, 重新建立轮询连接, 等待后台的更新通知.
其他方案
其他解决方案无外乎保持一个长连接 (如 Iframe 及 htmlfile 流), 实时的从后台获取信息, 或者借助第三方插件 (flashPlayer, jre), 使用的是 flash xmlsocket 或者 java applet socket 技术, 这些方式都不够纯 html, 所以这里就不过多介绍了, 更多传统 server push 技术可参考 IBM 的文章: 链接地址
WebSocket 介绍
webSocket 是 html5 新引入的技术, 允许后台随时向前端发送文本或者二进制消息, WebSocket 是一种全新的协议, 不属于 http 无状态协议, 协议名为 "ws", 这意味着一个 websocket 连接地址会是这样的写法: ws://twaver.com:8080/webSocketServer.ws 不是 http, 所以传统的 web 服务器不一定支持, 需要服务器与浏览器同时支持, WebSocket 才能正常运行, 目前的支持还不普遍, 需要特别的 web 服务器和现代的浏览器.
浏览器对 WebSocket 的支持
Google Chrome 浏览器最先支持 WebSocket, 随后是 Safari,Firefox, 此外最新版本的 Opera 和 IE(Opera11,IE10) 也支持 WebSocket.
下面是主要浏览器的支持情况, Opera11 中默认关闭了 WebSocket 支持, 所以这里没有列出, 更多信息可参考: 链接地址与 链接地址
客户端 WebSocket 的主要方法
浏览器支持程度各有区别, 前面 wiki 中关于 WebSocket 的 "Browser support" 章节有介绍, 遵循 w3c 关于 WebSocket API 的相关规范, 浏览器提供了 WebSocket 类型, 在 Firefox 中为 MozWebSocket, 检测浏览器是否支持 WebSocket 可以使用下面的脚本代码:
检测浏览器是否支持 WebSocket
- window.WebSocket = window.WebSocket || window.MozWebSocket;
- if (!window.WebSocket){
- alert( "WebSocket not supported by this browser" );
- return ;
- }
构造函数 - WebSocket#constructor(url, optional protocols)
第一个参数是请求地址, 第二个参数选填, 表示协议名
使用示例:
var websocket = new WebSocket( "ws://127.0.0.1:8080/alarm/alarmServer" );
事件 - open/message/close/error
WebSocket#onopen, onmessage, onclose, onerror
连接打开时, 回调 onopen 方法, 接收到后台消息时会触发到 onmessage 事件, 后台关闭时调用 onclose, 出现连接异常时可在 onerror 中捕获
使用示例:
- websocket.onmessage = function (evt){
- var data = evt.data;
- }
方法 - send/close
发送消息 - WebSocket#send(data)
关闭连接 - WebSocket#close(optional code, optional reason)
使用示例:
websocket.send(JSON.stringify({action: "node.remove" , id: "001" }));
服务器对 WebSocket 的支持
WebSocket 不同于 http 协议, 传统的 web 服务器通常不支持 WebSocket, 比如 tomcat 目前就不支持 (tomcat 7.0.26 支持 WebSocket 了), 反倒是一些小众的或者更活跃的 web server 率先支持 WebSocket, 如 jetty, 以及基于 node.js 的 WebSocket-Node 扩展, 基本上各种编程语言都有相应的服务器可以选择, 下图是我列举的几种, 详细情况参阅: 链接地址
服务器端编程语言各不相同, 具体实现自然也不相同, 即使是同一种语言, 实现类和接口函数也有很大的差别, 比如 jetty 和 netty 都是基于 java 语言, 但他们的实现类几乎没有相同命名的, 下面我以 jetty(http://www.eclipse.org/jetty) 为例, 简单介绍 WebSocket 相关的类和方法 http://www.eclipse.org/jetty) 为例, 简单介绍 WebSocket 相关的类和方法 :
jetty 对 WebSocket 的实现
WebSocketServlet 基于 servlet 标准, 增加了 doWebSocketConnect(...) 方法, 为客户端请求创建一个后台对应的 WebSocket 实例
- org.eclipse.jetty.websocket.WebSocketServlet
- {
- WebSocket doWebSocketConnect(HttpServletRequest request, String protocol)
- }
后台 WebSocket 类, 与客户端 WebSocket 类对应, 能监听 open, message, close 等状态变化事件, 并包含一个 Connection 属性, 用于向客户端发送消息
- org.eclipse.jetty.websocket.WebSocket
- org.eclipse.jetty.websocket.WebSocket.OnTextMessage
- {
- void onOpen(Connection connect);
- void onClose(int code, String message);
- void onMessage(String message);
- }
WebSocket.Connection 后台连接类, 包含于 WebSocket 对象中, 用于向客户端推送消息
- org.eclipse.jetty.websocket.WebSocket.Connection
- {
- void sendMessage(String message);
- }
来源: http://www.qdfuns.com/article/17138/a7fa684b6acf113f1bd2d741f022910c.html