Difference between revisions of "WebSockets"
Line 1: | Line 1: | ||
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. | 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. | ||
− | After an initial HTTP-request | + | The WebSocket protocol was standardized in [https://tools.ietf.org/html/rfc6455 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 <code>web.xml</code> configuration file. It is possible to transmit all kind of data, binary or text. | |
− | |||
− | |||
=Introduction= | =Introduction= | ||
Line 16: | Line 14: | ||
To speed up processing, the functions of the existing XQuery modules are automatically cached in main memory: | 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. | * Functions will be invalidated and parsed again if the timestamp of their module changes. | ||
Line 22: | Line 21: | ||
<pre class="brush:xquery"> | <pre class="brush:xquery"> | ||
module namespace page = 'http://basex.org/modules/web-page'; | module namespace page = 'http://basex.org/modules/web-page'; | ||
+ | |||
+ | import module namespace ws = "http://basex.org/modules/Websocket"; | ||
+ | |||
declare | declare | ||
%ws:connect("/") | %ws:connect("/") | ||
− | function | + | function page:connect( |
) { | ) { | ||
(: Do something after a client connects to the path "/" :) | (: Do something after a client connects to the path "/" :) | ||
}; | }; | ||
− | |||
− | |||
− | |||
declare | declare | ||
%ws:message("/","{$message}") | %ws:message("/","{$message}") | ||
− | function | + | function page:message( |
$message as xs:string | $message as xs:string | ||
) { | ) { | ||
(: Do something if a message arrives at the server :) | (: Do something if a message arrives at the server :) | ||
}; | }; | ||
− | |||
− | |||
− | |||
− | |||
− | |||
declare | declare | ||
%ws:close("/") | %ws:close("/") | ||
function chat: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) | |
− | + | }; | |
</pre> | </pre> | ||
Line 65: | Line 59: | ||
* Enable the WebSocket servlet in the web.xml. You can set here the maxIdleTime, maxTextMessageSize and maxBinaryMessageSize too. | * 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. | * 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. | ||
+ | |||
<pre class="brush:xml"> | <pre class="brush:xml"> | ||
<servlet> | <servlet> | ||
Line 89: | Line 84: | ||
==ws:connect(path)== | ==ws:connect(path)== | ||
− | Called | + | Called directly after a successful WebSocket handshake. The <code>path</code> specifies the path to which a client is connected to. |
==ws:message(path,message)== | ==ws:message(path,message)== | ||
− | Called when a <code>message</code> arrives at the server. The <code>path</code> specifies the | + | Called when a <code>message</code> arrives at the server. The <code>path</code> specifies the path to which a client is connected to. The <code>message</code> is the <code>message</code> sent by the client. Could be a text-message or a binary-message. |
==ws:close(path)== | ==ws:close(path)== | ||
− | Called when the WebSocket closes. The <code>path</code> specifies the | + | Called when the WebSocket closes. The <code>path</code> 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. | The WebSocket is already closed when this annotation is called so there can be no return. | ||
− | ==ws:error(path,message) | + | ==ws:error(path, message)== |
− | |||
− | |||
− | |||
− | |||
− | The | + | Called when an error has occurred. Usually, this happens because of bad/malformed incoming packets. The <code>path</code> specifies the path to which a client is connected to. The <code>message</code> is the error message. The WebSocket connection gets closed after the error handling. |
==ws:header-param(name,variable[,default]== | ==ws:header-param(name,variable[,default]== |
Revision as of 16:31, 31 August 2018
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.
Contents
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.