目录
1. websocket 介绍
HTTP 协议是一种无状态的、无连接的、单向的应用层协议。它采用了请求/响应模型。通信请求只能由客户端发起,服务端对请求做出应答处理,HTTP 协议无法实现服务器主动向客户端发起消息。
这种单向请求的特点,注定了如果服务器有连续的状态变化,客户端要获知就非常麻烦。大多数 Web 应用程序将通过频繁的异步 JavaScript 和 XML(AJAX)请求实现长轮询。轮询的效率低,非常浪费资源。
Websocket应运而生,WebSocket 连接允许客户端和服务器之间进行全双工通信,以便任一方都可以通过建立的连接将数据推送到另一端。WebSocket 只需要建立一次连接,就可以一直保持连接状态,双向实时通信。这相比于轮询方式的不停建立连接显然效率要大大提高。
-
应用场景
- 实时弹幕
- 媒体聊天
- 在线文档协同编辑
- 基于位置的应用(外卖员的实时位置,滴滴车司机的实时位置)
- 体育实况更新
- 股票基金报价实时更新
2. 客户端(浏览器)实现
-
WebSocket 对象
- 通过以下方式,在浏览器端创建 WebSocket 对象
- 参数 url 格式说明:ws://ip地址:端口号/资源名称
const ws = new WebSocket(url)
- WebSocket 事件
事件 | 事件处理程序 | 描述 |
---|---|---|
open | WebSocket 对象.onopen | 连接建立时触发 |
message | WebSocket 对象.onmessage | 客户端接收服务端数据时触发 |
error | WebSocket 对象.onerror | 通信发生错误时触发 |
close | WebSocket 对象.onclose | 连接关闭时触发 |
- WebSocket 方法
方法 | 描述 |
---|---|
WebSocket 对象.send() | 向服务器发送数据 |
<script/>
var sock = new WebSocket("ws://127.0.0.1:8080");
sock.on("open", function () {
console.log("connect success !!!!")
})
sock.on("error", function (err) {
console.log("error: ", err)
})
sock.on("close", function () {
console.log("close")
});
sock.on("message", function (data) {
console.log(data)
})
sock.send(JSON.stringify(values))
</script>
3. 服务器端实现
- 安装
npm install websocket
创建WebSocket服务器对象语法格式:
new WebSocket.Server(options[, callback])
事件 | 描述 |
---|---|
close | 服务器关闭时被触发 |
connection | 成功握手连接时触发 |
error | 发生错误时被触发,可注入一个Error对象 |
headers | 握手前被触发,允许在发送HTTP头之前检查和修改标题 |
listening | 绑定端口时被触发 |
//1、安装ws模块 npm install ws
//2、导入ws模块
const WebSocket=require('ws');
//3、创建WebSocket服务器
const server=new WebSocket.Server({port:8080});
//4、监听open事件
server.on('open',()=>{
console.log('建立连接');
})
//5、绑定close事件
server.on('close',()=>{
console.log('关闭连接')
})
//6、绑定connection事件 ws参数表示客户端 req表示客户端的请求信息
server.on('connection',(ws,req)=>{
//6.1获取客户端的ip port
const ip=req.connection.remoteAddress;
const port=req.connection.remotePort;
const clientName=ip+port;
console.log('%s is connect',clientName);
//6.2向客户端发送消息
ws.send('欢迎'+clientName);
//监听 客户端 message 事件,转发给其他人
ws.on('message',(msg)=>{
console.log('消息:%s 来自于 %s',msg,clientName);
//6.3把消息广播所有客户端:clients表示所有客户端
server.clients.forEach(function (client) {
//若某个客户端是打开的,就把消息广播给该客户
if (client.readyState===WebSocket.OPEN){
client.send(clientName+'---------'+msg);
}
})
})
})
4. socket.io 模块
Socket.IO是一个WebSocket 模块,包括了客户端的js和服务器端的nodejs,它的目标是构建可以在不同浏览器和移动设备上使用的实时应用,有以下特点:
- 易用性:socket.io封装了服务端和客户端,使用起来非常简单方便。
- 跨平台:socket.io支持跨平台,这就意味着你有了更多的选择,可以在自己喜欢的平台下开发实时应用。
- 自适应:它会自动根据浏览器从WebSocket、AJAX长轮询、Iframe流等等各种方式中选择最佳的方式来实现网络实时应用,非常方便和人性化,而且支持的浏览器最低达IE5.5