HTML5 - Web Socket

持久连接和双向通信

WebSocket 介绍

  • 目标:在一个持久连接上提供全双工的双向通信。
  • 最开始是以TCPConnection的身份添加到HTML5 规范的, 后来被抽离出来形成了自己的单独的规范。
  • 浏览器支持:Firefox 6+, Safari 5+, Chrome和iOS 4以上的Safari。

Web Sockets 协议

Web Socket 使用了自定义的协议,而不是HTTP,所以URL模式也略有不同:

  • 未加密的连接是ws://
  • 加密连接是wss://

使用自定义协议而不是HTTP协议的好处是,能够在客户端和服务器之间发送非常少量的数据,因此特别适合移动应用。

Web Sockets API

建立连接

要创建Web Socket,先实例一个WebSocket 对象并传入要连接的URL:

var socket = new WebSocket("ws://www.example.com/server.php");      
      

注意:必须给WebSocket 构造函数传入绝对URL路径。

Web Sockets API

关闭连接

要关闭Web Socket 连接,可以在任何时候调用close()方法。

socket.close();      
      

连接的建立过程

  • 实例化Web Socket 后,浏览器就会马上尝试创建HTTP连接;
  • 浏览器发起连接,并取得服务器响应后,建立的连接会从使用HTTP协议升级为Web Socket协议。

连接状态

WebSocket 有一个表示当前状态的readyState 属性:

  • WebSocket.OPENING(0): 正在建立连接
  • WebSocket.OPEN(1): 已经建立连接
  • WebSocket.CLOSING(2): 正在关闭连接
  • WebSocket.CLOSE(3): 已经关闭连接

readyState 的值永远从0开始。

发送简单数据

Web Socket 打开之后,就可以通过连接发送和接收数据。

发送数据使用send()方法,并传入任意字符串。例如:

var socket = new WebSocket("ws://www.example.com/foobar.php");
socket.send("Hello world!");
      

发送复杂数据

  • Web Sockets只能通过连接发送纯文本数据;
  • 对于复杂的数据结构,发送前要进行序列化;

下面的代码是把数据序列化成JSON字符串,再发送到服务器:

var message = {
  time: new Date(),
  text: "Hello World!",
  clientId: "adkeig393g8dk"
};      

socket.send(JSON.stringify(message));
      

服务器收到以后,再解析收到的JSON字符串。

接收数据

当服务器向客户端发来消息时,Web Socket 对象会触发message事件。这个message事件同样把返回的数据保存在event.data中。

socket.onmessage = function(event) {
  var data = event.data;
  // 处理数据
};
      

与通过send()发送到服务器的数据一样,event.data中返回的数据也是字符串。大部分情况下也需要手工解析。

其他事件

在连接生命周期不同阶段触发的其他三个事件(除了message):

  • open: 在成功建立连接时触发
  • error: 发生错误时触发,连接不能持续
  • close: 在连接关闭时触发

代码:其他事件

var socket = new WebSocket("ws://www.example.com/server.php");
socket.onopen = function() {
  alert("连接建立!");
}      
socket.onerror = function() {
  alert("连接出错!");
}
socket.onclose = function(event) {
  console.log("连接关闭!" + "Was clean?" + event.wasClean + " Code=" + event.code + " Reason=" + event.reason);
}
      

close事件的属性

前面的三个事件中只有close事件的event对象有额外的三个属性信息:

  • wasClean是一个布尔值,表示连接是否已经明确的关闭;
  • code 是服务器返回的数值状态码;
  • reason是一个字符串,包含服务器发回的信息。
socket.onclose = function(event) {
  console.log("连接关闭!" + "Was clean?" + event.wasClean + 
    " Code=" + event.code + " Reason=" + event.reason);
}
      

Demo

即时通信聊天室

使用Web Socket 进行即时通信

正在连接....

扩展阅读

<Thank you!>