Tcl Library Source Code

Bounty program for improvements to Tcl and certain Tcl packages.

[ Main Table Of Contents | Table Of Contents | Keyword Index | Categories | Modules | Applications ]


websocket - Tcl implementation of the websocket protocol

Table Of Contents


package require Tcl 8.4
package require http 2.7
package require logger
package require sha1
package require base64
package require websocket ?1.3.1?

::websocket::open url handler ?options?
::websocket::send sock type ?msg? ?final?
::websocket::server sock
::websocket::live sock path cb ?proto?
::websocket::test srvSock cliSock path ?hdrs? ?qry?
::websocket::upgrade sock
::websocket::takeover sock handler ?server?
::websocket::conninfo sock what
::websocket::find ?host? ?port?
::websocket::configure sock args
::websocket::loglevel ?loglvl?
::websocket::close sock ?code? ?reason?



The websocket library is a pure Tcl implementation of the WebSocket specification covering the needs of both clients and servers. Websockets provide a way to upgrade a regular HTTP connection into a long-lived and continuous binary or text communication between the client and the server. The library offers a high-level interface to receive and send data as specified in RFC 6455 (v. 13 of the protocol), relieving callers from all necessary protocol framing and reassembly. It implements the ping facility specified by the standard, together with levers to control it. Pings are server-driven and ensure the liveness of the connection across home (NAT) networks. The library has a number of introspection facilities to inquire about the current state of the connection, but also to receive notifications of incoming pings, if necessary. Finally, the library contains a number of helper procedures to facilitate the upgrading handshaking in existing web servers.

Central to the library is the procedure websocket::takeover that will take over a regular socket and treat it as a WebSocket, thus performing all necessary protocol framing, packetisation and reassembly in servers and clients. The procedure also takes a handler, a command that will be called back each time a (possibly reassembled) packet from the remote end is ready for delivery at the original caller. While exported by the package, the command websocket::takeover is seldom called in applications, since the package provides other commands that are specifically tuned for the needs of clients and servers.

Typically, clients will open a connection to a remote server by providing a WebSocket URL (ws: or wss: schemes) and the handler described above to the command websocket::open. The opening procedure is a wrapper around the latest http::geturl implementations: it arranges to keep the socket created within the http library opened for reuse, but confiscates it from its (internal) map of known sockets for its own use.

Servers will start by registering themselves through the command ::websocket::server and a number of handlers for paths using the command ::websocket::live. Then for each incoming client connection, they should test the incoming request to detect if it is an upgrade request using ::websocket::test and perform the final handshake to place the socket connection under the control of the websocket library and its central procedure using ::websocket::upgrade.

Apart from these main commands, the package provides a number of commands for introspection and basic operations on the websockets that it has under its control. As WebSockets connections are long-lived, most remaining communication with the library will be by way of callbacks, i.e. commands that are triggered whenever important events within the library have occur, but mostly whenever data has been received on a WebSocket.


A number of commands of the library take a handler handler command as an argument, a command which will be called back upon reception of data, but also upon important events within the library or events resulting from control messages sent by the remote end. For each callback being performed, the following arguments will be appended:



The following example opens a websocket connection to the echo service, waits 400ms to ensure that the connection is really established and sends a single textual message which should be echoed back by the echo service. A real example would probably use the connect callback to know when connection to the remote server has been establish and would only send data at that time.

package require websocket
::websocket::loglevel debug

proc handler { sock type msg } {
    switch -glob -nocase -- $type {
	co* {
	    puts "Connected on $sock"
	te* {
	    puts "RECEIVED: $msg"
	cl* -
	dis* {


proc test { sock } {
    puts "[::websocket::conninfo $sock type] from [::websocket::conninfo $sock sockname] to [::websocket::conninfo $sock peername]"

    ::websocket::send $sock text "Testing, testing..."

set sock [::websocket::open ws:// handler]
after 400 test $sock
vwait forever

TLS Security Considerations

This package uses the TLS package to handle the security for https urls and other socket connections.

Policy decisions like the set of protocols to support and what ciphers to use are not the responsibility of TLS, nor of this package itself however. Such decisions are the responsibility of whichever application is using the package, and are likely influenced by the set of servers the application will talk to as well.

For example, in light of the recent POODLE attack discovered by Google many servers will disable support for the SSLv3 protocol. To handle this change the applications using TLS must be patched, and not this package, nor TLS itself. Such a patch may be as simple as generally activating tls1 support, as shown in the example below.

package require tls
tls::init -tls1 1 ;# forcibly activate support for the TLS1 protocol

... your own application code ...

Bugs, Ideas, Feedback

This document, and the package it describes, will undoubtedly contain bugs and other problems. Please report such in the category websocket of the Tcllib Trackers. Please also report any ideas for enhancements you may have for either package and/or documentation.

When proposing code changes, please provide unified diffs, i.e the output of diff -u.

Note further that attachments are strongly preferred over inlined patches. Attachments can be made by going to the Edit form of the ticket immediately after its creation, and then using the left-most button in the secondary navigation bar.




http, internet, net, rfc 6455