/**
* GRANITE DATA SERVICES
* Copyright (C) 2006-2015 GRANITE DATA SERVICES S.A.S.
*
* This file is part of the Granite Data Services Platform.
*
* Granite Data Services is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* Granite Data Services is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
* General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA, or see <http://www.gnu.org/licenses/>.
*/
package org.granite.gravity.websocket;
import flex.messaging.messages.CommandMessage;
import flex.messaging.messages.Message;
import org.granite.context.GraniteContext;
import org.granite.gravity.GravityInternal;
import org.granite.logging.Logger;
import org.granite.messaging.webapp.ServletGraniteContext;
import org.granite.util.ContentType;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpSession;
import javax.websocket.CloseReason;
import javax.websocket.Endpoint;
import javax.websocket.EndpointConfig;
import javax.websocket.Session;
/**
* Created by william on 12/02/14.
*/
public class GravityWebSocketEndpoint extends Endpoint {
private static final Logger log = Logger.getLogger(GravityWebSocketEndpoint.class);
private final GravityWebSocketConfig config;
public GravityWebSocketEndpoint() {
config = GravityWebSocketConfig.remove();
}
@Override
public void onOpen(Session session, EndpointConfig endpointConfig) {
GravityInternal gravity = (GravityInternal)endpointConfig.getUserProperties().get("gravity");
ServletContext servletContext = (ServletContext)endpointConfig.getUserProperties().get("servletContext");
String connectMessageId = config.connectMessageId;
String clientId = config.clientId;
String clientType = config.clientType;
ContentType contentType = config.contentType;
HttpSession httpSession = config.session;
try {
String sessionId = null;
if (httpSession != null) {
ServletGraniteContext.createThreadInstance(gravity.getGraniteConfig(), gravity.getServicesConfig(),
servletContext, httpSession, clientType);
sessionId = httpSession.getId();
}
else {
ServletGraniteContext.createThreadInstance(gravity.getGraniteConfig(), gravity.getServicesConfig(),
servletContext, (String)null, clientType);
}
CommandMessage pingMessage = new CommandMessage();
pingMessage.setMessageId(connectMessageId != null ? connectMessageId : "OPEN_CONNECTION");
pingMessage.setOperation(CommandMessage.CLIENT_PING_OPERATION);
if (clientId != null)
pingMessage.setClientId(clientId);
WebSocketChannelFactory channelFactory = new WebSocketChannelFactory(gravity);
Message ackMessage = gravity.handleMessage(channelFactory, pingMessage);
if (sessionId != null)
ackMessage.setHeader("JSESSIONID", sessionId);
log.info("WebSocket connection started connectId %s clientId %s ackClientId %s sessionId %s", pingMessage.getMessageId(), clientId, ackMessage.getClientId(), sessionId);
WebSocketChannel channel = gravity.getChannel(channelFactory, (String)ackMessage.getClientId());
channel.setSession(httpSession);
channel.setContentType(contentType);
channel.setConnectAckMessage(ackMessage);
session.getUserProperties().put("channel", channel);
session.setMaxIdleTimeout(channel.getGravity().getGravityConfig().getChannelIdleTimeoutMillis());
channel.onWebSocketConnect(session);
}
finally {
GraniteContext.release();
}
}
@Override
public void onClose(Session session, CloseReason closeReason) {
WebSocketChannel channel = (WebSocketChannel)session.getUserProperties().get("channel");
channel.onWebSocketClose(closeReason.getCloseCode().getCode(), closeReason.getReasonPhrase());
}
@Override
public void onError(Session session, Throwable error) {
try {
WebSocketChannel channel = (WebSocketChannel)session.getUserProperties().get("channel");
if (channel != null)
channel.onWebSocketError(error);
else
log.error(error, "WebSocket error for session %s", session.getId());
}
catch (Exception e) {
// Tomcat does not give access to userProperties in error handler ???
log.error(error, "WebSocket error for session %s", session.getId());
}
}
}