Tokens

A token is an object which contains one or multiple fields and values. In Java the org.jWebSocket.token.Token class embeds a HashMap class, which holds multiple fields with their according values. Fieldnames, the keys within the Hashmap, are stored as Strings, the values can be arbitrary objects. Unlike JSON or XML tokens CSV tokens can only have simple fields i.e. they cannot contain complex object structures.

Why use different Token formats?

Each of the JSON, CSV and XML formats have their benefits for a particular purpose as described below.

  • JSON

    JSON can be interpreted very easily by JavaScript clients, but not that easy by Java clients. JSON may hold security risks because it may execute malicious code on the client. So here you need to take care on the server side that potential executable codes are stripped out of a token. JSON is the best choice if you mostly interact with Browser clients and run a reliable script tag filter on the server. Unlike JSON CSV is not risky because its data is not interpreted with eval but with as simple string tokenizer.

    Example: {field1:value1;field2:"value2";field3:[arrayitem1,arrayitem2];field4:{objfield1:value1;objfield2:value2}}

  • CSV

    CSV is the most compact format, however, one drawback is that it does not support complex object structure but only plain rows, i.e. objects that contain simple data types only. CSV is the best choice if you have to exchange a high amount of data with flat structures.

    Example: field1=value1,field2="value2",field3=value3

  • XML

    XML is the most flexible format but also the format with the highest overhead. XML can contain arbitrary object structures. Hence XML is the best choice if you do not have to exchange a high amount of data but keep to most flexible in terms of the token content.

    Example: Targeted for jWebSocket Release 1.1

  •  

Token-Types

Every token has a certain type stored in its type field. The type specifies which further fields within its namespace (see below) .

Namespaces

In jWebSockets the communication capabilities are implemented in various plug-ins, on the client-side as well as on the server-side. You can extend the existing functionality by creating your own plug-ins. To avoid naming conflicts with token fields jWebSocket provides namespaces for tokens. So before a plug-in starts to evaluate the content of a token it first checks for its name space which should match the name space of the plug-in.

Token-IDs

Every Token has a session unique token id which is exchanged between sender and receiver. Due to the multithreaded structure of the jWebSocket server it cannot be guaranteed that the results of a client request are returned to the client in the same order as they were requested. Thus if request is send to the server the jWebSocket client assigns a new session unique token id to each new token. The response from the server takes over this token-id into the response so that the client is able to assign the response correctly to the previous request.

However, you do not need to consider the token ids in your applications. All incoming responses can also be captured in the OnMessage callback handler of the jWebSocket client. Also for RPC calls the jWebSocket.js library processes the token-ids internally to assign the result of a call to a server method internally, so that you usually do not need to take care of them.

Token-Reference

Below you find the list of supported tokens in the SystemPlugIn of the jWebSocket package. First the Server-to-Client (S2C) tokens are listed followed by the Client-To-Server (C2S) tokens.

Server-To-Client Tokens

welcome

The welcome token is send from the server to a client, when the connection has successfully been established. The welcome token is the only token that contains the session-id for the client. It will neither be sent again by the server nor can it be requested by the client during the session. In all cases the processOpened method of the client is executed as soon as the connection was established.

Token Datatype Description
type String Always "welcome"
vendor String Name of the vendor who provides the jWebSocket services. Can be configured in Config.java.
version String Version string of the jWebSocket server.
usid String Unique session id the jWebSocket assigns to that client.
sourceId Integer Unique id for this client. This allows to address a certain client in the network irrespective of their user id.
timeout Integer Session timeout in milliseconds. After this time of client inactivity the server will automatically close the connection.

goodBye

The goodbye token is send from the server to a client after as response to a close request. The close method of the JavaScript client supports a timeout option. If timeout is <= 0 the client disconnects immediately. If the timeout is > 0 the client sends a close token to the server and waits timeout milliseconds for the goodBye response. In this case the server disconnects after responding with goodBye. If the client does not receive the goodBye within the given timeout it disconnects as well. In all cases the processClosed method of the client is executed as soon as the connection was terminated.

Token Datatype Description
type String Always "goodBye"
vendor String Name of the vendor who provides the jWebSocket services. Can be configured in Config.java.
version String Version string of the jWebSocket server.
usid String Unique session id that jWebSocket assigns to that client.
port Integer Server side outgoing TCP port number the client is connected with.

response

The response token is send as a response from a target to a previous request from a client. A response can either be send from the server e.g when running remote procedure calls (RPC) or from another client e.g. when running identify requests.

Token Datatype Description
type String Always "response"
utid Integer Unique token id to assign the response to the previous request on the client side.
reqType String Type of the token which was sent for the previous request, original request type.
code Integer Should be zero, if the result in Ok or any other code if an error occurred (also see msg field).
result Variant Result of the request, can be of arbitrary type depending on the request and the method on the target.
msg String An optional error message in case of errors or exceptions.

event

The event token is send as a message from the server or another client without a previous request. Events are fired when another client connects or disconnects or when the server side session timeout is exceed and the connection is about to be closed.

Token Datatype Description
type String Allways "event".
name String Name of the event, further fields of this token depend on the event. Name can be associated with event type.
: : Further fields depending on name / event type (see below).
  • connect event

    A new client has connected to the jWebSocket network. This event is optional and can be configured to not being sent automatically by the server. Please refer to the identify request to learn how to obtain connected users by following individual privacy policies.

    Token Datatype Description
    type String Always "event"
    name String Always "connect"
    sourceId String Unique id of the client that just connected (optional, whether or not broadcasting this field can be configured on the server).
    clientCount Integer Number of client currently connected the server (optional, whether or not broadcasting this field can be configured on the server).
  • disconnect event

    A client has disconnected from the jWebSocket network. This event is optional and can be configured to not being sent automatically by the server. If the disconnect event is not sent by the server the client cannot update potential local client lists in real-time. To obtain the connected clients asynchronously please refer to the getClients token.

    Token Datatype Description
    type String Always "event"
    name String Always "disconnect"
    sourceId String Unique id of the client that just connected (optional, whether or not broadcasting this field can be configured on the server).
    clientCount Integer Number of client currently connected the server including the one who is about to disconnect (optional, whether or not broadcasting this field can be configured on the server).
  • login event

    A new client has successfully logged in. This event can be used e.g. to update user lists on the client in real-time. This event is optional and can be configured to not being sent automatically by the server. Please refer to the identify request to learn how to obtain connected users by following individual privacy policies.

    Token Datatype Description
    type String Always "event"
    name String Always "login"
    sourceId String Unique id of the client that just connected (optional, whether or not broadcasting this field can be configured on the server).
    clientCount Integer Number of client currently connected the server including the one who is about to disconnect (optional, whether or not broadcasting this field can be configured on the server).
    username String Name of user who has logged in.
  • logout event

    A client which previously was logged in has logged out. This event can be used e.g. to update user lists. This event is optional and can be configured to not being sent automatically by the server. If the logout event is not sent by the server the client cannot update potential local user lists in real-time. To obtain the connected users asynchronously please refer to the getClients token.

    Token Datatype Description
    type String Always "event"
    name String Always "logout"
    sourceId String Unique id of the client that just connected (optional, whether or not broadcasting this field can be configured on the server).
    clientCount Integer Number of client currently connected the server including the one who is about to logout (optional, whether or not broadcasting this field can be configured on the server).
    username String Name of user who has logged out.

Client-To-Server Tokens

The following section describes the tokens which are send from the client to the server. These tokens can be associated with "commands" from the client to the server which usually are answered with a response token (see above) if not explicitely suppressed for certain reasons. Results are sent back from the server to the client in a response token as described above. Usually the fields result, code and msg are filled in the answer. Because JavaScript does not support synchronous calls each command provides an optional OnResponse listener which is fired when the responsetoken arrives.

login

Authenticates a client after the connection has been established. The client should wait until the response is received from the server before notifying the user about the login state or a potential error. If a login token is sent while another user already is authenticated, the previous user automatically gets logged out.

Token Datatype Description
type String Always "login".
ns String Namespace "org.jWebSocket.plugins.system".
username String Name of user who has logged out.
password String Please refer to section security.

logout

Logs the current user out but keeps the connection. Optionally another user can authenticate afterwards based upon the same underlying connection.

Token Datatype Description
type String Always "logout".
ns String Namespace "org.jWebSocket.plugins.system".

close

The close method of the JavaScript client supports timeout option. If timeout is <= 0 the client disconnects immediately. If the timeout is > 0 the client sends a close token to the server and waits timeout milliseconds for the goodBye response. In this case the server disconnects after responding with goodBye. If the client does not receive the goodBye within the given timeout it disconnects as well.

Token Datatype Description
type String Always "close".
ns String Namespace "org.jWebSocket.plugins.system".
timeout Integer Close timeout in milliseconds.

send

The send token is forwarded by the server to the client addressed by the given targetId. In the responseRequested field the sender can specify whether or not to get a response (acknowledge that the token has been forwarded) or not. I case of errors, e.g. when no client with the given targetId could be found, always a response with an error is returned.

Please consider that a certain client cannot be addressed by its username but by its client id only, because basically a user can login on multiple stations or browser instances/tabs, of course, only if the application allows that. Furthermore a client does not necessarily need to be authenticated to receive messages from the server.

Token Datatype Description
type String Always "send".
ns String Namespace "org.jWebSocket.plugins.system".
data String The message to be sent.
sourceId String Id of the source client who sent the message.
targetId String Id of the target client as receiver of the message.
responseRequested Boolean Specifies whether the sender expects an answer or if it is a one-way token (targetted for v0.8)
sender String Username of client who sent the message.

broadcast

The broadcast token is broadcasted by the server to all currently connected clients, optionally including the sender for special purposes. The server optionally sends a response (see field responseRequested). It's up to the other clients (targets) to send a response to the sender (source). Among others the broadcast can be used to e.g. for chat systems or to distribute player updates in gaming applications as well as to broadcast identify requests for the case that the server is configured to not automatically send connect, disconnect, login and logout events.

Token Datatype Description
type String Always "broadcast".
ns String Namespace "org.jWebSocket.plugins.system".
data String The message to be sent.
sourceId String Id of the source client who sent the message.
senderIncluded Boolean Specifies whether the message is also send to sender (default false).
responseRequested Boolean Specifies whether the sender expects an answer or if it is a one-way token.
sender String Username of the client who sent the message.

echo

The echo token sends a message to the server. The client expects a result with the same data. Usually applications will not use this token, except for connection and performance tests. For keep-alive purposes please refer to the ping token.

Token Datatype Description
type String Always "echo"
ns String Namespace "org.jWebSocket.plugins.system".
data String Data to be sent to the server and echoed back.

ping

The ping token is a simple and short message from a client to the server to indicate that the client is still alive. If the server does not receive data within its session timeout he automatically closes the connection after the timeout is exceeded.

Token Datatype Description
type String Always "ping"
ns String Namespace "org.jWebSocket.plugins.system".
echo Boolean Specifies whether the ping expects a result or not (default false). echo should be set to true only when the client wants to check if the server is still alive.

getClients

The getClients token requests the list of clients from the server. With the mode option (default = 0) the client can specify whether to return all, authenticated client only or non-authenticated clients only. The result field of the response contains an array with the requested clients in the format [username|dash if not logged in]@[clientId].

Token Datatype Description
type String Always "getClients".
ns String Namespace "org.jWebSocket.plugins.system".
mode Integer ALL_CLIENTS=0, AUTHENTICATED=1, NON_AUTHENTICATED=2.
Enough talk, let's get to the code!

Most of our users don't really know how to send a token from the server to the client and vice-versa, that's why we are briefly explaining here how to do that in a very easy way.

As we already know what is a namespace and a type, then let's quickly create an example how to communicate using jWebSocket in both directions.

How to send a token from a JavaScript client to the server

Let's take the basic example when a user registers to the server to be broadcasted on a public chat.

// Check for WebSocket support
if (jws.browserSupportsWebSockets()) {
	var lWSC = new jws.jWebSocketJSONClient(),
			lNS = jws.NS_BASE + ".plugins.chat",
			lURL = jws.getAutoServerURL(),
			lRes = lWSC.open(lURL, {
				// OnOpen callback
				OnOpen: function (aEvent) {
					// Once the server opened the connection we can 
					// send the first token
					var lRegisterToken = {
						// ns: 'org.jwebsocket.plugins.chat'
						ns: lNS,
						type: 'register'
					};
					mWSC.sendToken(lRegisterToken);
				},
				OnWelcome: function (aEvent) {
					// welcome from jWebSocket Server
					console.log(aEvent);
				},
				// OnMessage callback
				OnMessage: function (aEvent, aToken) {
					if(lNS === aToken.ns){
						if(aToken.type === "broadcast"){
							// Received a broadcast token, show it to the user
						}
					}
				},
				OnClose: function (aEvent) {
					// Connection closed
				}
			});

} else {
	alert(jws.MSG_WS_NOT_SUPPORTED);
}

Note that the OnMessage event process all tokens coming from the server side.

How to send a token from the server to the client

jWebSocket has a special class in Java to handle the tokens, this class is provided as org.jwebsocket.token.Token within the jWebSocketCommon package allowing the user to create customizable messages to be sent to the client. The tokens are transparently parsed at low level to the communication default client "JSON", "CSV" or "XML" as the user requires. The following code shows the Chat PlugIn with a list of users that register to be broadcasted within the application. Please note that the example is not complete, it should serve as a guide, for the end user to have an idea of what is a token and how he can send it. From the server side to send a token is as easy as invoking within the PlugIn the method getServer().sendToken(lCertainToken).

package org.jwebsocket.plugins.chat;
//...
import org.jwebsocket.plugins.TokenPlugIn;
import org.jwebsocket.token.Token;
//...

public class ChatPlugIn extends TokenPlugIn {

	private static final Logger mLog = Logging.getLogger();
	
	// The list of users to be broadcasted
	private static final FastMap<String, WebSocketConnector> mClients
			= new FastMap<String, WebSocketConnector>().shared();

	public static final String NS_CHAT
			= JWebSocketServerConstants.NS_BASE + ".plugins.chat";
	
	private final static String TT_REGISTER = "register";
	private final static String TT_UNREGISTER = "unregister";
	private final static String TT_GET_CLIENTS = "getChatClients";
	private final static String TT_BROADCAST = "broadcast";
	private final static String TT_MESSAGE_TO = "messageTo";
	private final static String TT_EVENT = "event";
	private final static String TT_NEW_CLIENT = "newClientConnected";
	
	public ChatPlugIn(PluginConfiguration aConfiguration) {
		super(aConfiguration);
		if (mLog.isDebugEnabled()) {
			mLog.debug("Instantiating chat plug-in...");
		}
		// specify default name space for chat plugin
		this.setNamespace(NS_CHAT);

		if (mLog.isInfoEnabled()) {
			mLog.info("Chat plug-in successfully instantiated.");
		}
	}
	
	@Override
	public void processToken(PlugInResponse aResponse,
			WebSocketConnector aConnector, Token aToken) {
		if (NS_CHAT.equals(aToken.getNS())) {
			if (TT_REGISTER.equals(aToken.getType())) {
				mClients.put(aConnector.getId(), aConnector);
				getClients(aConnector);
				notifyNewClientConnected(aConnector);
			} else if (TT_UNREGISTER.equals(aToken.getType())) {
				unregister(aConnector);
			} else if (TT_GET_CLIENTS.equals(aToken.getType())) {
				getClients(aConnector);
			} else if (TT_BROADCAST.equals(aToken.getType())) {
				broadcast(aConnector, aToken);
			} else if (TT_MESSAGE_TO.equals(aToken.getType())) {
				sendMessage(aConnector, aToken);
			}
		}
	}

	private void broadcast(WebSocketConnector aConnector, Token aToken) {
		String lMessage = aToken.getString("msg");
		String lUsername = aConnector.getUsername() + "@" + aConnector.getId();
		if (lMessage != null) {
			if (!lMessage.isEmpty()) {
				Token lBroadcastToken = TokenFactory.createToken(NS_CHAT, TT_BROADCAST);
				lBroadcastToken.setString("msg", lMessage);
				lBroadcastToken.setString("sourceId", lUsername);

				for (Map.Entry<String, WebSocketConnector> lEntry : mClients.entrySet()) {
					getServer().sendToken(lEntry.getValue(), lBroadcastToken);
				}
			} else {
				getServer().sendErrorToken(aConnector, aToken, -1,
						"No message given. Please check!");
			}
		} else {
			getServer().sendErrorToken(aConnector, aToken, -1,
					"No message given. Please check!");
		}
	}

// ...
// Please download the source code of jWebSocket to get the full code, this is just an example
}

With this guide we expect that our users have a simple example of how to use tokens in both, client and server side.

Publications

Learn more about WebSockets in general, get background information and gain deeper insight!

Join jWebSocket

Wether developer, designer or translator – join the jWebSocket team and grow together with our success!

Copyright © 2013 Innotrade GmbH. All rights reserved.