Subject: [hybi] Walkthrough of WebKit's WebSocket client implementation

From: Maciej Stachowiak <[email-masked]>
Date: Sun, 28 Feb 2010 12:52:20 -0800

There's been some interest in what client and server implementations  
of the WebSocket protocol might look like. Here's an overview of  
WebKit's WebSocket client implementation. (Knowledge of C++ is helpful  
but perhaps not essential to understanding this code.) I'm going to  
proceed top-down, from the JavaScript API to the lowest levels of the  
networking.

This directory contains most of the high-level WebSocket code: <http://trac.webkit.org/browser/trunk/WebCore/websockets 
 > Everything relating to the WebSocket API lives here, plus code that  
is not specific to a particular networking back end.

This file is the IDL file (syntax similar but not identical to Web  
IDL) that defines the interface to JavaScript:
<http://trac.webkit.org/browser/trunk/WebCore/websockets/WebSocket.idl>

These files implement the core of the WebSocket API object:
<http://trac.webkit.org/browser/trunk/WebCore/websockets/WebSocket.h>
<http://trac.webkit.org/browser/trunk/WebCore/websockets/WebSocket.cpp>

The IDL file is used to automatically generate JavaScript bindings to  
the core API object. It can also be used to generate bindings for  
other scripting languages.

Notice that none of the actual networking is implemented here. All of  
that is delegated to ThreadableWebSocketChannel:
<http://trac.webkit.org/browser/trunk/WebCore/websockets/ThreadableWebSocketChannel.h 
<http://trac.webkit.org/browser/trunk/WebCore/websockets/ThreadableWebSocketChannel.cpp 

This is an abstract base class for WebSocketChannel, which implements  
WebSocket protocol buffering and message framing:
<http://trac.webkit.org/browser/trunk/WebCore/websockets/WebSocketChannel.h 
<http://trac.webkit.org/browser/trunk/WebCore/websockets/WebSocketChannel.cpp 

(There's a separate concrete subclass which is used for JavaScript  
worker threads, which mostly proxies to the main thread:
<http://trac.webkit.org/browser/trunk/WebCore/websockets/WorkerThreadableWebSocketChannel.h 
 >)
<http://trac.webkit.org/browser/trunk/WebCore/websockets/WorkerThreadableWebSocketChannel.cpp 

WebSocketChannel handles most of the protocol framing, but it  
delegates the handshake to a separate object:
<http://trac.webkit.org/browser/trunk/WebCore/websockets/WebSocketHandshake.h 
<http://trac.webkit.org/browser/trunk/WebCore/websockets/WebSocketHandshake.cpp 

Notice that there's almost no code-sharing between the handshake and  
the HTTP stack. We retrieve cookies from the HTTP stack, but that's  
about it. There's not a lot of code involved in handling the  
handshake, and much of the code in this file is error logging.

None of this code actually talks to the network directly.  
WebSocketChannel delegates that to SocketStreamHandle. Much of the  
implementation of this class is dependent on the specific network back  
end (WebKit tries to use platform HTTP libraries):
<http://trac.webkit.org/browser/trunk/WebCore/platform/network/SocketStreamHandleBase.cpp 
<http://trac.webkit.org/browser/trunk/WebCore/platform/network/SocketStreamHandleBase.h 
<http://trac.webkit.org/browser/trunk/WebCore/platform/network/SocketStreamHandleClient.h 

Here is an example of a specific back end, for the CFNetwork library:
<http://trac.webkit.org/browser/trunk/WebCore/platform/network/cf/SocketStreamHandle.h 
<http://trac.webkit.org/browser/trunk/WebCore/platform/network/cf/SocketStreamHandleCFNet.cpp 

Here we reuse the HTTP stack's ability to establish a TLS/SSL  
connection, connect to SOCKS and HTTPs proxies, and provide HTTP  
authentication credentials.

Regards,
Maciej