WebSocket Client Reconnect

Another new feature was recently added to Tyrus (Java API for WebSocket Reference Implementation): Client ReconnectHandler. Some client use cases require almost persistent client-to-server connection and don’t really care about lower layer issues, like unstable internet connection.

Tyrus Client now include possibility of registering ReconnectHandler, which can help with these scenarios. Let’s see ReconnectHandler declaration:

public class ReconnectHandler {

  public boolean onDisconnect(CloseReason closeReason) {
    return false;

  public boolean onConnectFailure(Exception exception) {
    return false;

Method onDisconnect is executed whenever client endpoint @OnClose annotated method is called, method onConnectFailure is executed whenever client has some troubles connecting to remote endpoint (network issues, server returning HTTP Status 500, …). Both methods can return boolean value, which indicates whether client should try to reconnect or not.

It is perfectly fine to wait in any of these methods for some time – I would recommend it for onConnectFailure, because there usually is some reason for network failure and repeating requests without any delay can prolong them or even make them worse. Also I would recommend include some kind of counter, which would set the number of reconnect attempts.

Example implementation could look like:

ClientManager client = ClientManager.createClient();
ClientManager.ReconnectHandler reconnectHandler = new ClientManager.ReconnectHandler() {
  private int counter = 0;
  public boolean onDisconnect(CloseReason closeReason) {
    if (counter <= 3) {
      System.out.println("### Reconnecting... (reconnect count: " + counter + ")");
      return true;
    } else {
      return false;
  public boolean onConnectFailure(Exception exception) {
    if (counter <= 3) {
      System.out.println("### Reconnecting... (reconnect count: " + counter + ") " + exception.getMessage());
      // Thread.sleep(...) or something other "sleep-like" expression can be put here - you might want
      // to do it here to avoid potential DDoS when you don't limit number of reconnects.
      return true;
    } else {
      return false;
client.getProperties().put(ClientManager.RECONNECT_HANDLER, reconnectHandler);
Posted in java | Tagged , , , | Leave a comment

Updating Tyrus in Glassfish

This article is inspired by similar one about Jersey and will provide similar information. Thanks to Michal for creating such comprehensive instructions.

Fortunately, Tyrus does not depend on HK2 so the task here is lot easier. To be absolutely honest, I did expect some issues with Grizzly dependency in Tyrus client, but changes are backwards compatible (applies to Tyrus 1.4), so you can update Tyrus to any version of released Glassfish very easily.

Which version of Tyrus am I using?

You can get this from tyrus-core.jar manifest:

$ unzip -p $GLASSFISH_HOME/glassfish/modules/tyrus-core.jar META-INF/MANIFEST.MF | grep Bundle-Version
Bundle-Version: 1.0.0

This means you are using Tyrus 1.0. I strongly recommend to upgrade. Latest version now is Tyrus 1.4 and the output will look like:

$ unzip -p $GLASSFISH_HOME/glassfish/modules/tyrus-core.jar META-INF/MANIFEST.MF | grep Bundle-Version
Bundle-Version: 1.4.0

Glassfish distributions

Table below contains overview of current Glassfish 4.x builds:

Glassfish version Download link Tyrus version
4.0 (Java EE 7 RI) [download] 1.0
4.0.1 b01 [download] 1.0
4.0.1 b02 [download] 1.2.1
4.0.1 b03 [download] 1.2.1
4.0.1 latest nightly [download] latest

Updating to Tyrus 1.4

$ wget http://search.maven.org/remotecontent?filepath=org/glassfish/tyrus/bundles/websocket-ri-archive/1.4/websocket-ri-archive-1.4.zip -O ./websocket-ri-archive-1.4.zip
$ rm $GLASSFISH_HOME/glassfish/modules/tyrus-*jar
$ unzip -j ./websocket-ri-archive-1.4.zip "websocket-ri-archive-1.4/lib/*" -d $GLASSFISH_HOME/glassfish/modules/
Archive:  ./websocket-ri-archive-1.4.zip
  inflating: [path]/modules/tyrus-client-1.4.jar
  inflating: [path]/modules/tyrus-container-glassfish-cdi-1.4.jar
  inflating: [path]/modules/tyrus-container-grizzly-client-1.4.jar
  inflating: [path]/modules/tyrus-container-servlet-1.4.jar
  inflating: [path]/modules/tyrus-core-1.4.jar
  inflating: [path]/modules/tyrus-server-1.4.jar
  inflating: [path]/modules/tyrus-spi-1.4.jar

And that’s it. Note that you have to restart your Glassfish instance after replacing Tyrus jar files.


As of now (1/24/2013) latest nightly build of Glassfish contains Tyrus 1.3.3. Next nightly should contain latest Tyrus release – version 1.4.


Posted in java | Tagged , , , | Leave a comment

WebSocket Client on Android – Tyrus

Running some Java EE libraries or frameworks in non-standard VM is not an uncommon task and same is for Tyrus. I have to admit that this task was driven mainly by issue report TYRUS-256 from Reza. There is no official support from Tyrus running on Dalvik and I’m not even sure if it is a good idea, but important fact it works is that you can do it :-).

Whole issue which blocked runtime from being able to run on Android was in usage of javax.naming.InitialContext class. There is no simple alternative to it, but fortunately there is always a possibility to do little bit of reflection hacking to get rid of the dependency if it’s not there. The rest was only about creating the sample application and testing it on my phone, which was not that hard. I have to give kudos to IntelliJ IDEA team for their support, but not for Android Studio – it uses gradle as build tool and it seems like you cannot include java library because android plugin clashes with java plugin (I’m not very familiar with gradle as you might have noticed). Using and build script and build in support was better for my task.

The application I used for testing is available on github in my personal workspace: https://github.com/pavelbucek/tyrus-client-android-test. Feel free to test it and/or provide pull requests. I would be particularly interested in gradle build script.

That’s it for today. If you are using Tyrus on Android or if you have any related comments, please share them with us on Tyrus mailing list or as an enhancement request.

Posted in java | Tagged , , , | Leave a comment

Tyrus 1.4

I’m pleased to announce that Tyrus 1.4 was released today. It contains all features mentioned recently on my blog: Extensions support (including compression extensions implementation), shared client container and many other improvements and bug fixes. Binaries will be available on maven central repository soon and Tyrus 1.4 will be integrated into Glassfish trunk.

As always, feel free to contribute! You can file an enhancement or a bug or just ask if there is something unclear in the documentation.

Release notes


  • [TYRUS-136] – org.glassfish.tyrus.server.Server does not stop correctly when DeploymentException is thrown
  • [TYRUS-263] – SSL via HTTP PROXY – wss://echo.websocket.org Handshake error. “Response code was not 101: 200″
  • [TYRUS-269] – Parallel connection to ServerEndpoint with URI template mix up response to client instances …
  • [TYRUS-270] – The title of file README.html of Draw sample is mis-typed from “Draw Sample” to “Chat Sample”
  • [TYRUS-271] – “?null” is added to every request without query params
  • [TYRUS-272] – TyrusServerConfiguration incompatible with jetty’s jsr 356 implementation.
  • [TYRUS-273] – EJB component provider needs to provide method which will be invoked.
  • [TYRUS-275] – Tyrus client has bug causing limitation of # of open web sockets
  • [TYRUS-276] – Session accepts messages after idle timeout (@OnMessage is triggered)
  • [TYRUS-277] – session.setMaxIdleTimeout(0) does not reset/cancel the timeout
  • [TYRUS-280] – Extension parsed does not allow parameter without value
  • [TYRUS-281] – Client does CDI/EJB lookup
  • [TYRUS-282] – Session.setMaxIdleTimeout(..) does not work as expected for negative values
  • [TYRUS-288] – WebSocket connections are automatically closed after 30 idle seconds in standalone mode


  • [TYRUS-56] – content root directory configuration in Server class for static content
  • [TYRUS-160] – Tyrus tests won’t compile with JDK 1.6
  • [TYRUS-183] – UTF8 validation logic should be separated from frame parsing
  • [TYRUS-265] – Improve GrizzlyWriter implementation
  • [TYRUS-266] – Support for WebSocket extensions
  • [TYRUS-268] – In-memory transport for testing / performance analysis

New Features

  • [TYRUS-193] – Support Tyrus with different transports
  • [TYRUS-283] – CompressionExtension (permessage-compression)
  • [TYRUS-286] – Shared client container improvement (stop when there is no open session)
  • [TYRUS-287] – Cannot create non-daemon threads with Tyrus server standalone mode


  • [TYRUS-246] – Investigate and fix issues related to ServletTest#testWebSocketBroadcast
  • [TYRUS-264] – Client SPI
Posted in java | Tagged , , | Leave a comment

JavaCompiler + WatchService

I read an article about Java compiler API (almost by accident) and something related to PLAY framework and I just wanted to try to do something similar what it can do – compile on demand. Basically I have some class sources outside of my current project and I want it to be recompiled when modified, loaded and some method invoked to verify that the code was actually recompiled.

Please don’t take this seriously, it is just a proof of concept, nothing more.

public class Server {

    private static final JavaCompiler systemJavaCompiler = ToolProvider.getSystemJavaCompiler();

     * I did not bother with proper exception handling as you might notice :-)
    public static void main(String[] args) throws IOException, ClassNotFoundException,
            IllegalAccessException, InstantiationException, InvocationTargetException,
            NoSuchMethodException, InterruptedException {


        final WatchService watchService = FileSystems.getDefault().newWatchService();
        final Path path = Paths.get("DIR_WITH_SOURCE");
        final WatchKey watchedKey = path.register(watchService, StandardWatchEventKinds.ENTRY_MODIFY);

        while (true) {
            final WatchKey key = watchService.take();
            if (key.equals(watchedKey)) {

                for (WatchEvent<?> event : key.pollEvents()) {
                    if(event.kind().equals(StandardWatchEventKinds.ENTRY_MODIFY)) {
                        // you might want to call
                        // ((WatchEvent<Path>)event).context() to check modifyied file name


    static void compileAndInvoke() throws FileNotFoundException, ClassNotFoundException, NoSuchMethodException,
            IllegalAccessException, InstantiationException, InvocationTargetException {
        // use systemJavaCompiler.getTask(..) to set ouput directory
        final FileInputStream in = new FileInputStream("DIR_WITH_SOURCE/Test.class");

        final ClassLoader classLoader = new ClassLoader() {
            protected Class<?> findClass(String name) throws ClassNotFoundException {

                try {

                    final FileChannel channel = in.getChannel();
                    final MappedByteBuffer buffer = channel.map(FileChannel.MapMode.READ_ONLY, 0, channel.size());

                    if (name.equals("my.test.Test")) {
                        return defineClass(
                    // delete compiled class file - just to be sure it won't be picked up by other classloader
                    new File("DIR_WITH_SOURCE/Test.class").delete();
                } catch (IOException e) {

                return null;

        final Class<?> aClass = classLoader.loadClass("my.test.Test");
        final Method method = aClass.getMethod("test");

you can just replace “DIR_WITH_SOURCE” and “my.test.Test”, run (make sure there is method called “test” with no parameters in your Test class), open Test.java source, modify, save and wait little bit. This is actually little issue for me, it seems like it takes too long. Not sure whether it can be improved or not, maybe by implementing some custom WatchService like daemon.

For the sake of completeness, see my Test.java source:

public class Test {

    public void test() {


And thats it!

Posted in java | Tagged , , , , | Leave a comment

Using WebSocket Extensions in Tyrus

There is always room for another experimental feature :-) This one is maybe little less experimental than broadcast support, but please implement presented APIs with one important fact in your mind – it can change any time.

What is WebSocket Extension?

You can think of WebSocket Extension as a filter, which processes all incoming and outgoing frames. Frame is the smallest unit in WebSocket protocol which can be transferred on the wire – it contains some some metadata (frame type, opcode, payload length, etc.) and of course payload itself.

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|F|R|R|R| opcode|M| Payload len |    Extended payload length    |
|I|S|S|S|  (4)  |A|     (7)     |             (16/64)           |
|N|V|V|V|       |S|             |   (if payload len==126/127)   |
| |1|2|3|       |K|             |                               |
+-+-+-+-+-------+-+-------------+ - - - - - - - - - - - - - - - +
|     Extended payload length continued, if payload len == 127  |
+ - - - - - - - - - - - - - - - +-------------------------------+
|                               |Masking-key, if MASK set to 1  |
| Masking-key (continued)       |          Payload Data         |
+-------------------------------- - - - - - - - - - - - - - - - +
:                     Payload Data continued ...                :
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
|                     Payload Data continued ...                |

Figure taken from RFC 6455

If you are interested about some more details related to WebSocket protocol specification, please see linked RFC document (RFC 6455).

What can be achieved by WebSocket Extension?

Almost everything. You can change every single bit of incoming or outgoing frame, including control frames (close, ping and pong). There are some RFC drafts trying to standardise extensions like per message compression (used to be per frame compression) and multiplexing extension (now expired).

Tyrus already has support for per message compression extension and exposes interfaces which allow users to write custom extensions with completely different functionality.

When should I consider implementing WebSocket Extensions?

This is maybe the most important question. WebSocket Extensions can do almost everything, but you should not use them for use cases achievable by other means. Why? Majority of WebSocket use cases are about communication with browsers and javascript client cannot really influence which exception is going to be used. Browser must support your particular extension (by default or it can be enabled by some custom module).

You can easily use custom extension when using Tyrus java client, so if there is no browser interaction in your application, it should be easier to distribute your extensions to involved parties and you might lift the threshold when deciding whether something will be done by extension or by application logic.

Java API for WebSocket and Extensions

API currently contains following extension representation (javadoc removed):

public interface Extension {

    String getName();
    List getParameters();

    interface Parameter {
        String getName();
        String getValue();

and the specification (JSR 356) limits extension definition only for handshake purposes. To sum that up, users can only declare Extension with static parameters (no chance to set parameters based on request extension parameters) and that’s it. These extensions don’t have any processing part, so the work must be done somewhere else. As you might already suspect, this is not ideal state. Usability of extensions specified like this is very limited, it is basically just a marker class which has some influence on handshake headers. You can get list of negotiated extensions in the runtime (Session.getNegotiatedExtensions()) but there is no way how you could access frame fields other than payload itself.

Proposed Extension API

I have to repeat warning already presented at the start of this blog post – anything mentioned below might be changed without notice. There are some TODO items which will most likely require some modification of presented API, not to mention that RFC drafts of WebSocket Extensions are not final yet. There might be even bigger modification needed – for example, multiplexing draft specifies different frame representation, use of RSV bits is not standardised etc. So please take following as a usable proof of concept and feel free to use them in agile projects.

Firstly, we need to create frame representation.

public class Frame {

    public boolean isFin() { .. }
    public boolean isRsv1() { .. }
    public boolean isRsv2() { .. }
    public boolean isRsv3() { .. }
    public boolean isMask() { .. }
    public byte getOpcode() { .. }
    public long getPayloadLength() { .. }
    public int getMaskingKey() { .. }
    public byte[] getPayloadData() { .. }
    public boolean isControlFrame() { .. }

    public static Builder builder() { .. }
    public static Builder builder(Frame frame) { .. }

    public final static class Builder {

        public Builder() { .. }
        public Builder(Frame frame) { .. }
        public Frame build() { .. }
        public Builder fin(boolean fin) { .. }
        public Builder rsv1(boolean rsv1) { .. }
        public Builder rsv2(boolean rsv2) { .. }
        public Builder rsv3(boolean rsv3) { .. }
        public Builder mask(boolean mask) { .. }
        public Builder opcode(byte opcode) { .. }
        public Builder payloadLength(long payloadLength) { .. }
        public Builder maskingKey(int maskingKey) { .. }
        public Builder payloadData(byte[] payloadData) { .. }

This is pretty much straightforward copy of frame definition mentioned earlier. Frame is designed as immutable, so you cannot change it in any way. One method might be recognised as mutable – getPayloadData() – returns modifiable byte array, but it is always new copy, so the original frame instance remains intact. There is also a Frame.Builder for constructing new Frame instances, notice it can copy existing frame, so creating a new frame with let’s say RSV1 bit set to “1” is as easy as:

Frame newFrame = Frame.builder(originalFrame).rsv1(true).build();

Note that there is only one convenience method: isControlFrame. Other information about frame type etc needs to be evaluated directly from opcode, simply because there might not be enough information to get the correct outcome or the information itself would not be very useful. For example: opcode 0x00 means continuation frame, but you don’t have any chance to get the information about actual type (text or binary) without intercepting data from previous frames. Consider Frame class as as raw as possible representation. isControlFrame can be also gathered from opcode, but it is at least always deterministic and it will be used by most of extension implementations. It is not usual to modify control frames as it might end with half closed connections or unanswered ping messages.

New Extension representation needs to be able to handle extension parameter negotiation and actual processing of incoming and outgoing frames. It also should be compatible with existing javax.websocket.Extension class, since we wan’t to re-use existing registration API and be able to return new extension instance included in response from Session.getNegotiatedExtensions():List<Extension> call. Consider following:

public interface ExtendedExtension extends Extension {

    Frame processIncoming(ExtensionContext context, Frame frame);
    Frame processOutgoing(ExtensionContext context, Frame frame);

    List onExtensionNegotiation(ExtensionContext context, List requestedParameters);
    void onHandshakeResponse(ExtensionContext context, List responseParameters);

    void destroy(ExtensionContext context);

    interface ExtensionContext {

        Map<String, Object> getProperties();

ExtendedExtension is capable of processing frames and influence parameter values during the handshake. Extension is used on both client and server side and since the negotiation is only place where this fact applies, we needed to somehow differentiate these sides. On server side, only onExtensionNegotiation(..) method is invoked and client side has onHandshakeResponse(..). Server side method is a must, client side could be somehow solved by implementing ClientEndpointConfig.Configurator#afterResponse(..) or calling Session.getNegotiatedExtenions(), but it won’t be as easy to get this information back to extension instance and even if it was, it won’t be very elegant. Also, you might suggest replacing processIncoming and processOutgoing methods by just one process(Frame) method. That is also possible, but then you might have to assume current direction from frame instance or somehow from ExtenionContext, which is generally not a bad idea, but it resulted it slightly less readable code.

Last but not least is ExtensionContext itself and related lifecycle method. Original Extension from javax.websocket is singleton and ExtendedExtension must obey this fact. But it does not meet some requirements we stated previously, like per connection parameter negotiation and of course processing itself will most likely have some connection state. Lifecycle of ExtensionContext is defined as follows: ExtensionContext instance is created right before onExtensionNegotiation (server side) or onHandshakeResponse (client side) and destroyed after destroy method invocation. Obviously, processIncoming or processOutgoing cannot be called before ExtensionContext is created or after is destroyed. You can think of handshake related methods as @OnOpen and destroy as @OnClose.

For those more familiar with WebSocket protocol: process*(ExtensionContext, Frame) is always invoked with unmasked frame, you don’t need to care about it. On the other side, payload is as it was received from the wire, before any validation (UTF-8 check for text messages). This fact is particularly important when you are modifying text message content, you need to make sure it is properly encoded in relation to other messages, because encoding/decoding process is stateful – remainder after UTF-8 coding is used as input to coding process for next message. If you want just test this feature and save yourself some headaches, don’t modify text message content or try binary messages instead.

Code sample

Let’s say we want to create extension which will encrypt and decrypt first byte of every binary message. Assume we have a key (one byte) and our symmetrical cipher will be XOR. (Just for simplicity (a XOR key XOR key) = a, so encrypt() and decrypt() functions are the same).

public class CryptoExtension implements ExtendedExtension {

    public Frame processIncoming(ExtensionContext context, Frame frame) {
        return lameCrypt(context, frame);

    public Frame processOutgoing(ExtensionContext context, Frame frame) {
        return lameCrypt(context, frame);

    private Frame lameCrypt(ExtensionContext context, Frame frame) {
        if(!frame.isControlFrame() && (frame.getOpcode() == 0x02)) {
            final byte[] payloadData = frame.getPayloadData();
            payloadData[0] ^= (Byte)(context.getProperties().get("key"));

            return Frame.builder(frame).payloadData(payloadData).build();
        } else {
            return frame;

    public List onExtensionNegotiation(ExtensionContext context,
                                                  List requestedParameters) {
        // no params.
        return null;

    public void onHandshakeResponse(ExtensionContext context,
                                    List responseParameters) {

    private void init(ExtensionContext context) {
        context.getProperties().put("key", (byte)0x55);

    public void destroy(ExtensionContext context) {

    public String getName() {
        return "lame-crypto-extension";

    public List getParameters() {
        // no params.
        return null;

You can see that ExtendedExtension is slightly more complicated that original Extension so the implementation has to be also not as straightforward.. on the other hand, it does something. Sample code above shows possible simplification mentioned earlier (one process method will be enough), but please take this as just sample implementation. Real world case is usually more complicated.

Now when we have our CryptoExtension implemented, we want to use it. There is nothing new compared to standard WebSocket Java API, feel free to skip this part if you are already familiar with it. Only programmatic version will be demonstrated. It is possible to do it for annotated version as well, but it is little bit more complicated on the server side and I want to keep the code as compact as possible.

Client registration

ArrayList extensions = new ArrayList();
extensions.add(new CryptoExtension());

final ClientEndpointConfig clientConfiguration =

WebSocketContainer client = ContainerProvider.getWebSocketContainer();
final Session session = client.connectToServer(new Endpoint() {
    public void onOpen(Session session, EndpointConfig config) {
        // ...
}, clientConfiguration, URI.create(/* ... */));

Server registration:

public class CryptoExtensionApplicationConfig implements ServerApplicationConfig {

    public Set getEndpointConfigs(Set<Class<? extends Endpoint>> endpointClasses) {
        Set endpointConfigs = new HashSet();
                ServerEndpointConfig.Builder.create(EchoEndpoint.class, "/echo")
                        .extensions(Arrays.asList(new CryptoExtension())).build()
        return endpointConfigs;

    public Set<Class<?>> getAnnotatedEndpointClasses(Set<Class<?>> scanned) {
        // all scanned endpoints will be used.
        return scanned;

public class EchoEndpoint extends Endpoint {
    public void onOpen(Session session, EndpointConfig config) {
        // ...

CryptoExtensionApplicationConfig will be found by servlets scanning mechanism and automatically used for application configuration, no need to add anything (or even have) web.xml.

Per Message Deflate Extension

The original goal of whole extension support was to implement Permessage extension as defined in draft-ietf-hybi-permessage-compression-15 and we were able to achieve that goal. Well, not completely, current implementation ignores parameters. But it seems like it does not matter much, it was tested with Chrome and it works fine. Also it passes newest version of Autobahn test suite, which includes tests for this extension.

  1. PerMessageDeflateExtension.java (compatible with draft-ietf-hybi-permessage-compression-15, autobahn test suite)
  2. XWebKitDeflateExtension.java (compatible with Chrome and Firefox – same as previous, just different extension name)
  3. PerMessageDeflateTest.java


There are some things which needs to be improved or specified to make this reliable and suitable for real world use. It might not seem as big feature, but it enables lots of use cases not defined in original specification and some of them are clashing little bit, so for now, I kept everything as it was when you are not using extended extensions.

Everything mentioned in this article is already available in Tyrus 1.4-SNAPSHOT and will be part of 1.4 release.

  • Extension / Frame Validation
  • Frame representation – frame types
  • Frame representation – payload representation
  • Frame representation – masking – remove? (current state: container responsibility)
  • Exception handling – processIncoming and processOutgoing methods (current state: exceptions are logged)
  • Exception handling – onExtensionNegotiation
  • Possibility to reject negotiation extension in onExtensionNegotiation (based on extension params)
  • Extension ordering (current state: handshake response header order)
  • Extension resource validation (two extensions using same RSV bit(s) cannot be negotiated)
  • PerMessageDeflate – parameters
  • MultiplexingExtension – implement when (if) ready


There is still lots of decisions to be made and things to do, but it seems like we can implement usable extensions which are supported by newer versions of browsers and containers. PerMessageDeflate extension is nice example of handy feature which can save significant resources.


Posted in java | Tagged , , , , | Leave a comment

Tyrus client – shared container

Current “trunk” version contains one notable feature – shared client container. It can save significant portion of resources on client side if you are creating lots of client connections and there is almost no drawback.

This feature was added as a response to TYRUS-275 and it somehow copies what other containers are doing in the JRS 356 implementation. Specification does not really state which system resources should be reusable (that’s ok, I think this is implementation detail), but it also does not take care of thread pool related settings, which might introduce some inconsistencies among implementations.

WebSocket client implementation in Tyrus re-creates client runtime whenever WebSocketContainer#connectToServer is invoked. This approach gives us some perks like out-of-the-box isolation and relatively low thread count (currently we have 1 selector thread and 2 worker threads). Also it gives you the ability to stop the client runtime – one Session instance is tied to exactly one client runtime, so we can stop it when Session is closed. This seems as a good solution for most of WebSocket client use cases – you usually use java client from application which uses it for communicating with server side and you typically don’t need more than 10 instances (my personal estimate is that more than 90% applications won’t use more than 1 connection). There are several reasons for it – of it is just a client, it needs to preserve server resources – one WebSocket connection means one TCP connection and we don’t really want clients to consume more than needed. Previous statement may be invalidated by WebSocket multiplexing extension, but for now, it is still valid.

On the other hand, WebSocket client implementations in some other containers took another (also correct) approach – they share client runtime for creating all client connections. That means they might not have this strict one session one runtime policy, they cannot really give user way how he to control system resources, but surely it has another advantage – it can handle much more opened connections. Thread pools are share among client sessions which may or may not have some unforeseen consequences, but if its implemented correctly, it should outperform Tyrus solution mentioned in previous paragraph in some use cases, like the one mentioned in TYRUS-275 – performance tests. Reported created simple program which used WebSocket API to create clients and connect to remote endpoint and he measured how many clients can he create (or in other words: how many parallel client connection can be created; I guess that original test case is to measure possible number of concurrent clients on server side, but that does not really matter for this post). Tyrus implementation loose compared to some other and it was exactly because it did not have shared client runtime capability.

I hope that common grounds are established and explained and we can take more detailed look to Tyrus implementation of shared client runtime. Default client implementation is using Grizzly as client container and all the work was done there – client SPI did not need to be changed (phew), so basically there are only some static fields and some basic synchronisation required for this to work. Grizzly part was really easy, it is only about sharing the instance of created TCPNIOTransport. Another small enhancement related to this feature is shared container timeout – if shared client runtime does not handle any connections for set period of time, it will just shutdown and clear all used resources. Everything will be automatically recreated when needed. Default value for this is 30 seconds.

How can you use this feature?

ClientManager client = ClientManager.createClient();

client.getProperties().put(GrizzlyClientContainer.SHARED_CONTAINER, true);

And you are done. You might also want to specify container idle timeout:

client.getProperties().put(GrizzlyClientContainer.SHARED_CONTAINER_IDLE_TIMEOUT, 5);

and last but not least, you might want to specify thread pool sizes used by shared container (please use this feature only when you do know what are you doing. Grizzly by default does not limit max number of used threads, so if you do that, please make sure thread pool size fits your purpose):

client.getProperties().put(GrizzlyClientSocket.SELECTOR_THREAD_POOL_CONFIG, ThreadPoolConfig.defaultConfig().setMaxPoolSize(3));
client.getProperties().put(GrizzlyClientSocket.WORKER_THREAD_POOL_CONFIG, ThreadPoolConfig.defaultConfig().setMaxPoolSize(10));

And that’s it for today. You can use mentioned features with Tyrus 1.4-SNAPSHOT and newer, feel free to comment this post or drop me a note to users@tyrus.java.net with any feedback or suggestion how this can be improved.


Posted in java | Tagged , , , | Leave a comment

Want to work on Tyrus? We are hiring!

Tyrus project is looking for another contributor! If you want to became part of the team which is working on WebSocket API for Java (JSR 356) Reference implementation and related projects and products, this is the time to update your CV and share it with us. This job position is based in Prague, Czech Republic.

Formal job offer can be found on linked in.

If you are interested and have any questions, feel free to contact me directly via this blog or via pavel.bucek at oracle.com.

Posted in other | Tagged , , , | Leave a comment

Tyrus Container SPI

This blog post will be little more technical and insightful into Tyrus internals and won’t be as useful for common users which are just trying to use it for creating their web socket endpoint. I will describe how you can run Tyrus client or server side on virtually any container with a little help. We will start with Client side – it is a little bit simpler I think – then go through Server side and at the end I will present simple in-memory container which is already present in Tyrus workspace and is part of latest release (1.3.3).

Let me start with little background. Tyrus originally started as something built on top of project Grizzly, which serves as NIO layer in Glassfish. Grizzly had (still has) its own API which supports creating web socket endpoints and does even have client implementation. Then JSR 356 was started, Tyrus (originally called “websocket-sdk“) was created and it was just a simple adaptation layer on top of Grizzly container. Then it was decided that this JSR will  be part of Java EE 7. This brought much more visibility to this project and also some more requirements. Tyrus was required to run on any Java EE 7 compliant container, utilising Servlet 3.1 API (upgrade mechanism, non-blocking reads and writes). So another layer was created, this time slightly more low level, because Tyrus was required to handle reading and writing, something which was previously handled by Grizzly. The decision was made, Tyrus adopted some Grizzly code and the Container SPI started to form. Tyrus still kept Grizzly container support and it was able to work with Servet 3.1 API as well. (Just for the sake of completeness – this is about server side. Client part always exclusively used Grizzly as container).

Then another requirement came – it was decided that Tyrus will be integrated into WebLogic server (it will be part of upcoming 12.1.3 release). Initial integration used lots of Tyrus internals which was kind of scary, because future integrations might require significant amount of time, especially when considering some not trivial features we plan for Tyrus (Extension support, subprotocols, etc). WebLogic 12.1.3 does not contain Grizzly nor Servlet 3.1 implementation, so we needed to have something which will be more stable than any other Tyrus internal class.

Small note – this is final version of the SPI for now, it does not mean that it won’t change. We might need to extend it to support some new features or fix bugs. Also there is no discovery mechanism in place (yet), so implementors of these SPI will have direct dependency on some Tyrus internal class(es). These internal classes (TyrusWebSocketEngine, etc.) may be changed, but there is higher resistance mode for these, so it shouldn’t be done that often and if we can achieve backwards compatibility, we will. Discovery mechanism will most likely be introduced sometime later..

Enough with this history lesson, let’s get to the code part.

Client SPI

Client side container is basically only about implementing ClientContainer. Method openClientSocket will be called when ClientManager needs to connect to server endpoint and following sequence of calls is then expected:

    public class MyClientContainer implements ClientContainer {
        public void openClientSocket(String url,
                                     ClientEndpointConfig cec,
                                     Map<String, Object> properties,
                                     ClientEngine clientEngine)
                throws DeploymentException, IOException {

            // initialize container, open connection
            final UpgradeRequest upgradeRequest =
                            new ClientEngine.TimeoutHandler() {

            // handle ssl and proxies here if required
            // write upgradeRequest
            // wait for response, create UpgradeResponse instance
            // create custom writer
            // create connection close listener
            // get Connection
            final Connection connection = clientEngine.processResponse(
                    upgradeResponse, writer, closeListener

        void processIncomingData(ByteBuffer data) {
            // get read handler
            final ReadHandler readHandler = connection.getReadHandler();

            // call readHandler.handle on anything received

That’s it. ReadHandler and Writer classes are pretty straightforward, so no need to go there, only last important thing is how we can register ClientContainer so the runtime will use it. Here you need to implement ContainerProvider from JSR-356 API:

    // registered via META-INF/services
    public class MyContainerProvider extends ContainerProvider {
        protected WebSocketContainer getContainer() {
            return ClientManager.createClient(MyClientContainer.class.getName());

Note “registered via META-INF/services” means that you need to provide file named “javax.websocket.ContainerProvider” under META-INF/services directory and put fully classified class name of your implementation. Then all applications which run “ContainerProvider.getWebSocketContainer();” will get the client using your ClientContainer to make connections. You can always just use ClientManager directly if you need (it implements WebSocketContainer, so it is only about modifying the initial client instantiation).

Server SPI

Server side is slightly more complicated for obvious reasons – server bootstrap is more complicated – more than one endpoint can be deployed. Also it needs to handle more than one connection and there are some features defined in JSR 356 which complicate things a little bit.

Firstly you need to create ServerContainer. Tyrus has its own implementation – TyrusServerContainer. It has two abstract methods which needs to be implemented. Tyrus also comes to help you – these methods are implemented in TyrusWebSocketEngine, so you most likely will create instance of this class for your ServerContainer descendant. Then you are ready to start created container and you can accept incoming connections.

ServerContainer and WebSocketEngine instance you created should be used during whole life of deployed application. All objects created from this point on are related directly to ongoing connection / web socket session app.

WebSocketEngine has upgrade method which will validate incoming HTTP request and creates outgoing response. It returns UpgradeInfo, which has status (HANSDHAKE_FAILED, NOT_APPLICABLE, SUCCESS) and can create connection in case status is SUCCESS. HANDSHAKE_FAILED means there were some errors in HTTP header, NOT_APPLICABLE means that passed request is not upgrade request and you might want to pass it to further in the processing chain. For creating a connection, you need to have Writer implementation (very same interface is used on client side). Then the processing is simple – you just read the data from the connection, call connection.getReadHandler().handle(ByteBuffer), data is written through provided Writer implementation. And that’s pretty much it.

Sample code for this is not as simple as in client case and there would be left-out things, so lets skip it in this section. InMemory container implements both client and server in the easiest way possible, so if you are still interested, just continue reading.

In-memory container

This is nothing else than a simple test for both SPIs. It can be used for fast unit/e2e testing if you don’t need anything else than Tyrus runtime and you are fine that each connectToServer method call will create its own “server” container (you cannot connect from two clients to one in-memory server).

The best way how to explore that code would be check it out, open in your favourite IDE. You should be also able to see javadocs and maybe start debugging session to really see what is called when and so on.

Links to InMemory container implementation:

And I think that was enough for this post. Feel free to ask about whatever you want to know about Tyrus or WebSocket implementation. As almost always, you can find list of relevant links at the very bottom.


Posted in java | Tagged , , , , , | Leave a comment

Optimized WebSocket broadcast

Broadcast scenario is one of the most common use cases for WebSocket server-side code, so we are going to evaluate usability of current version of WebSocket API for Java to do that and suggest some improvements.

Please note that this post is experimental by its nature. You can use Tyrus features mentioned in this article, but anything can change any time, without warning.

When speaking about broadcast, let’s define what that actually is. When message is broadcasted,  it means that it is sent to all connected clients. Easy right? Common WebSocket sample application is chat (Tyrus is not an exception, see ./samples/chat) which does exactly that – when client sends a message to server endpoint, message gets re-sent to all clients so they can see it.

If we ignore authentication and authorisation, we can shrink server-side implementation to following code:

public void onMessage(Session s, String m) throws IOException {
  for (Session session : s.getOpenSessions()) {

Which works well and provides expected functionality. Underlying code must process the message for every connected client, so the DataFrame which will be sent on the is constructed n-times (where n is number of connected clients). Everything now depends on processing time required for creating single data frame. That operation is not expensive per say, but just the fact it needs to be invoked that many times creates a bottle neck from it. Another important fact is that the WebSocket connection has no state, so once created data frame can be sent to as many clients as you want. So in another words, we don’t really need to do create data frame multiple times, especially when we know that the message is the same for all connected clients.

WebSocket API does not allow consumers to access messages on data frame level and also does not provide way how to send already constructed data frame. That might come in some next version of the specification… so what can we do now?

If you are using Tyrus (1.3 or newer), you can try an optimized version of the same use-case:

public void onMessage(Session s, String m) {
  ((TyrusSession) s).broadcast(m);

This way, data frame will be constructed only once which will save server-side resources and additionally clients will receive broadcasted message in shorter period. “broadcast” method returns Map<Session, Future<?>> which can be used for getting the info about which message was already send and which wasn’t. Version with callback is not yet available, might be added later (if you’d want to have this feature, please send us a note to users@tyrus.java.net).

I don’t have any exact measurements to confirm performance gain when using Tyrus broadcast, but seems like it may be significant, especially for higher count of connected clients.

(note to JDK8 users: the first scenario can also be improved by using fork/join framework. It was intentionally ignored in this article, since Tyrus need to stick with Java SE 7 for now)

If you have any questions, don’t hesitate and ask at users@tyrus.java.net.

And, as always, list of related links:

Posted in java | Tagged , , , | Leave a comment