什么是 WebSocket 子协议?
What is a WebSocket Subprotocol?
我一直在尝试在 nodejs 中从头开始实现 WebSocket 协议,这样做我有一个问题一直没有解决。关于 websockets 的子协议到底是什么? WebSocket 构造函数的第二个参数是您指定“子协议”的地方 -
let socket = new WebSocket("ws://localhost:3000",["http",...]);
谁能给我说清楚他们的目的是什么?
解释于 MDN here
Think of a subprotocol as a custom XML schema or doctype declaration.
You're still using XML and its syntax, but you're additionally
restricted by a structure you agreed on. WebSocket subprotocols are
just like that. They do not introduce anything fancy, they just
establish structure. Like a doctype or schema, both parties must agree
on the subprotocol; unlike a doctype or schema, the subprotocol is
implemented on the server and cannot be externally referred to by the
client.
Subprotocols are explained in sections 1.9, 4.2, 11.3.4, and 11.5 of the spec.
A client has to ask for a specific subprotocol. To do so, it will send
something like this as part of the original handshake:
http GET /chat HTTP/1.1 ... Sec-WebSocket-Protocol: soap, wamp
or, equivalently:
... Sec-WebSocket-Protocol: soap Sec-WebSocket-Protocol: wamp
Now the server must pick one of the protocols that the client
suggested and it supports. If there is more than one, send the first
one the client sent. Imagine our server can use both soap and wamp.
Then, in the response handshake, it sends:
Sec-WebSocket-Protocol: soap
The server can't send more than one Sec-Websocket-Protocol header. If
the server doesn't want to use any subprotocol, it shouldn't send any
Sec-WebSocket-Protocol header. Sending a blank header is incorrect.
The client may close the connection if it doesn't get the subprotocol
it wants.
If you want your server to obey certain subprotocols, then naturally
you'll need extra code on the server. Let's imagine we're using a
subprotocol json. In this subprotocol, all data is passed as JSON. If
the client solicits this protocol and the server wants to use it, the
server needs to have a JSON parser. Practically speaking, this will be
part of a library, but the server needs to pass the data around.
Websockets 只是定义了一种交换任意消息的机制。这些消息意味着什么,客户端在任何特定时间点可以期待什么样的消息,或者他们被允许发送什么消息,完全取决于实施应用程序。所以你需要在服务器和客户端之间就这些事情达成协议。您可能会说……您需要 协议规范 。子协议参数只是让客户端正式交换此信息。您可以为您想要的任何协议编写任何名称。服务器可以简单地检查客户端在握手期间是否遵守该协议。你也可以用它来向服务器请求不同种类的协议,或者用它来进行版本控制(例如当你引入my-protocol-v2
,但仍然需要支持客户端只理解my-protocol-v1
)。
一些示例代码,复制自 https://hpbn.co/websocket/#subprotocol-negotiation,以使其清晰。
The client can advertise which protocols it supports to the server as
part of its initial connection handshake:
var ws = new WebSocket('wss://example.com/socket',
['appProtocol', 'appProtocol-v2']);
ws.onopen = function () {
if (ws.protocol == 'appProtocol-v2') {
...
} else {
...
}
}
我一直在尝试在 nodejs 中从头开始实现 WebSocket 协议,这样做我有一个问题一直没有解决。关于 websockets 的子协议到底是什么? WebSocket 构造函数的第二个参数是您指定“子协议”的地方 -
let socket = new WebSocket("ws://localhost:3000",["http",...]);
谁能给我说清楚他们的目的是什么?
解释于 MDN here
Think of a subprotocol as a custom XML schema or doctype declaration. You're still using XML and its syntax, but you're additionally restricted by a structure you agreed on. WebSocket subprotocols are just like that. They do not introduce anything fancy, they just establish structure. Like a doctype or schema, both parties must agree on the subprotocol; unlike a doctype or schema, the subprotocol is implemented on the server and cannot be externally referred to by the client.
Subprotocols are explained in sections 1.9, 4.2, 11.3.4, and 11.5 of the spec.
A client has to ask for a specific subprotocol. To do so, it will send something like this as part of the original handshake:
http GET /chat HTTP/1.1 ... Sec-WebSocket-Protocol: soap, wamp
or, equivalently:
... Sec-WebSocket-Protocol: soap Sec-WebSocket-Protocol: wamp
Now the server must pick one of the protocols that the client suggested and it supports. If there is more than one, send the first one the client sent. Imagine our server can use both soap and wamp. Then, in the response handshake, it sends:
Sec-WebSocket-Protocol: soap
The server can't send more than one Sec-Websocket-Protocol header. If the server doesn't want to use any subprotocol, it shouldn't send any Sec-WebSocket-Protocol header. Sending a blank header is incorrect. The client may close the connection if it doesn't get the subprotocol it wants.
If you want your server to obey certain subprotocols, then naturally you'll need extra code on the server. Let's imagine we're using a subprotocol json. In this subprotocol, all data is passed as JSON. If the client solicits this protocol and the server wants to use it, the server needs to have a JSON parser. Practically speaking, this will be part of a library, but the server needs to pass the data around.
Websockets 只是定义了一种交换任意消息的机制。这些消息意味着什么,客户端在任何特定时间点可以期待什么样的消息,或者他们被允许发送什么消息,完全取决于实施应用程序。所以你需要在服务器和客户端之间就这些事情达成协议。您可能会说……您需要 协议规范 。子协议参数只是让客户端正式交换此信息。您可以为您想要的任何协议编写任何名称。服务器可以简单地检查客户端在握手期间是否遵守该协议。你也可以用它来向服务器请求不同种类的协议,或者用它来进行版本控制(例如当你引入my-protocol-v2
,但仍然需要支持客户端只理解my-protocol-v1
)。
一些示例代码,复制自 https://hpbn.co/websocket/#subprotocol-negotiation,以使其清晰。
The client can advertise which protocols it supports to the server as part of its initial connection handshake:
var ws = new WebSocket('wss://example.com/socket',
['appProtocol', 'appProtocol-v2']);
ws.onopen = function () {
if (ws.protocol == 'appProtocol-v2') {
...
} else {
...
}
}