1websocket(n)              websocket client and server             websocket(n)


8       websocket - Tcl implementation of the websocket protocol


11       package require Tcl  8.4
13       package require http  2.7
15       package require logger
17       package require sha1
19       package require base64
21       package require websocket  ?1.3.1?
23       ::websocket::open url handler ?options?
25       ::websocket::send sock type ?msg? ?final?
27       ::websocket::server sock
29       ::websocket::live sock path cb ?proto?
31       ::websocket::test srvSock cliSock path ?hdrs? ?qry?
33       ::websocket::upgrade sock
35       ::websocket::takeover sock handler ?server?
37       ::websocket::conninfo sock what
39       ::websocket::find ?host? ?port?
41       ::websocket::configure sock args
43       ::websocket::loglevel ?loglvl?
45       ::websocket::close sock ?code? ?reason?


52       The  websocket  library  is  a pure Tcl implementation of the WebSocket
53       specification covering the needs of both clients and servers.  Websock‐
54       ets  provide  a  way  to upgrade a regular HTTP connection into a long-
55       lived and continuous binary or text communication  between  the  client
56       and  the  server.  The library offers a high-level interface to receive
57       and send data as specified in RFC 6455 (v. 13 of the protocol), reliev‐
58       ing  callers  from  all  necessary protocol framing and reassembly.  It
59       implements the ping facility specified by the standard,  together  with
60       levers  to control it.  Pings are server-driven and ensure the liveness
61       of the connection across home (NAT) networks.  The library has a number
62       of  introspection  facilities to inquire about the current state of the
63       connection, but also to receive notifications  of  incoming  pings,  if
64       necessary.  Finally, the library contains a number of helper procedures
65       to facilitate the upgrading handshaking in existing web servers.
67       Central to the library is the procedure websocket::takeover  that  will
68       take over a regular socket and treat it as a WebSocket, thus performing
69       all necessary protocol framing, packetisation and reassembly in servers
70       and  clients.   The procedure also takes a handler, a command that will
71       be called back each time  a  (possibly  reassembled)  packet  from  the
72       remote  end  is  ready  for  delivery  at  the  original caller.  While
73       exported by the package,  the  command  websocket::takeover  is  seldom
74       called  in applications, since the package provides other commands that
75       are specifically tuned for the needs of clients and servers.
77       Typically, clients will open a connection to a remote server by provid‐
78       ing  a  WebSocket  URL  (ws: or wss: schemes) and the handler described
79       above to the command websocket::open. The opening procedure is a  wrap‐
80       per around the latest http::geturl implementations: it arranges to keep
81       the socket created within the http library opened for reuse,  but  con‐
82       fiscates it from its (internal) map of known sockets for its own use.
84       Servers will start by registering themselves through the command ::web‐
85       socket::server and a number of handlers for  paths  using  the  command
86       ::websocket::live.   Then  for  each  incoming  client connection, they
87       should test the incoming request to detect if it is an upgrade  request
88       using  ::websocket::test  and  perform the final handshake to place the
89       socket connection under the control of the websocket  library  and  its
90       central procedure using ::websocket::upgrade.
92       Apart  from  these main commands, the package provides a number of com‐
93       mands for introspection and basic operations on the websockets that  it
94       has  under its control.  As WebSockets connections are long-lived, most
95       remaining communication with the library will be by way  of  callbacks,
96       i.e.  commands  that are triggered whenever important events within the
97       library have occur, but mostly whenever data has  been  received  on  a
98       WebSocket.


101       A  number  of commands of the library take a handler handler command as
102       an argument, a command which will be  called  back  upon  reception  of
103       data,  but  also  upon  important  events  within the library or events
104       resulting from control messages sent by the remote end.  For each call‐
105       back being performed, the following arguments will be appended:
107       sock   The  identifier  of  the  WebSocket,  as returned for example by
108              ::websocket::open
110       type   A textual type describing the event or message content,  can  be
111              one of the following
113              text   Complete text message
115              binary Complete binary message
117              ping   Incoming ping message
119              connect
120                     Notification of successful connection to server
122              disconnect
123                     Disconnection from remote end
125              close  Pending closure of connection
127       msg    Will contain the data of the message, whenever this is relevant,
128              i.e. when the type is text, binary or ping and whenever there is
129              data available.


132       ::websocket::open url handler ?options?
133              This  command is used in clients to open a WebSocket to a remote
134              websocket-enabled HTTP server.  The URL provided as an  argument
135              in  url  should start with ws: or wss:, which are the WebSockets
136              counterpart of http: and https:. The handler is a  command  that
137              will  be  called  back  on  data reception or whenever important
138              events  occur  during  the  life  of  the   websocket.    ::web‐
139              socket::open will return a socket which serves as both the iden‐
140              tifier of the websocket and of the physical low-level socket  to
141              the  server.   This socket can be used in a number of other com‐
142              mands for introspection or for controlling the behaviour of  the
143              library.   Being essentially a wrapper around the ::http::geturl
144              command, this command provides mostly the same set  of  dash-led
145              options  than  ::http::geturl.  Documented below are the options
146              that differ from ::http::geturl and which are  specific  to  the
147              WebSocket library.
149              -headers
150                     This  option is supported, knowing that a number of head‐
151                     ers will be automatically added internally in the library
152                     in  order  to  be  able to handshake the upgrading of the
153                     socket from a regular HTTP socket to a WebSocket with the
154                     server.
156              -validate
157                     This  option is not supported as it has no real point for
158                     WebSockets.
160              -handler
161                     This option is used internally by the  websocket  library
162                     and cannot be used.
164              -command
165                     This  option  is used internally by the websocket library
166                     and cannot be used.
168              -protocol
169                     This option specifies a list of application protocols  to
170                     handshake with the server.  This protocols might help the
171                     server triggering application specific features.
173              -timeout
174                     This option is supported, but will implemented as part of
175                     the library to enable a number of finalising cleanups.
177       ::websocket::send sock type ?msg? ?final?
178              This  command  will  send a fragment or a control message to the
179              remote end of the WebSocket identified by sock.  The type of the
180              message  specified in type can either be an integer according to
181              the specification or (preferrably) one  of  the  following  case
182              insensitive strings: "text", "binary" or "ping".  The content of
183              the message to send to the remote end is contained  in  msg  and
184              message  fragmentation is made possible by the setting the argu‐
185              ment final to non-true, knowing that the type of  each  fragment
186              has  then  to  be  the  same.  The command returns the number of
187              bytes that were effectively sent,  or  -1  on  errors.   Serious
188              errors, such as when sock does not identify a known WebSocket or
189              when the connection is not stable yet will generate errors  that
190              must be catched.
192       ::websocket::server sock
193              This  command  registers the (accept) socket sock as the identi‐
194              fier fo an HTTP server that  is  capable  of  doing  WebSockets.
195              Paths  onto  which  this server will listen for incoming connec‐
196              tions should be declared using ::websocket::live.
198       ::websocket::live sock path cb ?proto?
199              This procedure registers callbacks that will be performed  on  a
200              WebSocket  compliant server registered with ::websocket::server]
201              whenever a client connects to  a  matching  path  and  protocol.
202              sock  is  the listening socket of the websocket compliant server
203              declared using ::websocket::server.  path is a  glob-style  path
204              to match in client request, whenever this will occur.  cb is the
205              command to callback (see Callbacks).  proto is a glob-style pro‐
206              tocol name matcher.
208       ::websocket::test srvSock cliSock path ?hdrs? ?qry?
209              This  procedure  will  test  if  the connection from an incoming
210              client on socket cliSock and on the path path is the opening  of
211              a  WebSocket stream within a known server srvSock.  The incoming
212              request is not upgraded at once, instead a  (temporary)  context
213              for the incoming connection is created.  This allows server code
214              to perform a number of actions, if necessary,  before  the  Web‐
215              Socket  stream  connection  goes  live.   The  text  is  made by
216              analysing the content of the headers hdrs which should contain a
217              dictionary  list of the HTTP headers of the incoming client con‐
218              nection.  The command will return 1 if this is an incoming  Web‐
219              Socket upgrade request and 0 otherwise.
221       ::websocket::upgrade sock
222              Upgrade   the  socket  sock  that  had  been  deemed  by  ::web‐
223              socket::test to be a WebSocket connection request to a true Web‐
224              Socket as recognised by this library. As a result, the necessary
225              connection handshake will be sent to the client, and the command
226              will  arrange  for relevant callbacks to be made during the life
227              of the WebSocket, notably using the specifications described  by
228              ::websocket::live.
230       ::websocket::takeover sock handler ?server?
231              Take  over  the existing opened socket sock to implement sending
232              and receiving WebSocket framing on top of the socket.  The  pro‐
233              cedure arranges for handler to be called back whenever messages,
234              control messages or other important internal events are received
235              or  occured.   server  defaults  to  0 and can be set to 1 (or a
236              boolean that evaluates to true) to specify that this is  a  Web‐
237              Socket  within a server.  Apart from specificities in the proto‐
238              col, servers should ping their clients at regular  intervals  in
239              order to keep the connection opened at all time.  When server is
240              set to true, the library will arrange to send these pings  auto‐
241              matically.
243       ::websocket::conninfo sock what
244              Provides  callers with some introspection facilities in order to
245              get some semi-internal information about an  existing  websocket
246              connection.  Depending  on  the  value of the what argument, the
247              procedure returns the following piece of information:
249              peername
250                     Name (preferred) or IP of remote end.
252              sockname
253                     or name Name or IP of local end.
255              closed 1 if the connection is closed, 0 otherwise
257              client 1 if the connection is a client websocket, 0 otherwise
259              server 1 if the connection is a server websocket, 0 otherwise
261              type   server if the connection is a  server  websocket,  client
262                     otherwise.
264              handler
265                     The handler command associated to the websocket
267              state  The state of the websocket, which can be one of:
269                     CONNECTING
270                            Connection to remote end is in progress.
272                     CONNECTED
273                            Connection is connected to remote end.
275                     CLOSED Connection is closed.
277       ::websocket::find ?host? ?port?
278              Look  among  existing  websocket  connections  for the ones that
279              match the hostname and port number filters passed as parameters.
280              This lookup takes the remote end into account and the host argu‐
281              ment is matched both against the hostname  (whenever  available)
282              and  the  IP  address of the remote end.  Both the host and port
283              arguments are glob-style string matching filters and default  to
284              *, i.e. will match any host and/or port number.
286       ::websocket::configure sock args
287              This  command takes a number of dash-led options (and their val‐
288              ues) to configure the behaviour of an existing websocket connec‐
289              tion.   The  recognised  options  are the following (they can be
290              shortened to the lowest common denominator):
292              -keepalive
293                     is the number of seconds  between  each  keepalive  pings
294                     being sent along the connection.  A zero or negative num‐
295                     ber will effectively turn off the feature.   In  servers,
296                     -keepalive  defaults  to  30  seconds, and in clients, no
297                     pings are initiated.
299              -ping  is the text that is  used  during  the  automated  pings.
300                     This  text  defaults  to  the empty string, leading to an
301                     empty ping.
303       ::websocket::loglevel ?loglvl?
304              Set or query the log level of the  library,  which  defaults  to
305              error.   Logging  is  built on top of the logger module, and the
306              library makes use of the following levels: debug, info,  notice,
307              warn  and  error.   When called with no argument, this procedure
308              will simply return the  current  log  level.   Otherwise  loglvl
309              should contain the desired log level.
311       ::websocket::close sock ?code? ?reason?
312              Gracefully  close  a  websocket  that was directly or indirectly
313              passed to ::websocket::takeover.  The procedure will  optionally
314              send the code and describing reason as part of the closure hand‐
315              shake.  Good defaults are provided, so that reasons for a number
316              of  known codes will be sent back. Only the first 125 characters
317              of a reason string will be kept and sent as part  of  the  hand‐
318              shake. The known codes are:
320              1000   Normal closure (the default code when none provided).
322              1001   Endpoint going away
324              1002   Protocol Error
326              1003   Received incompatible data type
328              1006   Abnormal closure
330              1007   Received data not consistent with type
332              1008   Policy violation
334              1009   Received message too big
336              1010   Missing extension
338              1011   Unexpected condition
340              1015   TLS handshake error


343       The following example opens a websocket connection to the echo service,
344       waits 400ms to ensure that the connection  is  really  established  and
345       sends  a single textual message which should be echoed back by the echo
346       service.  A real example would probably use  the  connect  callback  to
347       know  when connection to the remote server has been establish and would
348       only send data at that time.
351              package require websocket
352              ::websocket::loglevel debug
354              proc handler { sock type msg } {
355                  switch -glob -nocase -- $type {
356                co* {
357                    puts "Connected on $sock"
358                }
359                te* {
360                    puts "RECEIVED: $msg"
361                }
362                cl* -
363                dis* {
364                }
365                  }
367              }
369              proc test { sock } {
370                  puts "[::websocket::conninfo $sock type] from [::websocket::conninfo $sock sockname] to [::websocket::conninfo $sock peername]"
372                  ::websocket::send $sock text "Testing, testing..."
373              }
375              set sock [::websocket::open ws://echo.websocket.org/ handler]
376              after 400 test $sock
377              vwait forever


381       This package uses the TLS package to handle the security for https urls
382       and other socket connections.
384       Policy  decisions like the set of protocols to support and what ciphers
385       to use are not the responsibility of TLS, nor of  this  package  itself
386       however.   Such  decisions are the responsibility of whichever applica‐
387       tion is using the package, and are likely  influenced  by  the  set  of
388       servers the application will talk to as well.
390       For  example,  in light of the recent POODLE attack [http://googleonli
391       nesecurity.blogspot.co.uk/2014/10/this-poodle-bites-exploiting-
392       ssl-30.html] discovered by Google many servers will disable support for
393       the SSLv3 protocol.  To handle this change the applications  using  TLS
394       must  be  patched,  and not this package, nor TLS itself.  Such a patch
395       may be as simple as generally activating tls1 support, as shown in  the
396       example below.
399                  package require tls
400                  tls::init -tls1 1 ;# forcibly activate support for the TLS1 protocol
402                  ... your own application code ...


406       This  document,  and the package it describes, will undoubtedly contain
407       bugs and other problems.  Please report such in the category  websocket
408       of  the Tcllib Trackers [http://core.tcl.tk/tcllib/reportlist].  Please
409       also report any ideas for enhancements you may have for either  package
410       and/or documentation.
412       When proposing code changes, please provide unified diffs, i.e the out‐
413       put of diff -u.
415       Note further that  attachments  are  strongly  preferred  over  inlined
416       patches.  Attachments  can  be  made  by  going to the Edit form of the
417       ticket immediately after its creation, and  then  using  the  left-most
418       button in the secondary navigation bar.


421       http


424       http, internet, net, rfc 6455


427       Networking
431tcllib                               1.3.1                        websocket(n)