WebSockets

From BaseX Documentation
Revision as of 16:31, 31 August 2018 by CG (talk | contribs)
Jump to navigation Jump to search

This page presents one of the Web Application services. It describes how to use the WebSockets API of BaseX. WebSocket is a communication protocol for providing full-duplex communication.

The WebSocket protocol was standardized in RFC 6455 by the IETF. After an initial HTTP-request, all communication takes place over a single TCP connection. In contrast to the HTTP protocol, a connection will be kept alive, and a server can send unsolicited data to the client.

For establishing a WebSocket connection, a handshake request is sent by the client. The web server returns a handshake response. If the handshake is successful, the persistent connection will be open until an the client or the server closes it, an error occurs or a timeout happens. The timeout can be specified in the web.xml configuration file. It is possible to transmit all kind of data, binary or text.

Introduction

Preliminaries

There are a bunch of annotations depending to WebSockets for annotating XQuery functions. When a WebSocket message arrives at the server, an XQuery function will be invoked that matches the constraints indicated by its annotations.

If a WebSocket function is requested (like connecting to the path '/', message to the path '/path', ...), the module directory and its sub-directories will be traversed, and all XQuery files will be parsed for functions with WebSocket annotations. Sub-directories that include an .ignore the file will be skipped.

To speed up processing, the functions of the existing XQuery modules are automatically cached in main memory:

  • Functions will be invalidated and parsed again if the timestamp of their module changes.

Examples

module namespace page = 'http://basex.org/modules/web-page';

import module namespace ws = "http://basex.org/modules/Websocket";

declare
%ws:connect("/")
function page:connect(
) {
  (: Do something after a client connects to the path "/" :)
};

declare
  %ws:message("/","{$message}")
function page:message(
  $message as xs:string
) {
  (: Do something if a message arrives at the server :)
};

declare 
  %ws:close("/")
function chat:close() {
  (: Return a close message with the id of the client who closes the connection :)
  let $client-id := ws:id()
  let $msg := json:serialize(
    <json type="object">
      <type>WebsocketClosed</type>
      <idThatClosed>{$client-id}</idThatClosed>
    </json>
  )
  (: Broadcast the message to all connected users except the client who closes the connection :)
  return ws:broadcast($msg)
};

Usage

  • Enable the WebSocket servlet in the web.xml. You can set here the maxIdleTime, maxTextMessageSize and maxBinaryMessageSize too.
  • If you get a message that exceeds the maxTextMessageSize/maxBinaryMessageSize or, if not set, the default messageSize of Jetty of 65 536 bytes (64 kB) then the connection will close. In this case, the ws:error annotation will be called.
<servlet>
  <servlet-name>wsservlet</servlet-name>
  <servlet-class>org.basex.http.ws.WsServlet</servlet-class>
  <init-param>
    <param-name>maxIdleTime</param-name>
    <param-value>100000</param-value>
  </init-param>
  <init-param>
    <param-name>maxTextMessageSize</param-name>
    <param-value>3000</param-value>
  </init-param>
</servlet>
<servlet-mapping>
  <servlet-name>wsservlet</servlet-name>
  <url-pattern>/ws/*</url-pattern>
</servlet-mapping>
  • Annotate your specific XQuery-Functions with WebSocketAnnotations.

Annotations

ws:connect(path)

Called directly after a successful WebSocket handshake. The path specifies the path to which a client is connected to.

ws:message(path,message)

Called when a message arrives at the server. The path specifies the path to which a client is connected to. The message is the message sent by the client. Could be a text-message or a binary-message.

ws:close(path)

Called when the WebSocket closes. The path specifies the path to which a client is connected to. The WebSocket is already closed when this annotation is called so there can be no return.

ws:error(path, message)

Called when an error has occurred. Usually, this happens because of bad/malformed incoming packets. The path specifies the path to which a client is connected to. The message is the error message. The WebSocket connection gets closed after the error handling.

ws:header-param(name,variable[,default]

For accessing specific parameters like the Http-Version or the Sec-WebSocket-Version.

Parameters

  • Http-Version -> f.e.: ```%ws:param("Http-Version", "{$version}")```
  • Origin
  • Protocol-Version
  • QueryString
  • IsSecure
  • RequestURI
  • Host
  • Sec-WebSocket-Version
  • offset -> just for binary-Messages
  • len -> just for binary-Messages

Tipps

  • For interacting with other clients or manage specific clients you should check out the WebSocket Module as well.