/*
* Copyright (C) 2015 Red Hat, Inc. and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jboss.errai.bus.server.websocket.jsr356;
import org.jboss.errai.bus.server.websocket.jsr356.channel.ErraiChannelFactory;
import org.jboss.errai.bus.server.websocket.jsr356.channel.ErraiWebSocketChannel;
import org.jboss.errai.bus.server.websocket.jsr356.configuration.ErraiEndpointConfigurator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.http.HttpSession;
import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.util.HashMap;
import java.util.Map;
/**
* WebSocket endpoint for Errai Bus messages.
*
* @author Michel Werren
*/
@ServerEndpoint(value = "/in.erraiBusWS", configurator = ErraiEndpointConfigurator.class)
public class ErraiWebSocketEndpoint {
public static final int CLOSE_CODE_NORMAL = 1000;
public static final int CLOSE_CODE_AWAY = 1001;
public static final int CLOSE_CODE_PROTOCOL_ERROR = 1002;
public static final int CLOSE_CODE_WRONG_DATA = 1003;
public static final int CLOSE_CODE_ABNORMAL = 1006;
public static final int CLOSE_CODE_MESSAGE_NOT_CONSISTENT = 1007;
public static final int CLOSE_CODE_MESSAGE_TOO_BIG = 1009;
public static final int CLOSE_CODE_MISSING_EXTENSION = 1010;
public static final int CLOSE_CODE_UNEXPECT_CONDITION = 1011;
public static final int CLOSE_CODE_TLS_ERROR = 1015;
private static final Logger LOGGER = LoggerFactory.getLogger(ErraiWebSocketEndpoint.class.getName());
private static final Map<String, ErraiWebSocketChannel> CHANNELS = new HashMap<String, ErraiWebSocketChannel>();
@OnOpen
public void onOpen(Session session, EndpointConfig config) {
final HttpSession httpSession = (HttpSession) config.getUserProperties().get(HttpSession.class.getName());
final ErraiWebSocketChannel channel = ErraiChannelFactory.getInstance().buildWebsocketChannel(session, httpSession);
CHANNELS.put(session.getId(), channel);
}
@OnMessage
public void onMessage(String message, Session session) {
final ErraiWebSocketChannel channel = CHANNELS.get(session.getId());
/*
* Fix for ERRAI-866: There is a chrome bug that can cause empty messages to
* be sent. (See:
* https://code.google.com/p/chromium/issues/detail?id=510016&colspec=ID%
* 20Pri%20M%20Stars%20ReleaseBlock%20Cr%20Status%20Owner%20Summary%20OS%
* 20Modified)
*/
if (!message.isEmpty()) {
channel.doErraiMessage(message);
}
}
@OnClose
public void onClose(Session session, CloseReason reason) {
final ErraiWebSocketChannel removedChannel = CHANNELS.remove(session.getId());
removedChannel.onSessionClosed();
if (reason != null) {
final int closeCode = reason.getCloseCode().getCode();
switch (closeCode) {
case CLOSE_CODE_ABNORMAL:
LOGGER.debug("abnormal closing of the websocket session");
break;
case CLOSE_CODE_WRONG_DATA:
LOGGER.debug("closing websocket session because of wrong data type");
break;
case CLOSE_CODE_PROTOCOL_ERROR:
LOGGER.debug("closing websocket session because of protocol error");
break;
case CLOSE_CODE_MESSAGE_NOT_CONSISTENT:
LOGGER.debug("closing websocket session because of not consistent data");
break;
case CLOSE_CODE_MESSAGE_TOO_BIG:
LOGGER.debug("closing websocket session because of too big message");
break;
case CLOSE_CODE_MISSING_EXTENSION:
LOGGER.debug("closing websocket session because of missing extension");
break;
case CLOSE_CODE_UNEXPECT_CONDITION:
LOGGER.debug("closing websocket session because of unexpected condition ");
break;
case CLOSE_CODE_TLS_ERROR:
LOGGER.debug("closing websocket session because of TLS handshake error");
break;
}
}
}
@OnError
public void onError(Throwable throwable) {
LOGGER.error("", throwable);
}
}