前言
初次接触 WebSocket 的人,都会问同样的问题:我们已经有了 HTTP 协议,为什么还需要另一个协议?它能带来什么好处?
答案很简单,因为 HTTP 协议有一个缺陷:HTTP 协议做不到服务器主动向客户端推送信息。
有一个方案是客户端发起请求建立连接后,服务端和客户端约定建立长连接,服务端就紧紧抓住这个连接,有消息就服务端就发过去,但是超时了就还得重新建立连接。这只是减少了客户端发起请求的次数,本质上还是不能实现服务端主动连接客户端并发送数据包。
什么是 WebSocket 协议
WebSocket 协议的诞生就是为了使得:服务器可以主动向客户端推送信息
什么是 Socket?
在网络中的两个应用程序(进程)需要全双工相互通信(全双工即双方可同时向对方发送消息),需要用到的就是 Socket,它能够提供端对端通信
Socket 的本质是一种特殊的文件,一些 Socket 函数就是对其进行的操作(读/写IO、打开、关闭)
我们可以采取这种方式构建一个桌面版的 im 程序,让不同主机上的用户发送消息。从本质上来说,Socket 并不是一个新的协议,它只是为了便于程序员进行网络编程而对 TCP/IP 协议族通信机制的一种封装
WebSocket 的优势:
(1)建立在 TCP 协议之上,服务器端的实现比较容易。
(2)与 HTTP 协议有着良好的兼容性。默认端口也是 80 和 443,并且握手阶段采用 HTTP 协议,因此握手时不容易屏蔽,能通过各种 HTTP 代理服务器。
(3)数据格式比较轻量,性能开销小,通信高效。
(4)可以发送文本,也可以发送二进制数据。
(5)没有同源限制,客户端可以与任意服务器通信。
(6)全双工,所以服务器可以随时主动给客户端下发数据。
(7)协议标识符是ws(如果加密,则为wss),服务器网址就是 URL
WebSocket 的核心
WebSocket 借助 TCP 协议建立连接(客户端用报文通知服务端后面彼此传输数据要用 WebSocket 协议),成功建立连接后通信过程使用 WebSocket 协议
协议是全双工的,所以服务器可以随时主动给客户端下发数据
WebSocket 的创建和使用
以下 API 用于创建 WebSocket 对象。
var Socket = new WebSocket(url, [protocol] );
以上代码中的第一个参数 url, 指定连接的 URL。第二个参数 protocol 是可选的,指定了可接受的子协议
WebSocket 的属性
WebSocket 的事件
WebSocket 的方法
WebSocket 的使用实例
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>WebSocket 协议的使用</title>
<script type="text/javascript">
function WebSocketTest(){
if ("WebSocket" in window){
alert("您的浏览器支持 WebSocket!");
// 打开一个 web socket
var ws = new WebSocket("ws://localhost:9998/echo");
ws.onopen = function(){
// Web Socket 已连接上,使用 send() 方法发送数据
ws.send("发送数据");
alert("数据发送中...");
};
ws.onmessage = function (evt){
var received_msg = evt.data;
alert("数据已接收...");
};
ws.onclose = function(){
// 关闭 websocket
alert("连接已关闭...");
};
}
else alert("您的浏览器不支持 WebSocket!");
}
</script>
</head>
<body>
<div id="sse">
<a href="javascript:WebSocketTest()">运行 WebSocket</a>
</div>
</body>
</html>
用 WebSocket 发送接受二进制数据
WebSocket可以通过ArrayBuffer,发送或接收二进制数据。
var socket = new WebSocket('ws://127.0.0.1:8081'); // 填上 url
socket.binaryType = 'arraybuffer';
// 监听 socket 打开
socket.addEventListener('open', function (event) {
// 发送二进制数据
var typedArray = new Uint8Array(4);
socket.send(typedArray.buffer);
});
// 接收二进制数据
socket.addEventListener('message', function (event) {
var arrayBuffer = event.data;
// 做一些处理
});
WebSocket 的缺点
不兼容低版本的浏览器