jWebSocket REST API

jWebSocket REST API (v1.0)

The jWebSocket REST API offers a traditional HTTP Request/Response communication mechanism to interact with the jWebSocket server runtime services. However, since the jWebSocket server is highly asynchronous and designed for permanent and bi-directional client connections, server events or streaming messages require to be received by using the client command “sync” (described above).

The jWebSocket REST API provides a cluster designed solution that allow developers to connect multiple jWebSocket servers in parallel. However it requires a top level HTTP load balancer to balance the HTTP requests across all active servers.

The Tomcat based REST API implementation:

Since Tomcat is a proved and robust web server, compliant with the Java Servlet Specification, the jWebSocket team decided to implement the REST communication API on top of it.

Configuring the TomcatHTTPEngine for REST support:

<!-- Tomcat HTTP Engine configuration -->
<engine>
  <name>org.jwebsocket.tomcat.http.TomcatHTTPEngine</name>
  <id>http0</id>
  <!-- Use "jWebSocketTomcatEngine-embedded-1.0.jar" for Tomcat embedded mode -->
  <jar>jWebSocketTomcatEngine-embedded-1.0.jar</jar>
  <!-- Use "jWebSocketTomcatEngine-1.0.jar" for Tomcat web app mode 
  <jar>jWebSocketTomcatEngine-1.0.jar</jar>
  -->
  <!-- keystore file with in ${JWEBSOCKET_HOME}conf -->
  <keystore>${JWEBSOCKET_HOME}conf/jWebSocket.ks</keystore>
  <!-- password to access keystore file -->
  <password>jWebSocket</password>
  <!-- The jWebSocket TomcatEngine can either work in embedded mode 
  	or in standard web app mode. In standard wep app mode the 
	jWebSocket Tomcat engine listens on same port like
	Tomcats's http. The http protocol is upgraded to use WebSockets.
	The http/websocket port can be configured via the Tomcat
	configuration in the server.xml configuration file.
  -->
  <!-- set both port settings to "0" (null) if running Tomcat
	Servlet Container for Web Apps and embed jWebSocket library.
	This uses the settings from server.xml, wraps the existing
	Tomcat WebSocket servlet and does NOT instantiate a separate
	embedded engine at run time within jWebSocket.
  -->
  <!--
  <port>0</port>
  <sslport>0</sslport>
  -->
  <!-- use 80/443 for default http/ws or https/wss connections
  	when running a jWebSocket Server and use Tomcat as an embedded 
	engine. These settings are recommended only when running 
	jWebSocket on a SEPARATE server beside a WebServer and the 
	firewall does not allow access to ports 8787 and 9797.
  -->
  <!--
  <port>80</port>
  <sslport>443</sslport>
  -->
  <!-- use 8787/9797 for default http/ws or https/wss connections
	These settings are recommended only when running jWebSocket
	on the same server beside a Tomcat WebServer and the firewall
	grants access to ports 8787 and 9797.
  -->
  <port>8787</port>
  <sslport>9797</sslport>
  <!-- these domains are accepted by the engine listening
	on the above mentioned port -->
  <domains>
    <domain>*</domain>
    <!-- limit allowed domains here -->
    <!--
	<domain>http*://jwebsocket.org</domain>
	<domain>http*://jwebsocket.com</domain>
	<domain>http*://*.jwebsocket.org</domain>
	<domain>http*://*.jwebsocket.com</domain>
	<domain>http*://10.10.*</domain>
	<domain>http*://10.21.*</domain>
	<domain>http*://192.168.*</domain>
	<domain>http*://localhost*</domain>
    -->
  </domains>
  <!-- default session timeout (minutes) -->
  <timeout>30</timeout>
  <!-- The default jWebSocket server web-app context. The context can be configured 
	through the files:
	- ${JWEBSOCKET_HOME}/conf/TomcatEngine/conf/context.xml 
	- ${JWEBSOCKET_HOME}/conf/TomcatEngine/conf/rest-web.xml
	- ${JWEBSOCKET_HOME}/conf/TomcatEngine/conf/rest-web.xml 
  -->
  <context>/jWebSocket</context>
  <!-- maximum size of the data packet that the engine will read,
	if the frame size is larger than this the connection will be closed.
  -->
  <maxframesize>1048840</maxframesize>
  <!-- Indicates if the engine requires to notify connected clients 
	during the jWebSocket stopping process. If the jWebSocket server
	is part of a cluster (JMSEngine), the engine will only notify if
	it there are not other active nodes. Default: FALSE
  -->
  <notifySystemStopping>false</notifySystemStopping>
  <!-- maximun number of connections allowed by this engine -->
  <maxconnections>10000</maxconnections>
  <!-- on max connections reached strategy -->
  <!-- close, reject --> 
  <onmaxconnections>reject</onmaxconnections>
  <settings>
    <!-- directory that contains the public web folder path -->
    <setting key="document_root">/path/to/web/static/</setting>
    <!-- max threads property value for each tomcat connector -->
    <setting key="max_threads">200</setting>
  </settings>
</engine>

Note:
Please consider to review the TomcatHTTPEngine configuration files for better understanding:

  • ${JWEBSOCKET_HOME}/conf/TomcatEngine/conf/context.xml
  • ${JWEBSOCKET_HOME}/conf/TomcatEngine/conf/rest-web.xml
  • ${JWEBSOCKET_HOME}/conf/TomcatEngine/conf/rest.xml
The REST communication protocol:
Open:
To open an HTTP connection the client requires to send the following GET parameters:
  • The “action” parameter with the value set to “open”.
  • The “sessionId” value, is an optional argument that indicates the session identifier in the server. If no value is specified, a random session id value is generated.
  • The “connectionId” value, is a mandatory argument that indicates the “connector id” value of the client connection in the server (MD5 hashed for security). The value requires to be secret, since in case of being intersected the connection session can be hijacked (limited to the same machine).
Example URL:
https://localhost:9797/jWebSocket/http?connectionId=0a113ef6b61820da&action=open
Example response:
{"ns":"org.jwebsocket.msgctrl","type":"info","name":"maxFrameSize","data":1048840,
"jwsWrappedMsg":true}
Note:
During the client connection “opening” process, the server also send the “welcome” event to the client, so developers should call next “sync”:
https://localhost:9797/jWebSocket/http?connectionId=0a113ef6b61820da&action=sync
 
Login:
To login the client requires to send the following GET parameters:
  • The “action” parameter with the value set to “login”.
  • The “connectionId” value.
  • The “username” value.
  • The “password” value.
  • The “utid” value (Integer). It acts as message correlation identifier. Is used in the jWebSocket tokens communication to relate requests to replies. The argument is optional, default value: 0.
Example URL:
https://localhost:9797/jWebSocket/http?connectionId=0a113ef6b61820da&action=login&username=root&password=root
 
Example response:
{"type":"response","code":0,"msg":"ok","utid":0,"ns":"org.jwebsocket.plugins.system",
"reqType":"login","uuid":"root","username":"root","authorities":["org.jwebsocket.plugins.
admin.gc", ...]}
Send:
To transmit data to the server the client requires to send the following GET parameters:
  • The “action” parameter with the value set to “send”.
  • The “connectionId” value.
  • The “data” parameter with the value (commonly a JSON message) to be sent. Optionally the data value can be sent by using POST method.
 
Example URL:
https://localhost:9797/jWebSocket/http?connectionId=0a113ef6b61820da&action=send&data=jsonmessagehere
 
Example JavaScript(using POST):
var lXHR = getXHRTransport();
lXHR.open("POST", "https://localhost:9797/jWebSocket/http?connectionId=0a113ef6b61820da&action=send", true);
lXHR.send(JSON.stringify({
ns: “org.jwebsocket.plugins.system”
type: “echo”,
data: “Echo this value”
}));
 
Example response:
{"type":"response","code":0,"msg":"ok","utid":0,"ns":"org.jwebsocket.plugins.system",
"reqType":"echo", "data":"Echo this value"}
Sync:
To retrieve server-2-client events/messages, developers require to invoke the “sync” command in periodical time intervals in order to process the server messages in a proper time (strictly depends of the application). The invocation of “sync” command returns a JSON array with strings that represents the sent message's packets (commonly JSON strings) to the active client.
 
To invoke the “sync” command, the client requires to send the following GET parameters:
  • The “action” parameter with the value set to “retrieve”.
  • The “connectionId” value. 
Example URL:
https://localhost:9797/jWebSocket/http?connectionId=0a113ef6b61820da&action=sync

Example response:

["{\"ns\":\"org.jwebsocket.plugins.system\",\"type\":\"welcome\",\"vendor\":\
"jWebSocket.org\",\"version\":\"1.0.0 RC3 (build 40825)\",\"engines\":[{\
"id\":\"http0\",\"class\":\"org.jwebsocket.tomcat.http.TomcatHTTPEngine\"},
{\"id\":\"jmsgw0\",\"class\":\"org.jwebsocket.plugins.jms.gateway.JMSEngine\"}],
\"sourceId\":\"b5b97450d04da42855736867e12ae4be\",\"maxFrameSize\":1048840,\
"timeout\":30,\"username\":\"anonymous\",\"protocolVersion\":13,\"subProtocol\
":null,\"encodingFormats\":[\"base64\",\"zipBase64\"],\"anonymous\":true}"]
Download:
To download a file the client requires to send the following GET parameters:
  • The “action” parameter with the value set to “logout”.
  • The “connectionId” value.
  • The “filename” value that represents the file to be downloaded, located in the FileSystemPlugIn virtual file-system(FSP-VFS). Example: “mydocs/cv.pdf”
  • The “alias” value that indicates the FSP-VFS alias value. The value is optional, default value is “privateDir”: the client private directory.
Example URL:
https://localhost:9797/jWebSocket/http?connectionId=0a113ef6b61820da&action=download&filename=avatar.png
Example response:
 
Note:
The download feature requires the jWebSocket FileSystemPlugIn properly configured and running.
 
 
Logout:
To logout the client requires to send the following GET parameters:
  • The “action” parameter with the value set to “logout”.
  • The “connectionId” value.
  • The “utid” value. It acts as message correlation identifier. Is used in the jWebSocket tokens communication to relate requests to replies. The argument is optional, default value: 0.
Example URL:
https://localhost:9797/jWebSocket/http?connectionId=0a113ef6b61820da&action=logout
Example response:
{"type":"response","code":0,"msg":"ok","utid":0,"ns":"org.jwebsocket.plugins.system",
"reqType":"logout","anonymous":false}
Close:
To close the HTTP connection the client requires to send the following GET parameters:
  • The “action” parameter with the value set to “close”.
  • The “connectionId” value. 
Example URL:
https://localhost:9797/jWebSocket/http?connectionId=0a113ef6b61820da&action=close

 

Example response:
http.command.close
Note:
If the client inactivity exceeds the engine “timeout” configuration, the connection is automatically closed and the session storage cleaned.
If the client receives the message string “http.command.close” without to invoke the command “close”, it means that the connection has been closed from the server.
 
Warning for client/server developers related to Request/Response mechanism
Because jWebSocket is designed for permanent and bi-directional client connections, backend service developers are able to send many event messages to a client during a single client request. For the REST solution, specifically for the Request/Response mechanism, the mentioned scenario is not possible, because the HttpServletRequest writer instance is closed once it receives the first packet to be written, the rest of the packets are enqueued and only accessed through the “sync” command. The restriction is present to avoid per request timeout handlers that will produce at the end unnecessary extra server CPU load.

Example (Print a document):

  1. Server send “accessing printer” event message.
  2. Server send “sending document to printer” event message.
  3. Server send “printing” event message.
  4. Server send “message printed successfully” event message.
Note:
In the described example, the “response” to the HTTP request that ordered to print the document could be like following:
{“type”:”event”, “name”:”print_document”, “document”:”jWebSocket_Manual_1.0.doc”, “data”: “accessing printer”}
In this case, client developers may invoke the command “sync” to get the rest of the messages from the server.
 
The HTTPWebSocket JavaScript class for jWebSocket
For jWebSocket developers, using the REST API is pretty transparent, because the HTTPWebSocket class overrides the native browser WebSocket class in order to keep compliant with the jWebSocket JavaScript libraries.

To enable the HTTP communication, follow three simple steps:

1. Include the jWebSocketHTTP.js JavaScript library in your application:
<script src="../../res/js/jWebSocketHTTP.js" type="text/javascript"></script>
2. Invoke the following command before start the jWebSocket connection:
jws.enableHTTPSupportForWebSockets();
3. Use the following URL pattern for the jWebSocket client connection:
http[s]://${host}:${port}/jWebSocket/http?connectionId=${connectionId}
[&sessionId=${sessionId}]
The JWebSocketHTTPClient class for the jWebSocket Java client.
For jWebSocket Java client developers, using the REST API is pretty transparent, the JWebSocketHTTPClient class provides the back-end server REST API integration for the Java client library.

To enable the REST API in the Java client, the following steps are required:

1. Instantiate the Java client by passing the JWebSocketHTTPClient object as contructor argument:
client = new JWebSocketTokenClient(new JWebSocketHTTPClient());
client.open(lURL);
Note:
To use HTTP proxies with JWebSocketHTTPClient class, please see specialized contructors.

2. Use the following URL pattern for the jWebSocket client connection:

http[s]://${host}:${port}/jWebSocket/http?connectionId=${connectionId}[
&sessionId=${sessionId}]

 

jWebSocket REST support automated tests
The jWebSocket REST support includes a set of automated tests to guarantee the correct features behavior.

Note:
Please consider that the tests use a fixed server location:

“http://localhost:8787/jWebSocket/http”
 
 

Copyright © 2013 Innotrade GmbH. All rights reserved.