HTTP vs. WebSocket

HTTP is a RESTful protocol with a uni-directional communication. This means the client needs to poll to get updates from the server. With HTTP/1.0 for every request has been a new TCP connection created. Since HTTP/1.1 they are providing a keep-alive mechanism which is keeping the TCP connection alive for several requests.

Protocol-Stack:

--------------
|    HTTP    |
--------------
|    TCP     |
--------------
|    IP      |
--------------

Communication:
1. Connection: close (Default for HTTP/1.0)

Client                 Server
   |<-- TCP handshake -->|
   |--- HTTP request --->|
   |<-- HTTP response ---|

   |<-- TCP handshake -->|
   |--- HTTP request --->|
   |<-- HTTP response ---|

2. Connection: keep-alive (Default for HTTP/1.1)

Client                 Server
   |<-- TCP handshake -->|
   |--- HTTP request --->|
   |<-- HTTP response ---|
   |--- HTTP request --->|
   |<-- HTTP response ---|

Requests: Get (Get Object), Put (Create Object), Post (Update Object), Delete (Delete Object), ...

Example - Change email of user (Simplified)

Client                    Server
   |<--- TCP handshake ---->|
   |--- 1) GET request ---->|
   |<-- 2) GET response ----|
   |--- 3) POST request --->|
   |<-- 4) POST response ---|

1) GET request:

GET / HTTP/1.1
Host: www.site.org/user

2) GET response:

HTTP/1.1 200 OK
[
 { "id" = 000, "name" = "admin", "email" = "admin@site.com" },
 { "id" = 001, "name" = "user1", "email" = "old_user@site.com" }
]

3) POST request:

POST / HTTP/1.1
Host: www.site.org/user?id=001
{ email = "new_user@site.com" }

4) POST response:

HTTP/1.1 200 OK
{ "id" = 001, "name" = "user1", "email" = "new_user@site.com" }

WebSocket is like a normal socket and allows a bi-dircetional communication. This means the server can inform the client about updates. For the whole communication is just one TCP connection necessary. The communication is also full-duplex, which means that client and server can write parallel to each other.

Protocol-Stack:

--------------
|  WebSocket |
--------------
|    TCP     |
--------------
|    IP      |
--------------

Communication:

Client                         Server
   |<------ TCP handshake ------>|
   |--- HTTP upgrade request --->|
   |<-- HTTP upgrade response ---|
   |<-- Websocket text frame --->|
                ...
   |<-- Websocket close frame -->|

Example - Get notified when email of user changed (Simplified)
The structure of the messages send via the websocket has to be known by both sides (specification).

Client                            Server
   |<-------- TCP handshake --------->|
   |--- 1) HTTP upgrade request ----->|
   |<-- 2) HTTP upgrade response -----|
   |--- 3) WS subscribe request ----->|
   |<-- 4) WS subscribe response -----|
   |<-- 5) WS event frame 1 ----------|
                ...
   |<-- 6) WS event frame 2 ----------|
                ...
   |--- 7) WS unsubscribe request --->|
   |<-- 8) WS unsubscribe response ---|
   |--- 9) WS close frame ----------->|

1) HTTP upgrade request

GET /chat HTTP/1.1
Host: www.site.com
Connection: Upgrade
Upgrade: websocket

2) HTTP upgrade response

HTTP/1.1 101 Switching Protocols
Connection: Upgrade
Upgrade: websocket

3) WS subscribe request

Opcode: Text
Payload: {
  "type" : "subscribe",
  "event" : "user"
}

4) WS subscribe response

Opcode: Text
Payload: {
  "type" : "subscribe",
  "event" : "user",
  "status" = "accepted"
}

5) WS event frame 1

Opcode: Text
Payload: {
  "type" : "data",
  "event" : "user",
  "data" = [
    { "id" = 000, "name" = "admin", "email" = "admin@site.com" },
    { "id" = 001, "name" = "user1", "email" = "old_user@site.com" }
  ]
}

6) WS event frame 2

Opcode: Text
Payload: {
  "type" : "data",
  "event" : "user",
  "data" = [
    { "id" = 000, "name" = "admin", "email" = "admin@site.com" },
    { "id" = 001, "name" = "user1", "email" = "new_user@site.com" }
  ]
}

7) WS unsubscribe request

Opcode: Text
Payload: {
  "type" : "unsubscribe",
  "event" : "user"
}

8) WS unsubscribe response

Opcode: Text
Payload: {
  "type" : "unsubscribe",
  "event" : "user",
  "status" = "accepted"
}

9) WS close frame

Opcode: Connection Close
Payload: {}