Servidor pronto para produção de WebSockets em Java?

EDIT : removido referência ao C # como a única resposta aceita é sobre Java. Se alguém precisar de informações sobre a implementação do servidor websocket em C #, faça uma nova pergunta.

Você conhece a estrutura “produção pronta” para criar o WebSockets Server em Java? Eu encontrei uma biblioteca http://nugget.codeplex.com/ mas eu não sabia como é estável e rápido.

Para Java, confira este post informativo . Copie e cole de lá:

  • Jetty WebSocket Server – O Jetty suporta WebSockets desde setembro do ano passado. Esta parece ser uma boa opção.
  • Resina Caucho
  • jWebSocket
  • GlassFish / Grizzly (veja aqui um DZone postando aqui )
  • JBoss Netty (veja patch aqui )
  • Webbit

Fora dessas opções, acho que Jetty e Resin são os mais maduros e estáveis. No entanto, sempre bom fazer seu próprio teste.

A resposta aceita é de 3 anos, com o recente lançamento do JEE7, agora todos os contêineres da Web que implementam o servert 3.1 suportarão websocket via pacote padrão da API ( javax.websocket ).

O código a seguir mostra um exemplo de como implementar o websocket usando o 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()); } } 

Exemplo em detalhes aqui .

Contêiner da Web que suporta o Websocket:

  • Tomcat 8
  • WildFly (anteriormente Jboss AS)
  • Glassfish 4.0
  • e muito mais

A opção Vert.x também vale a pena considerar.

Criar um servidor ws pode ser tão simples quanto

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

ou

 vertx.createHttpServer().websocketHandler(new Handler() { @Override public void handle(final ServerWebSocket ws) { logger.info("ws connection established with " + ws.remoteAddress()); ws.dataHandler(new Handler() { @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>() { @Override public void handle(AsyncResult event) { logger.info("ws server is up and listening on port " + port); } }); 

Para mais detalhes veja aqui http://vertx.io/docs/vertx-core/java/#_websockets

Assim, pode-se escrever seu próprio servidor WebSocket com o Vert.x, empacotá-lo como FatJar e executá-lo sozinho.

Ou você pode incorporar env Vert.x. em seu aplicativo e implemente seu verticle (que implementa o servidor ws) programaticamente.


Outra alternativa é o Undertow do servidor web do JBoss. Que é facilmente incorporável em aplicativos.

Adicione estas dependencies:

  io.undertow undertow-servlet ${version.io.undertow}   io.undertow undertow-websockets-jsr ${version.io.undertow}  

E aqui está um exemplo de servidor ws:

 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(); 

Dê uma olhada no quadro do Bristleback . É uma sobreposição de alto nível para servidores Java Websocket comumente usados, como Jetty, Netty ou Tomcat. Se você gosta do Spring Framework, você deve definitivamente tentar o Bristleback!

Disclaimer: Eu sou um colaborador no projeto Framework Bristleback.

O Apache Tomcat 8.0 implementa a API WebSockets 1.1 ( JSR-356 ). Você pode até jogar com exemplos após a instalação, navegando para a pasta de exemplos: há echo chat e jogo de cobra.

JETTY

Passei a semana passada criticando como criar um servidor WebSocket. Finalmente tenho algo para trabalhar espero que isso ajude. Ele usa bibliotecas do Jetty (jars).

Arquivo WebRTC_IceServer.java

 package com.evanstools; import org.eclipse.jetty.server.*; import org.eclipse.jetty.websocket.server.*; public class WebRTC_IceServer{ public static void main(String[] args){ try{ //////////////////////// if(args.length == 0){ System.out.printf("%s%n","WebRTC_IceServer [port]"); return; } Server server = new Server(Integer.parseInt(args[0])); WebSocketHandler.Simple webSocketHandlerSimple = new WebSocketHandler.Simple(WebsocketPOJO.class); server.setHandler(webSocketHandlerSimple); server.start(); server.join(); //////////////////////// }catch(Exception w){w.printStackTrace();} } } 

Arquivo WebsocketPOJO.java

 package com.evanstools; import org.eclipse.jetty.websocket.api.annotations.*; import org.eclipse.jetty.websocket.api.Session; //The class must be not abstract and public. @WebSocket public class WebsocketPOJO{ //Flags one method in the class as receiving the On Connect event. //Method must be public, not abstract, return void, and have a single Session parameter. @OnWebSocketConnect public void onWebSocketConnect(Session session){ System.out.printf("%s%n","test client connected"); } //Flags one method in the class as receiving the On Close event. //Method signature must be public, not abstract, and return void. //The method parameters: ////Session (optional) ////int closeCode (required) ////String closeReason (required) @OnWebSocketClose public void OnWebSocketClose(Session session,int closeCode,String closeReason){} //Flags up to 2 methods in the class as receiving On Message events. //You can have 1 method for TEXT messages, and 1 method for BINARY messages. //Method signature must be public, not abstract, and return void. //The method parameters for Text messages: ////Session (optional) ////String text (required) //The method parameters for Binary messages: ////Session (optional) ////byte buf[] (required) ////int offset (required) ////int length (required) @OnWebSocketMessage public void onWebSocketMessageString(Session session, String text){} //Flags one method in the class as receiving Error events from the WebSocket implementation. //Method signatures must be public, not abstract, and return void. //The method parameters: ////Session (optional) ////Throwable cause (required) //@OnWebSocketError //Flags one method in the class as receiving Frame events from the WebSocket implementation after they have been processed by any extensions declared during the Upgrade handshake. //Method signatures must be public, not abstract, and return void. //The method parameters: ////Session (optional) ///Frame (required) //The Frame received will be notified on this method, then be processed by Jetty, possibly resulting in another event, such as On Close, or On Message. Changes to the Frame will not be seen by Jetty. //@OnWebSocketFrame }