Click here to Skip to main content
Click here to Skip to main content

Using Sec-Websocket-Protocol

, 1 Feb 2014 CPOL
Rate this:
Please Sign up or sign in to vote.
Example server and client using different protocols over a Websocket (php/js)

Introduction

This article describes an example websocket server (which happens to be written in PHP), use of the Sec-WebSocket-Protocol header and an example client in HTML/javascript.

Implementing Protocols allows a single websocket server to present different interfaces to different clients.

Background  

Websockets provide a connection between browser and server which allows data to be sent in either direction at any time. There are a number of 'server-push' methods in use but Websockets promises to replace most, if not all, of these 'workarounds'.  

The Websockets standard (as per RFC 6455 ) now has native support in most popular desktop and mobile browsers with compatible javascript api - even InternetExplorer (as of IE v11 ).

The basic frame protocol is described in RFC 6455; a binary header contains an opcode, length and mask information followed by a block of data. How that data is interpreted is not defined by the specification, nor is the actual value of an optional http header used in the startup handshake: Sec-WebSocket-Protocol

Many simple websocket examples simply ignore protocol and use the connection to send a string (maybe encoded as JSON) to some server which is designed to understand it. However, if you happen to connect such a client to another websocket server - almost anything could happen.

Therefore, you can define your own method of interpreting websocket data, call that a protocol, give your protocol a name like 'myprotocol' and then have your javascript open a websocket connection like this:

var host = "ws://some.host.or.other/
var protcol="myprotocol";
socket = new WebSocket(host, protocol);

The server then knows it has to talk 'myprotocol' for this connection.

Actually, a server could be written to handle different data based on the protocol and/or the content of the url since all of this is down to the developer.

What we are looking at here is an example of a single websocket server which can handle several different protocols - allowing different clients to request different formats of data from the same server.  

'True' vs. 'Cheating' websocket servers

I'm not sure there really is such a definition, however... 

A 'true' websocket server would be integrated with a standard webserver which accepts requests like "http://some.url/" and delivers an HTTP service and accepts requests like "ws://something" and delivers a websocket service - all, usually, on port 80. 

A 'cheating' websocket server simply runs and accepts socket connections on a given port number. The example php server below 'cheats' because it can be executed from the commandline or a standard webserver (port 80) and then accepts websocket connections itself on a different port.  

The example here is a 'cheating' websocket server for development use. You probably don't want to do this in a live environment Smile | :)

If you want a simple webserver to use with this that you just run-and-it-works; check out Civetweb or Mongoose.  

What does the code do?

websocket2.php

websocket2.php is an example websocket server written in php, you can run this on the commandline if you have php installed or run it from a local webserver. It is quite happy accepting connections from anywhere on the web as long as you configure your routers etc. to allow its listening port number thru.

It is written to only accept connections with a valid protocol. If the javascript in our browser asked for:

socket = new WebSocket(host, 'myprotocol'); 

then, looking at the headers on connect with Chrome's developer tool (Network/headers), we see: 

Request URL:ws://192.168.0.42:12352/websocket/websocket2.php
Request Method:GET
Status Code:101 Switching Protocols
 
Request Headers
Cache-Control:no-cache
Connection:Upgrade
Host:tonywilk.no-ip.org:12352
Origin:http://192.168.0.42
Pragma:no-cache
Sec-WebSocket-Key:DMF3ByMTLq+cp7AyMN0qUA==
Sec-WebSocket-Protocol:myprotocol           <-- browser sends 'can I have this protocol'
Sec-WebSocket-Version:13
Upgrade:websocket
User-Agent: ... Chrome/32.0.1700.102 Safari/537.36
 
Response Headers
Connection:Upgrade
Sec-WebSocket-Accept:L6wqtsHk6dzD+kd9NCYT6Wt7OCU=
Sec-WebSocket-Protocol:myprotocol           <-- server replies ok
Upgrade:WebSocket

In fact the client can request a number of protocols like this:

Sec-WebSocket-Protocol:myprotocolv1,myprotocolv2,anotherprotcol

Allowing the server to decide which one to provide,

Our example server code has a list of handlers, one for each protocol type:

$protocolHandlers= array(
   "echo"    => 'doEcho',     // simply echos payload to ALL clients
   "chat"    => 'doChat',     // sends "[name] message..." to all other 'chat' clients
   "command" => 'doCommand',  // accepts commands to the server
);
include('./JSONsvc2.php');    // JSONsvc: adds protocol handler "JSONsvc"

(The included JSONsvc2.php dynamically adds "JSONsvc" to this list.)

These example protocols are very simple, but look at the differences - which hopefully demonstrate the usefulness of different protocols at the server end - if only to separate code and development of alternate interfaces to the same core server and be able to talk to all clients easily.

The JSONsvc protocol is a little more complicated and will be covered in a later article.
(In the mean time, there's lots of comment in the source.)  

websocket2.html

An example client which connects to the server using any of its protocols. it has a HELP button Smile | :)

If this is placed on a webserver along with the php files it can start the php server by loading it into an invisible iframe or you can run the php server on some socket somewhere else and just fill in the relevant host ip:port information. The php server attempts to keep the socket open by sending a websocket ping every 20 seconds which the javascript api helpfully replies to.

The default port number for the websocket server is 12352. This can be changed on the commandline or in the url (see the source for details).

Using the Code 

Extract the .zip into some directory 'wsdemo'.

If this directory is on a local webserver with php available, you are good to go - just browse to http://myserver/wsdemo/websockets2.html  - assuming that your access to myserver allows access to port 12352.  

From the browser you have to set the location of the php script if you want the page to start it for you by entering:  

php script url: http://myserver/wsdemo/websockets2.php 

to run on a different port: 

php script url: http://myserver/wsdemo/websockets2.php?port=9999

or you can run the php in a browser window with debug by opening a browser with:

http://myserver/wsdemo/websockets2.php?debug=1&port=9999 

If the directory is on your local machine, you will have to get PHP installed then you can run websockets2.php from the commandline and open websockets2.html in a browser.

Note that websocket2.php requires JSONsvc2.php.

On the commandline you can change the default port from 12352 amd enable debug by: 

prompt> php websockets2.php -d -p9999 

In all cases, the browser app needs to know where the websocket server is located, so fill in the Websocket Host. some examples:

ws://myserver:12352/
ws://localhost:9999/  

The defaults are to the webserver which sits on my desk, so you can try simply browsing to http://tonywilk.no-ip.org/wsdemo/websocket2.html - this may or may not be available, but it's worth a try !

Finally  

I think we're going to see a lot more of Websockets being used in all sorts of web applications now that we have compatibility with most browsers. However the current version is still young and some parts are causing security concerns (like the data masking to prevent cache poisoning - which is, frankly, pathetic), so I have no doubt it will change before too long.

There may even be standardized protocols for use with Websockets eventually.

In the mean time, get hold of the code, run up a server, open a browser and have a play!

TonyWilk  


Notes

Browsers supporting  Websockets v13
At the time of writing the following browsers have been tested with this code:
PC: Internet Explorer 11, Chrome 32, Firefox 26.0 and Android: Chrome 31, Opera 18
on windows pc/laptop, Samsung S3/4, Amazon Fire and a Nexus 7

Websocket Standard

The Websocket standard defines "Sec-WebSocket-Version: 13", if you see references to higher version numbers - check if they mean the earler drafts. The document which became "The Websocket Protocol" version 13 was called: "draft-ietf-hybi-thewebsocketprotocol-17" (!)





License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

tonywilk
Founder
United Kingdom United Kingdom
Developer in just about anything from 6502 machine code thru C, C++ and now things like PHP and javascript. Used to develop hardware and still dabble with electronics and ham radio when I'm not letting off pyrotechnics, shooting or flying my VPM M16 gyroplane.

Comments and Discussions

 
GeneralNice Work PinmemberNasir Darwish27-Oct-14 0:50 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.1411022.1 | Last Updated 2 Feb 2014
Article Copyright 2014 by tonywilk
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid