Web Sockets的目标是在一个单独的持久链接上提供全双工、双向通讯。在Javascript中建立了Web Sockets以后,会有一个HTTP请求发送到浏览器以发起链接。在取得服务器响应后,创建的链接会使用HTTP升级从HTTP协议交换为Web Socket协议。也就是说,使用标准的HTTP服务器没法实现Web Sockets,只有支持这种协议的专门服务器才能正常工做。
因为Web Sockets使用了自定义的协议,因此URL模式也略有不一样。未加密的链接再也不是http://,而是ws://;加密的链接也不是https://,而是wss://。在使用Web Sockets URL时,必须带着这个模式,由于未来还有可能支持其余模式。
使用自定义协议而非HTTP协议的好处:
可以在客户端和服务器之间发送很是少许的数据,而没必要担忧HTTP那样字节级的开销。因为传递的数据包很小,所以Web Sockets很是适合移动应用。毕竟对移动应用而言,带宽和网络延迟都是关键问题。
自定义协议的缺点:
制定协议的时间比制定Javascript API的时间还要长。
存在一致性和安全性问题。
支持Web Sockets的浏览器:Firefox6+、Safari5+、Chrome、iOS4+版的Safari。
(1)Web Sockets API
建立Web Socket,实例一个WebSocket对象并传入要链接的URL:
var socket = new WebSocket("ws://www.example.com/server.php");
注:必须给WebSocket构造函数传入绝对URL。同源策略对Web Sockets不适用,所以能够经过它打开到任何站点的链接。至因而否会与某个域中的页面通讯,则彻底取决于服务器。(经过握手信息就能够知道请求来自何方。)
WebSocket表示当前状态的readyState属性:
* WebSocket.OPENING(0):正在创建链接。
* WebSocket.OPEN(1):已经创建链接。
* WebSocket.CLOSING(2):正在关闭链接。
* WebSocket.CLOSE(3):已经关闭链接。
关闭Web Socket链接:
socket.close();
调用了close()以后,readyState的值当即变为2(正在关闭),而在关闭链接后就会变成3。
(2)发送和接收数据
向服务器发送数据,使用send()方法并传入任意字符串:
var socket = new WebSocket("ws://www.example.com/server.php");
socket.send("Hello World!");
由于Web Sockets只能经过链接发送纯文本数据,因此对于复杂的数据结构,在经过链接发送以前,必须序列化。
如:
var message = {
time: new Date(),
text: "Hello World!",
clientId: "asdfp8734req"
};
socket.send(JSON.stringify(message));
当服务器向客户端发送消息是,WebSocket对象就会触发message事件:
socket.onmessage = function(event){
var data = event.data;
//处理数据
//event.data返回的数据也是字符串
};
(3)其余事件
* open:在成功创建链接时触发。
* error:在发生错误时触发,链接不能持续。
* close:在链接关闭时触发。
WebSocket对象不支持DOM2级事件侦听器,必须使用DOM0级语法分别定义每一个事件处理程序。
1 var socket = new WebSocket("ws://www.example.com/server.php");
2 socket.onopen = function(){
3 alert("Connection established.");
4 };
5 socket.onerror = function(){
6 alert("Connection error.");
7 };
8 socket.onclose = function(){
9 alert("Connection closed.");
10 };
只有close事件的event对象有额外的信息。
三个额外属性: wasClean:布尔值,表示链接是否已经明确的关闭; code:服务器返回的数值状态码; reason:一个字符串,包含服务器发回的消息。能够吧这些信息显示给用户,也能够记录到日志中以便未来分析:socket.onclose = function(event){ console.log("Was clean?" + event.wasClean + " Code=" + event.code + " Reason=" + event.reason);};