Java中生产就绪的WebSockets服务器?

30

编辑:删除关于C#的提及,因为唯一被接受的答案是有关Java的。如果有人需要关于C#中websocket服务器实现的信息,请提出新问题。

你知道用于创建Java WebSockets服务器的“生产就绪”框架吗?我找到了一个库http://nugget.codeplex.com/,但我不知道它的稳定性和速度如何。

6个回答

49

被认可的答案已经有3年了,随着JEE7的最新发布,现在每个实现服务器3.1的Web容器都将通过标准API(javax.websocket)包支持websocket。

以下代码展示了如何使用JEE7实现websocket的示例:

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

详细示例可以在这里找到。

支持Websocket的Web容器:


onbinary 是否缺失或不是API的一部分? - R.Moeller

35

好的,因为Jetty WebSockets(我可以信任它的实现),我接受了你的答案;)谢谢!;) - Edward83

5

考虑使用Vert.x选项。

创建WebSocket服务器可以非常简单,例如:

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

或者

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

更多细节请查看http://vertx.io/docs/vertx-core/java/#_websockets

使用Vert.x,可以编写自己的WebSocket服务器,将其打包为FatJar,然后独立运行。

或者,在您的应用程序中嵌入Vert.x环境,并通过编程方式部署实现ws服务器的垂直线程。


另一种选择是JBoss的Web服务器Undertow,它很容易在应用程序中嵌入。

添加以下依赖项:

<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>

以下是一个样例 WebSocket 服务器:

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

您提供的Vert.x WebSockets文档链接似乎已失效。 这个链接可以使用:http://vertx.io/docs/vertx-core/java/#_websockets - Pampy
@Pampy,你说的对,我确认了。已经更新了。非常感谢你! - aymens

2
请查看刚烈背部框架。它是一个高级覆盖层,用于常用的Java Websocket服务器,如Jetty,Netty或Tomcat。如果您喜欢Spring Framework,则一定要尝试Bristleback!

免责声明:我是Bristleback Framework项目的贡献者。


当然,该项目托管在 GitHub,并且根据 LGPL 许可证进行授权。 - voitec

0

Apache Tomcat 8.0 实现了 WebSockets 1.1 API (JSR-356)。安装后,您甚至可以通过导航到示例文件夹来尝试示例:其中包括回声聊天和贪吃蛇游戏。


0

JETTY

我花了过去一周的时间思考如何制作一个WebSocket服务器。最终找到了一些可行的方法,希望这能有所帮助。它使用了Jetty(jars)库。

文件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();}
}
}

文件 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
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接