001    package org.granite.gravity.jetty8;
002    
003    import javax.servlet.ServletContext;
004    import javax.servlet.http.HttpServletRequest;
005    import javax.servlet.http.HttpSession;
006    
007    import org.eclipse.jetty.websocket.WebSocket;
008    import org.eclipse.jetty.websocket.WebSocketHandler;
009    import org.granite.context.GraniteContext;
010    import org.granite.gravity.Gravity;
011    import org.granite.gravity.GravityManager;
012    import org.granite.logging.Logger;
013    import org.granite.messaging.webapp.ServletGraniteContext;
014    
015    import flex.messaging.messages.CommandMessage;
016    import flex.messaging.messages.Message;
017    
018    public class JettyWebSocketHandler extends WebSocketHandler {
019            
020            private static final Logger log = Logger.getLogger(JettyWebSocketHandler.class);
021            
022            private final ServletContext servletContext;
023            
024            public JettyWebSocketHandler(ServletContext servletContext) {
025                    this.servletContext = servletContext;
026            }
027            
028        public WebSocket doWebSocketConnect(HttpServletRequest request, String protocol) {
029            if (!"org.granite.gravity".equals(protocol))
030                    return null;
031            
032                    Gravity gravity = GravityManager.getGravity(servletContext);
033                    JettyWebSocketChannelFactory channelFactory = new JettyWebSocketChannelFactory(gravity, servletContext);
034                    
035                    try {
036                            String connectMessageId = request.getHeader("connectId") != null ? request.getHeader("connectId") : request.getParameter("connectId");
037                            String clientId = request.getHeader("GDSClientId") != null ? request.getHeader("GDSClientId") : request.getParameter("GDSClientId");
038                            String clientType = request.getHeader("GDSClientType") != null ? request.getHeader("GDSClientType") : request.getParameter("GDSClientType");
039                            String sessionId = null;
040                            HttpSession session = request.getSession(false);
041                            if (session != null) {
042                            ServletGraniteContext.createThreadInstance(gravity.getGraniteConfig(), gravity.getServicesConfig(), 
043                                            this.servletContext, session, clientType);
044                            
045                                    sessionId = session.getId();
046                            }
047                            else {
048                                    for (int i = 0; i < request.getCookies().length; i++) {
049                                            if ("JSESSIONID".equals(request.getCookies()[i].getName())) {
050                                                    sessionId = request.getCookies()[i].getValue();
051                                                    break;
052                                            }
053                                    }                               
054                            ServletGraniteContext.createThreadInstance(gravity.getGraniteConfig(), gravity.getServicesConfig(), 
055                                            this.servletContext, sessionId, clientType);
056                            }
057                            
058                            log.info("WebSocket connection started %s clientId %s sessionId %s", protocol, clientId, sessionId);
059                            
060                            CommandMessage pingMessage = new CommandMessage();
061                            pingMessage.setMessageId(connectMessageId != null ? connectMessageId : "OPEN_CONNECTION");
062                            pingMessage.setOperation(CommandMessage.CLIENT_PING_OPERATION);
063                            if (clientId != null)
064                                    pingMessage.setClientId(clientId);
065                            
066                            Message ackMessage = gravity.handleMessage(channelFactory, pingMessage);
067                            
068                            JettyWebSocketChannel channel = gravity.getChannel(channelFactory, (String)ackMessage.getClientId());
069                            
070                            if (!ackMessage.getClientId().equals(clientId))
071                                    channel.setConnectAckMessage(ackMessage);
072                            
073                            return channel;
074                    }
075                    finally {
076                            GraniteContext.release();
077                    }
078        }
079    }