WebSocket 对web应用来将是一个事件驱动,全双工异步通信通道(WebSocket is an event-driven, full-duplex asynchronous communications channel for your web applications)
websocket特点:
- 在TLS(Transport Layer Security 或 SSL)协议上进行操作
- 能够实时的更新,减少客户端和服务端(更多)资源需求
- 使用HTTP作为初始化传输机制,客户端接受到响应之后,通信不会中断,因此能够拜托传统的HTTP request/response 模式的约束
- 只要连接(connection)保持打开,客户端和服务端就能够自由异步的发送信息,而不用使用轮询(polling)
学习目标:
- 了解Websocket API
- Websocket 协议: 信息传递工具
- web 应用中如何使用
API
初始化
WebSocket 的构造器有2个参数:
-
URL
: 用作连接到服务器,如果不指定端口,则会通过默认端口80(HTTP 端口)或者端口443(HTTPS 端口)连接 -
protocol
(可选参数): 可以是数组或者一个字符串,不传入则默认为空字符串,用来指定子协议(subprotocols)。头文件作为 Sec-WebSocket-Protocol,一个server能够实现多个WebSocket子协议
WebSocket的一些协议:
- Registered protocols: 在WebSocket RFC6455的规范中,第11.5节定义了子协议名称由IANA维护注册的注册管理机构。
- Opened protocols: 可以使用开发的未注册的协议,比如XMPP(Extensible Messaging and Presence Protocol) 或者 STOMP(Simple Text Oriented Message Protocol 面向简单文字信息协议)
- Custom protocols: 可以自由设计协议,只要客户端和服务端都支持,推荐使用包含子协议发起方(originator)的域名的ASCII版本的名称,比如:chat.acme.com
使用本地server,而不使用web server代理连接的话,可以通过下列方式来实例化一个WebSocket对象
# 此处URL为: 'ws://localhost:8181'
# 如果使用TLS传输协议,URL中的'ws://' 可以用 'wss://'替换
var ws = new WebSocket('ws://localhost:8181');
事件
open
当WebSocket server响应连接请求,握手完成,open 事件触发,连接建立。
此时服务端完成握手,准备好发送信息和接收来自客户端应用的信息
var stock_request = {"stock": ["AAPL", "MSFT", "AMZN", "GOOG", "YHOO"]}
// WebSocket 连接建立
ws.onopen = function(e) {
console.log('Connection established');
ws.send(JSON.stringify(stock_request));
};
// stock_request json化后的字符串通过WebSocket发送给服务端
// 服务端知道哪些stocks需要更新
// 并且每隔1s向客户端将信息发送这些stocks信息
可以通过这个事件,可以向服务器发送信息,并且输出状态到屏幕,连接已准备好,可以开始双向的通信
message
当服务器端有数据,WebSocket API将调用 'message' 事件
error
当发生错误时,'error'事件触发,然后 'close' 事件将触发或者尝试重新连接,code 和 reason 特性能够提供一些错误信息
ws.onerror = function(e) {
console.log('WebSocket failure, error', e);
handleErrors(e);
}
PING/PONG
WebSocket协议调用2种帧类型: PING 和 PONG。
客户端不能够发送PING到服务端,PING只能由服务端发送,浏览器应当以PONG作为回应
close
当WebSocket连接关闭,'close'事件将触发,同时'onerror' 将被执行。一旦此事件触发,服务器和客户端的连接也就断开了
code 和 reason 特性,可以用于指示要处理的错误条件或close事件的原因,
wasClean(布尔值)可以用来判断中断是否完整, readyState 的值,从2('closing') 变为 3('closed')
// close事件
ws.onclose = function(e) {
console.log(e.reason + ' ' + e.code);
for (var symbol in stocks) {
if (stocks.hasOwnProperty(symbol)) {
stocks[symbol] = 0;
}
}
}
// close方法
ws.close(1000, 'WebSocket connection closed');
方法
WebSocket的创建者使它的方法十分的简单,只有2个方法:
- send()
- close()
send()
当客户端和服务端建立起连接,客户端可以指定什么类型的数据能够被传递,能够接收 string 和 binary 的值。
我们知道WebSocket是事件驱动的,使用此事件前,必须保证连接已经打开,并且准备好了接收消息,可以通过下面2种方式来完成:
1.在 onopen 事件中发送数据
var ws = new WebSocket('ws://localhost:8181');
ws.onopen = function(e) {
ws.send(JSON.stringify(stock_request));
}
2.检查 readyState 特性,确保WebSocket对象准备好了接收messages
function processEvent(e) {
if (ws.readyState === WebSocket.OPEN) {
// Socket 打开,Send
ws.send(e);
} else {
// 显示错误信息,待会再发送
}
}
close()
断开WebSocket连接或者中断尝试连接完成可以使用 close方法,调用此方法之后,数据就不能够再传递了
可以不带参数使用:
ws.close()
或者传入一个 数字代码 和 关闭原因
ws.close(1000, 'Goodbye, World');
数字代码:
- 1000:
CLOSE_NORMAL
,正常关闭,连接任务已经成功完成 - 1001:
CLOSE_GOING_AWAY
,终端离开,要么服务器失败或者浏览器离开连接的页面 - 1002:
CLOSE_PROTOCOL_ERROR
, 由于协议错误,终端终止连接 - 1003:
CLOSE_UNSUPPORTED
,由于终端接收到的数据类型不支持,连接断开 - 1004:
CLOSE_TOO_LARGE
,接收到的数据过大导致连接断开 - 1005:
CLOSE_NO_STATUS
,保留数字代码,显示没有状态码被提供 - 1006:
CLOSE_ABNORMAL
,表示连接意外被终止
特性(Attributes)
当连接建立(open),客户端应用中有几个可使用的特性
readyState
只读,在客户端发送数据之前最好先检查一下这个属性,这个属性有4个值,分别表示WebSocket不同的状态:
-
WebSocket.CONNECTING
:0
, 连接还没有打开 -
WebSocket.OPEN
:1
,连接打开,准备好通信 -
WebSocket.CLOSING
:2
,连接正在关闭中 -
WebSocket.CLOSED
:3
,连接关闭
不同的值可以用于调试和了解连接服务器的生命周期
bufferedAmount
发送到服务器的缓存数据量,多用于发送 binary 数据,因为该数据量给浏览器处理过大,这个属性最大的用处就是 在关闭连接之前确保所有的数据都被发送,并且实现客户端节流(throttling)
protocol
WebSocket构造器可选参数,客户端发送多个子协议到服务器,服务器决定选取那个协议,客户端和服务端握手完成,服务端应当包含选择的协议或者什么也没有
总结
本章主要了解了WebSocket的一些基本概念,以及WebSocket建立客户端与服务端的优势,主要有:
- WebSocket的定义
- WebSocket对象的实例化,2个参数,URL,protocols(可选)
- WebSocket相关的一些事件:open, message, error, close, PING/PONG
- 2个方法:send(), close()
- 特性:readyState,bufferedAmount, protocol