2014-12-27 90 views
2

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

我发现了如何使用它@ServerEndpoint注释,就像在这里做:在类波纹管HttpSession from @ServerEndpoint

使用@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

有关的信息的缘故,这里是我开始嵌入码头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(); 
    } 

} 

让我知道如果你需要更多的信息。

任何帮助将不胜感激。

在此先感谢。

回答

4

你会想使用WebSocketCreator的概念。

首先你要定义你所选择的WebSocketCreator在您在WebSocketServlet

public class MySessionSocketServlet extends WebSocketServlet 
{ 
    @Override 
    public void configure(WebSocketServletFactory factory) 
    { 
     factory.getPolicy().setIdleTimeout(30000); 
     factory.setCreator(new MySessionSocketCreator()); 
    } 
} 

下一页配置WebSocketServletFactory,你会希望在升级过程中抢HttpSession并把它传递到WebSocket的对象,您正在创造。

public class MySessionSocketCreator implements WebSocketCreator 
{ 
    @Override 
    public Object createWebSocket(ServletUpgradeRequest req, ServletUpgradeResponse resp) 
    { 
     HttpSession httpSession = req.getSession(); 
     return new MySessionSocket(httpSession); 
    } 
} 

最后,刚在你自己的WebSocket的轨道,HttpSession的。

@WebSocket 
public class MySessionSocket 
{ 
    private HttpSession httpSession; 
    private Session wsSession; 

    public MySessionSocket(HttpSession httpSession) 
    { 
     this.httpSession = httpSession; 
    } 

    @OnWebSocketConnect 
    public void onOpen(Session wsSession) 
    { 
     this.wsSession = wsSession; 
    } 
} 

值得注意的是:在HttpSession可以届满,被清理和清理而WebSocket的是积极的。此外,此时的内容不保证与其他网络操作的更改保持同步(这主要取决于您在服务器端使用的会话存储/缓存技术)

还有一个注意事项:抗拒在您的套接字实例中存储/跟踪ServletUpgradeRequest对象的冲动,因为此对象被Jetty正确地回收和清除。

+0

我只想访问“HttpSession”中记录的用户以维护用户及其相应websocket会话的地图以进一步通信。作为一种解决方法,在'onopen' javascript回调函数中,我使用用户标识向WebSocket发送消息,如下所示:ws.onopen = function(){ws.send(“onopen:”+ sessionId_); };' 然后,我在服务器上进行用户和websocket会话之间的关联。 您认为这种方法比通过WebSocketCreator概念访问'HttpSession'好吗? – reinaldoluckman 2014-12-29 23:40:31

+0

我有类似的要求,(我的要求是,如果同一用户在多个选项卡中打开应用程序,则会创建多个websocket会话,因此如果用户在一个选项卡中注销,我想从所有选项卡注销用户),请问您可以帮助你如何解决问题? – Jayesh 2017-02-26 04:53:12

+0

@Jayesh请为新主题打开一个新问题 – 2017-02-27 14:08:25