技术简介
Websocket是通过TCP连接的通信协议,旨在在浏览器和Web服务器之间实时交换消息。
为了建立WebSocket连接,客户端和服务器使用类似于HTTP的协议。客户端发出一个特殊的HTTP请求,服务器以特定的方式响应该HTTP请求。
备注
尽管新的请求和响应与HTTP请求和响应“相似”,但与之不同。例如,一个请求具有一个主体,但标头中没有“ Content-Length”字段(这违反了HTTP约定)。您可以在Wikipedia上阅读有关此内容的更多信息。
该技术的主要优点之一是其简单性。客户端和服务器上只有4个事件要处理:
- 连接
- 错误
- 信息
- 关
为什么选择Websocket?
除ws外,还有两种其他的连续数据传输方法:服务器发送事件(SSE)和长轮询。
让我们比较一下服务器和客户端之间持续通信的机制,并得出有关使用Websocket为何值得(或不值得)的结论。
Websocket | se | 长池 | |
---|---|---|---|
协议 | websocket(ws或wss) | HTTP(S) | HTTP(S) |
速度 | 高 | 低 | 低 |
数据流的方向性 | 双向的 | 单向 | 双向的 |
另外 | 传输二进制数据,
不支持某些旧版浏览器 |
连接断开时自动重新连接 |
ws技术的主要优点之一是数据传输速度。SSE和LP使用HTTP(S)协议,工作方式如下:
- 要求更改;
- 如果服务器上出现更改,则服务器将其发送;
- , .
:
api.
const http = require("http");
const express = require( "express");
const WebSocket = require( "ws");
const app = express();
const server = http.createServer(app);
const webSocketServer = new WebSocket.Server({ server });
webSocketServer.on('connection', ws => {
ws.on('message', m => {
webSocketServer.clients.forEach(client => client.send(m));
});
ws.on("error", e => ws.send(e));
ws.send('Hi there, I am a WebSocket server');
});
server.listen(8999, () => console.log("Server started"))
这里发生了什么?
要创建支持ws的服务器,我们创建一个常规的http服务器,然后在创建websocket时将其绑定到该服务器。
“开启”功能有助于管理websocket事件。最值得注意的事件是消息事件,因此让我们仔细看一下。
该函数在此处接收参数m-消息,即用户发送的消息。因此,我们可以从客户端发送一个字符串,并在服务器上对其进行处理。在这种情况下,服务器仅将此消息转发给连接到Websocket服务器的每个人。 webSocketServer对象的clients数组包含与服务器的所有连接。 ws对象一次仅存储一个连接。
评论
您不应该在实际的应用程序中使用这种方法。如果以这种方式描述api,则服务器无法将一个请求与另一个请求区分开。稍后将介绍如何构建基于websocket的api。
与客户端上的服务器的交互如下所示:
export const wsConnection = new WebSocket("ws://localhost:8999");
wsConnection.onopen = function() {
alert(" .");
};
wsConnection.onclose = function(event) {
if (event.wasClean) {
alert(' ');
} else {
alert(' '); // , ""
}
alert(': ' + event.code + ' : ' + event.reason);
};
wsConnection.onerror = function(error) {
alert(" " + error.message);
};
export const wsSend = function(data) {
// readyState - true,
if(!wsConnection.readyState){
setTimeout(function (){
wsSend(data);
},100);
} else {
wsConnection.send(data);
}
};
基于Websocket的API
与REST API的请求分布在不同的URL上不同,Websocket API仅具有一个URL。为了构建基于websocket的完整API,您需要教系统将一个请求与另一个请求区分开。这可以实现如下:
1)从客户端,我们将以json字符串的形式传输请求,并在服务器上进行解析:
const sendMessage = (message) => conn.send(JSON.stringify({ event: "chat-message", payload: { userName, message }}));
2)在服务器上,我们解析字符串,然后选择事件字段-请求的类型。让我们为每种类型写下相应的答案:
const dispatchEvent = (message, ws) => {
const json = JSON.parse(message);
switch (json.event) {
case "chat-message": webSocketServer.clients.forEach(client => client.send(message));
default: ws.send((new Error("Wrong query")).message);
}
}
因此,我们可以将不同的请求发送到服务器,并根据请求处理响应。
结论
如果您承担了制作API的任务,并且发现客户对支持旧版浏览器不感兴趣,那么基于WebSocket的API是一个不错的选择。为了您的方便,我们在link上为客户端和服务器部分准备了代码。