WebSockets

Intro

WebSockets?

  • full-duplex
  • TCP-based
  • persistent connection
  • message-oriented
  • cross-origin
  • standardized protocol
  • JavaScript API

WebSockets in action

  • http://wordsquared.com/
  • http://paintwith.me/
  • ...

…and more!

Why WebSockets?

  • HTTP is half-duplex
  • HTTP has too much overhead
  • Ajax doesn’t help
  • Comet doesn’t help


WebSocket protocol

  • protocol hell
  • security issues in hixie-76
  • RFC 6455

WebSocket protocol

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

WebSocket protocol

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

packets behind WebSocket connection

WebSocket request & response headers


Using WebSockets

  • Server-side:
    • Node.js
      • WebSocket-Node 
      • Socket.IO
    • C#/.NET (IIS 8 ASP.NET 4.5)
      • XSockets.NET 
      • Fleck
  • Java
    • Atmosphere
  • Ruby
    • EM-WebSocket

Browser Support

caniuse

WebSocket API

WebSocket WebSocket( in DOMString url, in optional DOMString protocols );
WebSocket WebSocket( in DOMString url, in optional DOMString[] protocols );

WebSocket API

  1. Parse URL or throw SYNTAX_ERR
  2. If port is blocked, throw SECURITY_ERR
  3. Check sub-protocol
  4. Get origin from <script>
  5. Return WebSocket object
  6. Establish a socket connection

WebSocket API

Status

  • readyState 
    • CONNECTING ( = 0 ) 
    • OPEN ( = 1 ) CLOSE ( = 2 ) 
    • CLOSING 
  • onopen 
  •  onmessage 
  •  onclose 
  •  onerror

Methods

  • close(code, reason)
  • send(data)
    • String
    • ArrayBuffer
    • Blob

Simple Chat

Feature: Simple chat
In order to websocket's challenge
As a presenter I will create a simple chat

Simple chat

Intro
Scenario: At the beginning every user can select their name
Given New user
When try to connect to the chat
Then user can select his name

Simple chat

New message
Scenario: New message
Given user which was already connected to the chat
And several users was already connected to the chat
When user enter a new message
Then all users will receive message

Simple chat

Message history
Scenario: Message history
Given New user
And History is not empty
When Use connect to the chat
Then User will recieve entire message history

Simple Chat

Close connection
Scenario: Close connection
Given User which was already connected to the chat
When a user closes the browser window
Then server will post another system message to the console that a user has disconnected.

Simple chat

API
  • type
    • message - one element
      • author
      • text
      • time
    • history
      • array of elements


Simple chat

Need help?
input.keydown(function(e) {
var msg;
if (e.keyCode === 13) {
  msg = $(this).val();
  if (!msg) return;
  connection.send(msg);
  $(this).val("");
}

Simple chat

https://gist.github.com/forcewake/6403353#file-index-html
https://gist.github.com/forcewake/6403353#file-client-js

Binary data in JS [oh why]

  • WebGL
  • Files
  • XHR2
  • WebSockets
  • DataView
  • Type arrays
  • Blobs
  • Clamped array
  • ...

Binary data in JS [is great]


var buffer = new ArrayBuffer(16)

var dv = new DataView(buffer, 8, 4)


Binary data in JS [is great]


         dv.setUint16(2, 0x1337)
      

        dv.getInt8(2) -> 0x13
      
      var arr = new Int32Array(buffer) 
arr[2] === ?



Blobs

API

         Blob Blob( [optional] Array parts, [optional] BlobPropertyBag properties );

         Blob slice( optional long long start, optional long long end, optional DOMString contentType };


Binary data over WS

…just send it already!

opcode

meaning

0

Continuation Frame

1

Text Frame

2

Binary Frame

8

Connection Close Frame

9

Ping Frame

10

Pong Frame

socket.binaryType = “arraybuffer” | “blob”

The WebSocket Challenge

  • ArrayBuffer
  • JSON Danger

THE WEBSOCKET CHALLENGE

  1. { msg:”challenge_accepted”, name: “Socketeers” }
  2. { msg: “auth”, auth_token: “6f7sd8s78”}
  3. Task1 request: { msg: “task_one”,  auth_token: “6f7sd8s78”}
  4. Task1 server response: { msg: “compute”, operator:”+/-/*”, operands:[4,5]}
  5. Task1 send result: { msg: “task_one_result”, result: “9”, auth_token: “6f7sd8s78” }
  6. Task2 request: { msg: ???, auth_token: “6f7sd8s78” }
  7. Task2 server response: {msg: “binary_sum”, bits: 8/16 } and ArrayBuffer (16 bytes)Convert to an unsigned typed array according to the `bits` field
  8. Task2 send result: { msg: “task_two_result”, result: “0”, auth_token: “6f7sd8s78” }

THE WEBSOCKET CHALLENGE

Check message type with typeof evt.data == “string”

XXX.XXX.XXX.XXX:8080