Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do websocket implementations use http protocol internally?

To establish a WebSocket connection, the client sends a WebSocket handshake request, for which the server returns a WebSocket handshake response, as shown in the example below.[30]

Client request (just like in HTTP, each line ends with \r\n and there must be an extra blank line at the end):

GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
Origin: http://example.com

Server response:

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=
Sec-WebSocket-Protocol: chat

I can't understand it. To initialize the connection HTTP GET request is sent. But what if I don't host HTTP server but I just host WebSocket server? How does it handle HTTP requests then?

like image 581
Konrad Avatar asked Nov 02 '17 21:11

Konrad


2 Answers

By design, the WebSocket protocol handshake uses HTTP so WebSockets can be utilized in existing HTTP servers and other HTTP-based technologies:

The WebSocket Protocol is designed to supersede existing bidirectional communication technologies that use HTTP as a transport layer to benefit from existing infrastructure (proxies, filtering, authentication). Such technologies were implemented as trade-offs between efficiency and reliability because HTTP was not initially meant to be used for bidirectional communication (see [RFC6202] for further discussion). The WebSocket Protocol attempts to address the goals of existing bidirectional HTTP technologies in the context of the existing HTTP infrastructure; as such, it is designed to work over HTTP ports 80 and 443 as well as to support HTTP proxies and intermediaries, even if this implies some complexity specific to the current environment. However, the design does not limit WebSocket to HTTP, and future implementations could use a simpler handshake over a dedicated port without reinventing the entire protocol. This last point is important because the traffic patterns of interactive messaging do not closely match standard HTTP traffic and can induce unusual loads on some components.

But, once the WebSocket handshake is finished, only the WebSocket protocol is used, not HTTP anymore.

So, it doesn't matter if you use an HTTP server with WebSocket support, or a dedicated WebSocket server. ANY WebSocket implementation MUST use HTTP (and all semantics therein, including authentication, redirection, etc) for the initial handshake. It is mandated by the WebSocket protocol specification, RFC 6455.

The opening handshake is intended to be compatible with HTTP-based server-side software and intermediaries, so that a single port can be used by both HTTP clients talking to that server and WebSocket clients talking to that server. To this end, the WebSocket client's handshake is an HTTP Upgrade request

So, a dedicated WebSockets server must be able to handle HTTP requests during the handshake phase, at least. It is not that hard to implement.

like image 114
Remy Lebeau Avatar answered Sep 29 '22 03:09

Remy Lebeau


Do websocket implementations use http protocol internally?

Yes, initially, then they switch to the webSocket protocol. All webSocket connections start with an HTTP request with a header that requests an upgrade to the webSocket protocol. If the receiving server agrees, then the two sides switch protocols from HTTP to webSocket and from then on the connection uses the webSocket protocol.

So, ALL webSocket servers MUST support that initial HTTP request because that's how all webSocket connections are started.

The webSocket protocol is designed this way for a couple reasons:

  1. So a single host and port can be used for both regular HTTP and webSocket connections. If you want, you can use a single server process to handle both types of connections. If they were on different ports, you would need two separate server processes.

  2. So that webSockets can run on port 80 or 443 (along with an HTTP server) for maximum compatibility with various, already deployed network infrastructure such as corporate proxies, firewalls, etc.... that may only permit traffic on regular HTTP ports.

As you've seen, a webSocket request starts with an HTTP request like this:

GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
Origin: http://example.com

Note the Upgrade: websocket header. That tells the receiving HTTP server that this is a request for a webSocket connection. If the server wants to accept that connection, it returns a 101 response which tells the client that they can now switch protocols:

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=
Sec-WebSocket-Protocol: chat

After this response, both client and server switch protocols (on the same TCP connection) and from then on they only speak the webSocket protocol and the TCP connection remains open until client or server explicitly close it (typically a long lived connection).

I can't understand it. To initialize the connection HTTP GET request is sent. But what if I don't host HTTP server but I just host WebSocket server?

All webSocket servers have to accept HTTP requests because all webSocket connections start with an HTTP request. So, there is no such thing as a webSocket server that doesn't accept an HTTP request. A pure webSocket only server can only accept HTTP requests that have the Upgrade: webSocket header and fail any other HTTP requests.

How does it handle HTTP requests then?

All webSocket servers expect incoming, new connections to start with HTTP so they must have a simple HTTP server built-in (can parse the initial HTTP headers).

like image 43
jfriend00 Avatar answered Sep 29 '22 03:09

jfriend00