Changes

Jump to navigation Jump to search
2,546 bytes added ,  17:06, 31 October 2018
no edit summary
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: Data can be sent in both directions and simultaneously.
 
Please note that the current WebSocket implementation relies on Jetty’s WebSocket servlet API. Other web servers may be supported in future versions.
=Introduction=
=Annotations=
To tag functions as WebSocket functions you have to use [[XQuery 3.0#Annotations|annotations]]. The annotation is written after the keyword ''declare'' and before the keyword ''function''. For the context of WebSockets there are some annotations listed below. Functions which are annotated with a WebSocket annotation will be called if the appropriate event occurs. For example, the function annotated with <code>ws:connect('/')</code> will be executed if a client establishes a connection with the WebSocket root path (which is, by default, <code>ws/</code>). By using annotations, it’s easy to provide an API for your WebSocket connection. You just have to specify what to do when a WebSocket Event occurs, annotate it with the corresponding annotation and the Servlet will do the rest for you.
==%ws:connect(path)==
Called directly after a successful WebSocket handshake. The <code>path</code> specifies the path which a client is connected to. :You can specify here how to handle your users, f.e. save a name as a WebSocket attribute. Furthermore, you can check here some of the header-params for validity. <pre class="brush:xquery">declare %ws:connect('/') function local:connect() { };</pre>
==ws:message(pathYou can specify here how to handle your users,message)==e. g. save a name as a WebSocket attribute. Furthermore, you can check header parameters for validity.
Called when a <code>==%ws:message</code> arrives at the server. The <code>(path</code> specifies the path 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. It should be ensured that the format of the , message is correct. )==
Called when a client message arrives at the server. The <code>path</code> specifies the path which a client is connected to. The <code>message</code> string contains the name of the variable to which the message will be bound: <pre class="brush:xquery">declare %ws:message('/', '{$info}') function local:message($info) { };</pre> The value will be of type <code>xs:string</code> or <code>xs:base64Binary</code>. As there is no fixed message protocol, the client needs to take care of the message syntax. ==%ws:error(path, message)== Called when an error occurs. The <code>path</code> specifies the path which a client is connected to. The <code>message</code> string contains the name of the variable to which the message will be bound: <pre class="brush:xquery">declare %ws:error('/', '{$error}') function local:error($error) { };</pre> Usually, errors happen because of bad/malformed incoming packets. The WebSocket connection gets closed after the error handling. ==%ws:close(path)== Called when the WebSocket closes. The <code>path</code> specifies the path which a client is connected to: <pre class="brush:xquery">declare %ws:close('/') function local:connect() { };</pre>
Called when the WebSocket closes. The <code>path</code> specifies the path which a client is connected to.
The WebSocket is already closed when this annotation is called so there can be no return.
==%ws:errorheader-param(pathname, messagevariable[, default])==
Called when an error has occurred. Usually, this happens because of bad/malformed incoming packetsFor accessing connection-specific properties like the HTTP version. The value will be bound to the specified <code>pathvariable</code> specifies . If the path which a client is connected to. The property has no value, an optional <code>messagedefault</code> is the error message. The WebSocket connection gets closed after the error handling.value will be assigned instead:
<pre class=="brush:xquery">declare %ws:close('host', '{$host}') %ws:header-param(name'host',variable'{$host}')function local:close($host) { admin:write-log('Connection was closed: ' || $host)};</pre> The following parameters are available: {| class="wikitable" |- valign="top"! Name! Description|- valign="top"| <code>host</code>| The host of the request URI.|- valign="top"| <code>http-version</code>| The HTTP version used for the request.|- valign="top"| <code>is-secure</code>| Indicates if the connection is secure.|- valign="top"| <code>origin</code>| The WebSocket origin.|- valign="top"| <code>protocol-version</code>| The version of the used protocol.|- valign="top"| <code>query-string</code>| The query string of the request URI.|- valign="top"| <code>request-uri</code>| The Request URI to use for this request.|- valign="top"| <code>sub-protocols</code>| List of configured sub-protocols.|} General information on the request can be retrieved via the [,default[Request Module]]). =Writing ApplicationsThe [[WebSocket Module]] contains functions for interacting with other clients or manage specific clients. For example, you can store and access client-specific properties for a WebSocket connection or close the connection of clients. Note that one WebSocket connection can be opened per browser tab. In contrast, only one HTTP session exists for multiple tabs in in a browser. If you want to keep client-specific data on the web server, you can either store them in HTTP sessions or in the WebSocket connection. Note further that the results of functions annotated with <code>%ws:close</code> or <code>%ws:error</code> will not be transmitted to the client. Both annotations have rather been designed to gracefully close connections, write log data, remove clients from session data, etc. For keeping the connection alive it is recommendable to use heart-beats, and send regular pings to the server. There is no ideal timespan for sending pings: It should not be sent too often, but you should also consider possible network latencies. If your HTTP connection is secure, you should use the <code>wss</code> instead of the <code>ws</code> scheme.
For accessing specific parameters like If you get the Http<code>[basex:ws] WebSocket connection required</code> error, you may be attempting to call WebSocket functions from a non-Version or WebSocket context. If you use a proxy server, check in the Sec-WebSocket-Versionconfiguration if WebSockets are enabled.
=Examples==Parameters===The following list shows the parameters of a WebSocket. You can access the parameters via the annotation <code>%ws:header-param(name,variable[,default])</code>* Http-Version -> f.e.: <code>%ws:param("Http-Version", "{$version}")</code>* Origin* Protocol-Version* QueryString* IsSecure* RequestURI* Host* Sec-WebSocket-Version* offset -> just for binary-Messages* len -> just for binary-Messages
=Tipps=Basic Example==
* For interacting The following chapter explains how to create a simple basic web application with other clients or manage specific clients you should check out the [[WebSocket Module]] as wellWebSockets.* The results of functions annotated with <code>%ws:close</code> or <code>%ws:error</code> will not be transmitted to You can find another example in the client* For keeping the connection alive it is possible to implement heart-beats * Use <BaseX source code>wss</code> instead of <code>ws</code> for a secure WebSocket connection* If you use a proxy server, check its configuration if WebSocket support is enabled.
=Example=The following chapter explains how to create a simple basic webapplication with websockets. You can find another example in the BaseX source code. First of all , you have to ensure that the <code>WsServlet </code> is enabled in your <code>web.xml</code>file. It will be enabled if you use the standard <code>web.xml</code>configuration of BaseX.
For establishing a connection to the WebSocket server , it is necessary that the server provides at least one function annotated with a WebSocket annotation. Lets Let’s start by using the annotation <code>%ws:connect('/')</code>.In the connect function, specific WebSocket a bidirectional communication with the client can be initialized: attributes like such as the id and nameof a client can be set, emit or a welcome message can be emitted to other connected users, write database entries, do nothing, ... can be setand so on.
<pre class="brush:xquery">
%ws:connect('/')
function example:connect() as empty-sequence() {
()
};
</pre>
With The connect function is sufficient for creating the state until now you can create a connection between persistent client and /serverconnection. For doing sth. senseful In order to something sensible with the WebSocket connection , you should implement a function annotated with <code>%ws:message("/")</code>.: 
<pre class="brush:xquery">
import module namespace ws = 'http://basex.org/modules/ws'
 
declare
%ws:message('/', '{$message}')
function example:message(
$message as xs:string
) as empty-sequence() {
ws:emit($message)
};
</pre>
In the function above the WebSocketModule function <code>emit</code> is used for forwarding the message to all connected clients. Notice that you have to import the [[WebSocket Module]] before using it.
With In the code function above it , the [[WebSocket Module]] is possible to implement client-side functionality to connect to a WebSocket imported, and sendthe function <code>ws:emit</receive messages via code> is used for forwarding the WebSocketmessage to all connected clients.Following The following client-side code shows demonstrates a basic usage application of the WebSocket connection: <pre class="brush:java">var ws = new WebSocket("ws://localhost:8984/ws");
<pre>
var ws = new WebSocket("wss://localhost:8984/ws");
ws.onmessage = function(event) {
alert(event.data);
</pre>
The <code>send</code> function can be called to pass on a string to the server. There are no heartbeats heart-beats in this example. This means that the connection is terminated if nothing happens for 5 minutes (standard timeout).If It will also be closed if you send a message which that exceeds the textsize standard text size. ==Chat Application== In the full distributions of 3kb defined BaseX, you will find a little self-contained chat application that demonstrates how WebSockets can be used in the <code>webpractice. =Changelog= WebSockets werre introduced with Version 9.xml</code> the connection gets closed too1.
Bureaucrats, editor, reviewer, Administrators
13,551

edits

Navigation menu