在嵌入式Jetty 9上的带注释的@WebSocket类中访问HttpSession

在嵌入式Jetty 9上的带注释的@WebSocket类中访问HttpSession,websocket,embedded-jetty,jetty-9,Websocket,Embedded Jetty,Jetty 9,如何访问Jetty 9中带注释的@WebSocket类中的HttpSession对象 我发现了如何使用@ServerEndpoint annotation实现这一点,如下所示: 使用@WebSocket注释,就像在下面的类中一样,我该如何做呢 @WebSocket public class AuctionWebSocket { // NEED TO ACCESS HttpSession OBJECT INSIDE THESE METHODS: @OnWebSocketConn

如何访问Jetty 9中带注释的@WebSocket类中的HttpSession对象

我发现了如何使用@ServerEndpoint annotation实现这一点,如下所示:

使用@WebSocket注释,就像在下面的类中一样,我该如何做呢

@WebSocket
public class AuctionWebSocket {

    // NEED TO ACCESS HttpSession OBJECT INSIDE THESE METHODS:

    @OnWebSocketConnect
    public void onConnect(Session session) {
        System.out.println("onConnect...");        
    }

    @OnWebSocketMessage
    public void onMessage(String message) {        
        System.out.println("Message: " + message);
    }    

    @OnWebSocketClose
    public void onClose(int statusCode, String reason) {
        System.out.println("onClose...");        
    }

    @OnWebSocketError
    public void onError(Throwable t) {
        System.out.println("onError...");        
    }    
}
在方法
onConnect(Session Session)
中,我试图调用
Session.getUpgradeRequest().getSession()
,它总是返回
null

为了便于了解,以下是我如何启动嵌入式Jetty 9:

public class Main {

    public static void main(String[] args) throws Exception {

        String webPort = System.getenv("PORT");
        if (webPort == null || webPort.isEmpty()) {
            webPort = "8080";
        }

        Server server = new Server(Integer.parseInt(webPort));

        ClassList classlist = org.eclipse.jetty.webapp.Configuration.ClassList.setServerDefault(server);
        classlist.addBefore("org.eclipse.jetty.webapp.JettyWebXmlConfiguration",
                "org.eclipse.jetty.annotations.AnnotationConfiguration");

        WebAppContext wac = new WebAppContext();
        String webappDirLocation = "./src/main/webapp/";

        wac.setAttribute("org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern", ".*/classes/.*");
        wac.setDescriptor(webappDirLocation + "/WEB-INF/web.xml");
        wac.setBaseResource(new ResourceCollection(new String[]{webappDirLocation, "./target"}));
        wac.setResourceAlias("/WEB-INF/classes/", "/classes/");
        wac.setContextPath("/");
        wac.setParentLoaderPriority(true);

        /*
         * WebSocket handler.
         */
        WebSocketHandler wsh = new WebSocketHandler() {

            @Override
            public void configure(WebSocketServletFactory wssf) {
                wssf.register(AuctionWebSocket.class);
            }
        };

        ContextHandler wsc = new ContextHandler();
        wsc.setContextPath("/auction-notifications");
        wsc.setHandler(wsh);

        ContextHandlerCollection chc = new ContextHandlerCollection();
        chc.setHandlers(new Handler[]{wac, wsc});

        server.setHandler(chc);

        server.start();
        server.join();
    }

}
如果你需要更多信息,请告诉我

任何帮助都将不胜感激


提前感谢。

您需要使用WebSocketCreator概念

首先,在
WebSocketServlet
中配置的
WebSocketServletFactory
中设置所选的
WebSocketCreator

公共类MySessionSocketServlet扩展了WebSocketServlet
{
@凌驾
公共void配置(WebSocketServletFactory工厂)
{
factory.getPolicy().setIdleTimeout(30000);
setCreator(新的MySessionSocketCreator());
}
}
接下来,您需要在升级过程中获取
HttpSession
,并将其传递到您正在创建的WebSocket对象中

公共类MySessionSocketCreator实现WebSocketCreator
{
@凌驾
公共对象createWebSocket(ServletUpgradeRequest请求、ServletUpgradeResponse响应)
{
HttpSession HttpSession=req.getSession();
返回新的MySessionSocket(httpSession);
}
}
最后,只需在您自己的
WebSocket
中跟踪该
HttpSession

@WebSocket
公共类MySessionSocket
{
私有HttpSession HttpSession;
非公开会议;
公共MySessionSocket(HttpSessionHttpSession)
{
this.httpSession=httpSession;
}
@OnWebSocketConnect
公共打开(会话wsSession)
{
this.wsSession=wsSession;
}
}
注意:
HttpSession
可能会在WebSocket处于活动状态时过期并被清除。此外,此时的
HttpSession
内容不能保证与其他web操作的更改保持同步(这主要取决于您在服务器端使用的会话存储/缓存技术)


还有一个注意事项:不要急于在套接字实例中存储/跟踪
ServletUpgradeRequest
对象,由于该对象被Jetty适当地回收和清理。

我只想访问
HttpSession
中的登录用户,以维护用户及其各自websocket会话的地图,以便进一步通信。作为一种解决方法,在
onopen
javascript回调中,我向websocket发送一条带有用户id的消息,如下
ws.onopen=function(){ws.send(“onopen:+sessionId_u1;)}WebSocketCreator
概念访问
HttpSession
好吗?我有一些类似的要求(我的要求是,如果同一用户在多个选项卡中打开应用程序,那么会创建多个websocket会话,因此如果用户在一个选项卡中注销,我想从所有选项卡中注销用户),您能帮助解决问题吗?@Jayesh请为新主题打开一个新问题
HttpSession HttpSession=req.getSession()
向我返回null,我想这是因为请求已经升级了。我用
HttpSession HttpSession=req.getHttpServletRequest().getSession()解决了这个问题