Java 如何在jetty容器中设置JSR356 WebSocket

Java 如何在jetty容器中设置JSR356 WebSocket,java,websocket,jetty,jsr356,Java,Websocket,Jetty,Jsr356,我看到了很多关于如何使用某种嵌入式web服务器设置JSR356 WebSocket的教程 但是我想在部署到独立jetty安装的现有WAR中添加一些WebSocket,jetty jetty-9.2.3.v20140905,我可以找到很少的信息。我不知道是什么阻止它工作。据我所知,带注释的服务器端点应该由jetty自动处理 服务器端点: @ServerEndpoint(value = "/myendpoint") public class MyServerEndpoint {

我看到了很多关于如何使用某种嵌入式web服务器设置JSR356 WebSocket的教程

但是我想在部署到独立jetty安装的现有WAR中添加一些WebSocket,jetty jetty-9.2.3.v20140905,我可以找到很少的信息。我不知道是什么阻止它工作。据我所知,带注释的服务器端点应该由jetty自动处理

服务器端点:

    @ServerEndpoint(value = "/myendpoint")
public class MyServerEndpoint {     
    private Logger logger = Logger.getLogger(this.getClass().getName());     

    @OnOpen 
    public void onOpen(Session s) {
        logger.info("Server Connected ... " + s.getId());
        s.getAsyncRemote().sendText("You are connected to the websocket server");   
    }        

    @OnMessage  
    public void onMessage(String message, Session session) {

        // Sent the message back to all connected users             
        logger.info("Server Session " + session + " Received string message " + message);

        for(Session s: session.getOpenSessions()) {     
            if (s.isOpen()) { 
                s.getAsyncRemote().sendText(message + " server response");
            }       
        }   
    }        

    @OnClose    
    public void onClose(Session session, CloseReason reason) {
        logger.info("Server Session " + session + " closed for reason " + reason);
    }   
}
客户点:

    @ClientEndpoint
public class MyClientEndpoint {     
    private Logger logger = Logger.getLogger(this.getClass().getName());     

    @OnOpen 
    public void onOpen(Session s) {
        logger.info("Client Connected ... " + s.getId());
        s.getAsyncRemote().sendText("hello from the client!");  
    }        

    @OnMessage  
    public void onMessage(String message, Session session) {

        logger.info("Client Session " + session + " Received string message " + message);       

    }        

    @OnClose    
    public void onClose(Session session, CloseReason reason) {
        logger.info("Client Session " + session + " closed for reason " + reason);
    }   
}
下面是将客户机连接到服务器的代码(在某些现有方法中运行)

    WebSocketContainer container = ContainerProvider.getWebSocketContainer();
    String uri = "ws://localhost:8080/myWar/myendpoint"; 
    container.connectToServer(MyClientEndpoint.class, URI.create(uri));
然而,旋转jetty会在connectToServer线路上出现错误

2014-10-30 12:26:58.658:WARN:oeja.ServletContainerInitializersStarter:main: 
org.eclipse.jetty.websocket.api.InvalidWebSocketException: Unable to instantiate websocket: class java.lang.Class
at   org.eclipse.jetty.websocket.jsr356.ClientContainer.newClientEndpointInstance(ClientContainer.java:311)
    at org.eclipse.jetty.websocket.jsr356.ClientContainer.connectToServer(ClientContainer.java:172)
我所能想到的就是URI不正确。如果jetty在8080上运行,my.war被命名为myWar,而我的端点被命名为myendpoint…这不是正确的URI吗


是否必须执行一些附加步骤来“激活”服务器端点以侦听连接?我一定错过了什么明显的东西

奇怪的是,你的错误信息

org.eclipse.jetty.websocket.api.InvalidWebSocketException: 
  Unable to instantiate websocket: class java.lang.Class
意味着websocket实现被交给了一个原始java.lang.Class进行实例化。 那是行不通的

这也意味着没有尝试连接,因为WebSocket类本身非常糟糕,无法进行连接

下面是一个简短(有效且有效)的示例,展示了它的用法

package jetty.jsr356;
导入java.io.IOException;
导入java.net.URI;
导入java.util.concurrent.CountDownLatch;
导入javax.websocket.ClientEndpoint;
导入javax.websocket.CloseReason;
导入javax.websocket.CloseReason.CloseCodes;
导入javax.websocket.ContainerProvider;
导入javax.websocket.OnClose;
导入javax.websocket.OnMessage;
导入javax.websocket.OnOpen;
导入javax.websocket.Session;
导入javax.websocket.WebSocketContainer;
@客户点
公共类TestClientAnnotatedClass
{
专用静态倒计时闩锁关闭闩锁=新倒计时闩锁(1);
@奥诺彭
公共开放(会议)
{
System.out.println(“@OnOpen-”+会话);
尝试
{
session.getBasicRemote().sendText(“用JavaWebSocket摇滚”);
}
捕获(IOE异常)
{
e、 printStackTrace();
}
}
@OnMessage
公共void onMessage(会话,字符串msg)
{
System.out.println(“@OnMessage-[“+msg+”]);
尝试
{
session.close(新的CloseReason(CloseCodes.NORMAL_close,“谢谢”));
}
捕获(IOE异常)
{
e、 printStackTrace();
}
}
@一次
公共作废关闭(关闭原因关闭)
{
System.out.println(“@OnClose-”+close);
closelock.countDown();
}
公共静态void main(字符串[]args)
{
尝试
{
WebSocketContainer ws=ContainerProvider.getWebSocketContainer();
connectToServer(TestClientAnnotatedClass.class,新URI(“ws://echo.websocket.org/?encoding=text”);
closelock.wait();
}
捕获(可丢弃的t)
{
t、 printStackTrace();
}
}
}
您将看到与此类似的输出

2014-10-30 11:34:19.197:INFO::main: Logging initialized @71ms
@OnOpen - WebSocketSession[websocket=JsrAnnotatedEventDriver[websocket=jetty.jsr356.TestClientAnnotatedClass@5cca5f2c],behavior=CLIENT,connection=WebSocketClientConnection@6a2e714b{IDLE}{f=Flusher[queueSize=0,aggregateSize=0,failure=null],g=Generator[CLIENT,validating],p=Parser@55465b1f[ExtensionStack,s=START,c=0,len=0,f=null,p=WebSocketPolicy@7e087bf5[behavior=CLIENT,maxTextMessageSize=65536,maxTextMessageBufferSize=32768,maxBinaryMessageSize=65536,maxBinaryMessageBufferSize=32768,asyncWriteTimeout=60000,idleTimeout=300000,inputBufferSize=4096]]},remote=WebSocketRemoteEndpoint@5f025277[batching=true],incoming=JsrAnnotatedEventDriver[websocket=jetty.jsr356.TestClientAnnotatedClass@5cca5f2c],outgoing=ExtensionStack[queueSize=0,extensions=[],incoming=org.eclipse.jetty.websocket.jsr356.JsrSession,outgoing=org.eclipse.jetty.websocket.client.io.WebSocketClientConnection]]
@OnMessage - [Rock it with Java WebSocket]
@OnClose - CloseReason[1000,Thanks]

Jetty使用反射创建带注释的客户端端点实例(请参见),但是Java无法以这种方式实例化非静态内部类。实际原因异常类似于
java.lang.NoSuchMethodException:.OuterClass$InnerClass。(
但它被吞没了


解决方案:带注释的端点类不应是嵌套的或嵌套的静态(内部)类。

谢谢。然而,我得到了同样的错误。org.eclipse.jetty.websocket.api.InvalidWebSocketException:无法实例化websocket:class java.lang.class我想知道问题是否出在我的jetty安装上,而不是我正在使用的代码上。我从“main”函数中提取了代码,并将其放在war文件中的另一个函数中,这不会有什么区别吗?让我看看是否可以为您组合一个示例项目。