WebSockets production ready server in Java?

EDIT: removed reference to C# as the only accepted answer is about Java. If someone needs information about websocket server implementation in C#, ask a new question.

Do you know "production ready" framework for creating WebSockets Server in Java? I found one library http://nugget.codeplex.com/ but i did not know how it is stable and fast.


Solution 1:

The accepted answer is 3 years old, with the recent release of JEE7, now every Web Containers that implement servert 3.1 will support websocket via standard API (javax.websocket) package.

The following code show example how to implement websocket using JEE7:

import java.util.logging.Level;
import java.util.logging.Logger;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;

@ServerEndpoint(value = "/chat")
public class ChatServer {

    private static final Logger LOGGER = 
            Logger.getLogger(ChatServer.class.getName());

    @OnOpen
    public void onOpen(Session session) {
        LOGGER.log(Level.INFO, "New connection with client: {0}", 
                session.getId());
    }

    @OnMessage
    public String onMessage(String message, Session session) {
        LOGGER.log(Level.INFO, "New message from Client [{0}]: {1}", 
                new Object[] {session.getId(), message});
        return "Server received [" + message + "]";
    }

    @OnClose
    public void onClose(Session session) {
        LOGGER.log(Level.INFO, "Close connection for client: {0}", 
                session.getId());
    }

    @OnError
    public void onError(Throwable exception, Session session) {
        LOGGER.log(Level.INFO, "Error for client: {0}", session.getId());
    }
}

Example in details here.

Web Container that support Websocket:

  • Tomcat 8
  • WildFly (Previously Jboss AS)
  • Glassfish 4.0
  • and much more

Solution 2:

For Java, check out this informative post. Copy-paste from there:

  • Jetty WebSocket Server – Jetty has supported WebSockets since last September. This seems to be a good option.
  • Caucho Resin
  • jWebSocket
  • GlassFish/Grizzly (see a DZone posting on it here)
  • JBoss Netty (see patch here)
  • Webbit

Out of these options, I guess Jetty and Resin are the most mature and stable. However, always good to do your own testing.

Solution 3:

The Vert.x option is also worth considering.

Creating a ws server can be as simple as

vertx.websocketHandler(new Handler<ServerWebSocket>() {
    public void handle(ServerWebSocket ws) {
        // A WebSocket has connected!
    }
}).listen(8080);

or

vertx.createHttpServer().websocketHandler(new Handler<ServerWebSocket>() {
        @Override
        public void handle(final ServerWebSocket ws) {
            logger.info("ws connection established with " + ws.remoteAddress());
            ws.dataHandler(new Handler<Buffer>() {
                @Override
                public void handle(Buffer data) {
                    JsonObject item = new JsonObject(data.toString());
                    logger.info("data in -> " + item.encodePrettily());
                       // if you want to write something back in response to the client
                    //ws.writeTextFrame(...);
            }
            });
        }
    }).listen(port, new Handler<AsyncResult<HttpServer>>() {
        @Override
        public void handle(AsyncResult<HttpServer> event) {
            logger.info("ws server is up and listening on port " + port);
        }
    });

For more details look here http://vertx.io/docs/vertx-core/java/#_websockets

So one can write his own WebSocket server with Vert.x, package it as FatJar, and run it on its own.

Or you can embed Vert.x env. in your app, and deploy your verticle (that implements the ws server) programmatically.


Another alternative is JBoss's web server Undertow. Which is easily embeddable in applications.

Add these dependencies:

<dependency>
  <groupId>io.undertow</groupId>
  <artifactId>undertow-servlet</artifactId>
  <version>${version.io.undertow}</version>
</dependency>

<dependency>
  <groupId>io.undertow</groupId>
  <artifactId>undertow-websockets-jsr</artifactId>
  <version>${version.io.undertow}</version>
</dependency>

And here's a sample ws server:

Undertow server = Undertow.builder()
            .addHttpListener(8080, "localhost")
            .setHandler(path()
                    .addPrefixPath("/myapp", websocket(new WebSocketConnectionCallback() {

                        @Override
                        public void onConnect(WebSocketHttpExchange exchange, WebSocketChannel channel) {
                            channel.getReceiveSetter().set(new AbstractReceiveListener() {

                                @Override
                                protected void onFullTextMessage(WebSocketChannel channel, BufferedTextMessage message) {
                                    final String messageData = message.getData();
                                    for (WebSocketChannel session : channel.getPeerConnections()) {
                                        WebSockets.sendText(messageData, session, null);
                                    }
                                }
                            });
                            channel.resumeReceives();
                        }
                    }))
            .build();

    server.start();

Solution 4:

Take a look at the Bristleback Framework. It is a high level overlay for commonly used Java Websocket Servers, like Jetty, Netty or Tomcat. If you like Spring Framework, you must definitely try Bristleback!

Disclaimer: I'm a contributor in Bristleback Framework project.