Changes

Jump to navigation Jump to search
1,990 bytes added ,  11:54, 27 July 2020
m
Text replacement - "==%" to "=="
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.: <syntaxhighlight lang="xquery">declare %ws:connect('/') function local:connect() { };</syntaxhighlight>
You can specify here how to handle your users, e. g. save a name as a WebSocket attribute. Furthermore, you can check header parameters for validity.
==%ws:message(path, message)==
Called when a <code>client message</code> 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:
The <codesyntaxhighlight lang="xquery">declare %ws:message<('/code> is the <code>', '{$info}') function local:message($info) { };</codesyntaxhighlight> sent by the client. It will be of type <code>xs:string</code> or <code>xs:base64Binary</code>. The client needs to take care of the message syntax, and it must not exceed the configured maximum size.
==%wsThe value will be of type <code>xs:close(path)==string</code> or <code>xs:base64Binary</code>. As there is no fixed message protocol, the client needs to take care of the message syntax.
Called when the WebSocket closes. The <code>==ws:error(path</code> specifies the path which a client is connected to., 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: <syntaxhighlight lang="xquery">declare %ws:error('/', '{$error}') function local:error($error) { };</syntaxhighlight> Usually, errors happen because of bad/malformed incoming packets. The WebSocket is already connection gets closed after the error handling. ==ws:close(path)== Called when this annotation the WebSocket closes. The <code>path</code> specifies the path which a client is called so there can be no return. connected to:
<syntaxhighlight lang=="xquery">declare %ws:errorclose('/') function local:connect(path, message)=={ };</syntaxhighlight>
Called The WebSocket is already closed when an error occurs. The <code>path</code> specifies the path which a client this annotation is connected tocalled so there can be no return.
Usually==ws:header-param(name, errors happen because of bad/malformed incoming packets. The <code>message</code> is the error message. The WebSocket connection gets closed after the error handling.variable[, default])==
==%ws:headerFor accessing connection-param(name, specific properties like the HTTP version. The value will be bound to the specified <code>variable[</code>. If the property has no value, an optional <code>default])==</code> value will be assigned instead:
For accessing connection-specific properties like the HTTP version. The value will be bound to the specified <codesyntaxhighlight lang="xquery">variable</code>. If no value is availabledeclare %ws:close('host', '{$host}') %ws:header-param('host', an optional <code>default'{$host}')function local:close($host) { admin:write-log('Connection was closed: ' || $host)};</codesyntaxhighlight> value will be bound instead.
The following parameters are available:
! 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>
|- valign="top"
| <code>protocol-version</code>
| The version of the used protocol (max. 1.3).
|- valign="top"
| <code>query-string</code>
| The query string of the request URI.
|- valign="top"
| <code>isrequest-secure</code>| Indicates if the connection is secure.|- valign="top"| <code>is-secureuri</code>
| The Request URI to use for this request.
|- valign="top"
| <code>hostsub-protocols</code>| The host List of the request URI.|- valign="top"| <code>sec-websocketconfigured sub-version</code>| The websocket versionprotocols.
|}
General information on the request can be retrieved via the [[Request Module]]. =TippsWriting 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. If you get the <code>[basex:ws] WebSocket connection required</code> error, you may be attempting to call WebSocket functions from a non-WebSocket context. If you use a proxy server, check in the configuration if WebSockets are enabled.
* The [[WebSocket Module]] contains functions for interacting with other clients or manage specific clients.* The results of functions annotated with <code>%ws:close</code> or <code>%ws:error</code> will not be transmitted to the client.* For keeping the connection alive it is recommendable to use heart-beats, and send regular pings to the server.* Use <code>wss</code> instead of <code>ws</code> for a secure WebSocket connection.* If you use a proxy server, check in the configuration if WebSockets are enabled.=Examples=
==Basic Example==
The following chapter explains how to create a simple basic web application with WebSockets. You can find another example in the BaseX source code.
For establishing a connection to the WebSocket server, it is necessary that the server provides at least one function annotated with a WebSocket annotation. Let’s start by using the annotation <code>%ws:connect('/')</code>. In the connect function, a bidirectional communication with the client can be initialized: attributes such as the id and name of a client can be set, or a welcome message can be emitted to other connected users, and so on.
<pre classsyntaxhighlight lang="brush:xquery">
declare
%ws:connect('/')
function example:connect() as empty-sequence() {
};
</presyntaxhighlight>
The connect function is sufficient for creating the persistent client/server connection. In order to something sensible with the connection, you should implement a function annotated with <code>%ws:message("/")</code>:
<pre classsyntaxhighlight lang="brush:xquery">
import module namespace ws = 'http://basex.org/modules/ws'
ws:emit($message)
};
</presyntaxhighlight>
In the function above, the [[WebSocket Module]] is imported, and the function <code>ws:emit</code> is used for forwarding the message to all connected clients.
The following client-side code demonstrates a basic application of the WebSocket connection:
<pre classsyntaxhighlight lang="brush:javajavascript">
var ws = new WebSocket("ws://localhost:8984/ws");
ws.send(message);
};
</presyntaxhighlightThe <code>send</code> function can be called to pass on a string to the server. There are no heart-beats in this example. This means that the connection is terminated if nothing happens for 5 minutes (standard timeout). It will also be closed if you send a message that exceeds the standard text size. ==Chat Application== In the full distributions of BaseX, you will find a little self-contained chat application that demonstrates how WebSockets can be used in practice.
The <code>send</code> function can be called to pass on a string (e. g. a chat message) to the server.=Changelog=
There are no heartbeats in this exampleWebSockets werre introduced with Version 9. This means that the connection is terminated if nothing happens for 5 minutes (standard timeout). It will also be closed if you send a message that exceeds the standard text size1.
Bureaucrats, editor, reviewer, Administrators
13,550

edits

Navigation menu