Table of Contents
This chapter describes the concepts, functions, and configurations of the WebSocket container.
The WebSocket container is included in the web engine and one exists for every web context.The WebSocket container provided by JEUS complies with JSR 356 and Java API for WebSocket. Thus, the server's WebSocket service must be written according to the API defined by the relevant standard. But, this document does not include detailed information about WebSocket RFC6455 and Java API for WebSocket standards.
1. Since the HTML5 WebSocket API is a client library, it is irrelevant to WebtoB and JEUS.
2. The Java API for WebSocket is included in Java EE 7. Therefore, for Java EE 7 based developments, refer to the Java EE 7 libraries.
The basic functions of the WebSocket container are to deploy WebSocket Server Endpoint objects included in the web context and connect a WebSocket Handshake request from the client to a Server Endpoint object that it maps to. Once a client and a WebSocket container are connected, WebSocket sessions are created and the life cycle of the session objects are also managed.
The role of a service developer is to implement a WebSocket Server Endpoint class(javax.websocket.Endpoint) and a configuration class(javax.websocket.server.ServerApplicationConfig), and package them into the web application.
The following are the constraints for using WebSocket containers in JEUS 7.
Only available for the HTTP listeners. Thus, it is recommended to use then with the reverse proxy function of WebtoB 4.1.8 or later. Detailed information about WebSocket support in the WebtoB reverse proxy function, refer to the WebtoB guide.
The <websocket> configuration can be set in detail, but it is not needed to use WebSocket.
The client API provided by the Java API for WebSocket standard is provided through lib/system/jeus-websocket-client.jar. To use another vendor's client module, if the full name of the another vendor's provider class in the META-INF/service/javax.websocket.ContainerProvider file of the above jar file is specified, then the module can be used via the service loader.
This chapter describes the additional functions of the WebSocket container.
A WebSocket container provides space in memory for storing data per WebSocket session. The map object (hereafter UserProperties) obtained by calling the javax.websocket.Session.getUserProperties() API contains the data.
Assume that WebSocket applications (web context including the WebSocket Server Endpoint) are deployed to two different servers. If data are saved in the UserProperties by using the WebSocket and the server is abnormally terminated, all data will be lost. However, if the data are backed up on another server, the UserProperties can be recovered by connecting the WebSocket to the backup server even if the server is abnormally terminated. From the user perspective, the WebSocket service can be used seamlessly. This is called WebSocket UserProperties Failover or Distributed WebSocket UserProperties.
The existing user can get the data in UserProperties stored in advance, but the failed over WebSocket endpoint is an endpoint that exists in a different server (not the existing server), and WebSocket Session is newly created. Therefore, this function must be used is very limited cases.
The following conditions must be met in order to use this function.
WebSocket UserProperties Failover operates based on the HTTP session service. The WebSocket session cluster must be supported. For more information about the session cluster, refer to JEUS Session Management Guide. "2.8. Session Cluster Modes".
The following must be added to the jeus-web-dd.xml configuration file of the WebSocket application.
<websocket> <distributed-userProperties> <enabled>true</enabled> </distributed-userProperties> </websocket>
In general, the WebSocket Session and HTTP Session are not integrated for use.
Data in the UserProperties object must be serializable.
WebSocket connection is initiated by an HTTP request. The cookie header of the WebSocket Handshake request must include the JSESSIONID. The HTTP session that the JSESSIONID points to must be created in the web context that the server endpoint belongs to.
For instance, when the JSP that calls the HTML5 WebSocket API is called, the HTTP session is created to send JESSIONID to the cookie header. When HTML5 WebSocket JavaScript is executed in the web browser, the WebSocket Handshake request is sent to JEUS. The cookie header must be included in the request header. WebSocket UserProperties Failover cannot be used If a WebSocket Client, which does not support this, is used.
Firefox 30.0 attaches the cookie header to the WebSocket Handshake request when HTML5 WebSocket API is used.
GET /service/chat HTTP/1.1 Connection: keep-alive, Upgrade Cookie: JSESSIONID=FheDy8e0bOTPO7KNqdeJ7Eps8j51CaQqcRWHvpYo9mdVw1BCSwlwrFiy rclsolkr.amV1czcvc2VydmVyMg== Sec-WebSocket-Key: Csv/FCQo1g1eZfqMtPd8+g== Sec-WebSocket-Version: 13 Upgrade: websocket User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:30.0) Gecko/20100101 Firefox/30.0 FirePHP/0.7.4
When this function is used with the WebtoB reverse proxy, the session routing must be configured in the reverse proxy configuration. For detailed information, refer to the WebtoB guide.
Note the following when using this function.
The HTTP session's timeout and the WebSocket session's timeout are not related. Especially in the case of a WebSocket session, since it is dependent on the HTTP session, the HTTP session properties cannot be modified from the WebSocket container level. When serializable data are added(put) to the UserProperties object, depending on the circumstances the HTTP session can time out first which prevents failover from occurring. HTTP session's timeout must be adjusted appropriately taking such situations into consideration.
If the HTTP session times out when adding (put) serializable data to the UserProperties, a WARNING level message will be logged.
The UserProperties of WebSocket sessions are not shared between different web contexts.
The following information can be obtained through Map<String, Object> which is a return value of Session.getUserProperties().
Item | Description |
---|---|
jeus.websocket.remoteAddr(String) | If Forwarded or X-Forwarded-For exists in an HTTP request header, the header value will be used. If not, a HttpServletRequest.getRemoteAddr() value will be used. |
jeus.websocket.remoteHost(String) | If Forwarded or X-Forwarded-For exists in an HTTP request header, the header value will be used. If not, a HttpServletRequest.getRemoteHost() value will be used. |
jeus.websocket.remotePort(String) | If Forwarded or X-Forwarded-For exists in an HTTP request header, a port value included in the header will be used. If a header does not have a port value, this property will be not supported. If there is no header, a HttpServletRequest.getRemotePort() value will be used. If the value is less than or equal to 0, it will be invalid. |
Configure the WebSocket container settings in jeus-web-dd.xml of each web application.
[Example 6.1] Web Context Configuration File: <<jeus-web-dd.xml>>
<jeus-web-dd xmlns="http://www.tmaxsoft.com/xml/ns/jeus" version="8.0"> <websocket> <max-incoming-binary-message-buffer-size>8192</max-incoming-binary-message-buffer-size> <max-incoming-text-message-buffer-size>8192</max-incoming-text-message-buffer-size> <max-session-idle-timeout-in-millis>1800000</max-session-idle-timeout-in-millis> <monitoring-period-in-millis>300000</monitoring-period-in-millis> <blocking-send-timeout-in-millis>10000</blocking-send-timeout-in-millis> <async-send-timeout-in-millis>30000</async-send-timeout-in-millis> <websocket-executor> <min>10</min> <max>30</max> <keep-alive-time>60000</keep-alive-time> <queue-size>4096</queue-size> </websocket-executor> <distributed-userProperties> <enabled>false</enabled> <use-write-through-policy>false</use-write-through-policy> </distributed-userProperties> <init-param> <name>name</name> <value>value</value> </init-param> <batching-buffer-size>655536</batching-buffer-size> <websocket-timeout-min-threads>1</websocket-timeout-min-threads> </websocket> </jeus-web-dd>
The following describes each configuration tag.
Tag | Description |
---|---|
<max-incoming-binary-message- buffer-size> | Maximum size of the buffer used for binary messages transmitted from the client. If the message size is larger than this value, the 1009 error occurs and the WebSocket session is closed. |
<max-incoming-text-message- buffer-size> | Maximum size of the buffer used for text messages transmitted from the client. If the message size is larger than this value, the 1009 error occurs and the WebSocket session is closed. |
<max-session-idle-timeout- in-millis> | Timeout for closing idle WebSocket sessions. If the value is larger than zero and smaller than 1000, it is set to 1000. (Default value: 30 minutes (1800000ms)) |
<monitoring-period-in-millis> | Cycle for checking the WebSocket session timeout. If the value is smaller than 1000, it is set to 1000. (Default value: 5 minutes (300000ms)) |
<blocking-send-timeout-in-millis> | Timeout for waiting for a synchronous send. Applied when using javax.websocket.RemoteEndpoint.Basic. (Default value: 10 seconds) |
<async-send-timeout-in-millis> | Timeout for waiting for messages awaiting to be sent asynchronously. Returned by javax.websocket.WebSocketContainer.getDefaultAsyncSendTimeout(). |
<websocket-executor> | Thread pool related settings used by the WebSocket container. This is usually used to process asynchronous sends. Set the following sub-tags.
|
<distributed-userProperties> | WebSocket Session Failover related settings depending on what is defined in the javax.websocket.Session.getUserProperties() method. . Set the following sub-tags.
|
<init-param> | Additional configurations used for a WebSocket container. Set a parameter name to <name> and a value to <value>. |