
org.everrest.websockets.WSConnectionContext Maven / Gradle / Ivy
/*******************************************************************************
* Copyright (c) 2012-2016 Codenvy, S.A.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Codenvy, S.A. - initial API and implementation
*******************************************************************************/
package org.everrest.websockets;
import org.everrest.websockets.message.ChannelBroadcastMessage;
import org.everrest.websockets.message.Pair;
import org.everrest.websockets.message.RestOutputMessage;
import org.slf4j.LoggerFactory;
import javax.websocket.EncodeException;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
/**
* @author andrew00x
*/
public class WSConnectionContext {
private static final org.slf4j.Logger LOG = LoggerFactory.getLogger(WSConnectionContext.class);
static final List connectionListeners = new CopyOnWriteArrayList<>();
static final Map connections = new ConcurrentHashMap<>();
public static boolean registerConnectionListener(WSConnectionListener listener) {
return connectionListeners.add(listener);
}
public static boolean removeConnectionListener(WSConnectionListener listener) {
return connectionListeners.remove(listener);
}
/**
* Send message to all connections subscribed to the channel. Method tries to send message to as many connections as
* possible. Even if method fails to send message to the first connection it will try to send message to other
* connections, if any. After that a first occurred error is rethrown.
*
* @param message
* message
* @throws EncodeException
* if message cannot be serialized
* @throws IOException
* if any i/o error occurs when try to send message to client
* @see org.everrest.websockets.message.ChannelBroadcastMessage#getChannel()
*/
public static void sendMessage(ChannelBroadcastMessage message) throws EncodeException, IOException {
final String channel = message.getChannel();
final RestOutputMessage transport = newRestOutputMessage(message);
Exception error = null;
for (WSConnectionImpl connection : connections.values()) {
if (connection.getChannels().contains(channel)) {
try {
connection.sendMessage(transport);
} catch (EncodeException | IOException e) {
if (error == null) {
error = e;
}
}
}
}
if (error instanceof EncodeException) {
throw (EncodeException)error;
} else if (error != null) {
// If error is not null then may be IOException only.
throw (IOException)error;
}
}
private static RestOutputMessage newRestOutputMessage(ChannelBroadcastMessage message) {
final RestOutputMessage transport = new RestOutputMessage();
transport.setUuid(message.getUuid());
transport.setHeaders(new Pair[]{Pair.of("x-everrest-websocket-channel", message.getChannel()),
Pair.of("x-everrest-websocket-message-type", message.getType().toString())});
transport.setBody(message.getBody());
return transport;
}
static {
registerConnectionListener(new WSConnectionListener() {
@Override
public void onOpen(WSConnection connection) {
LOG.debug("Open connection {} ", connection);
}
@Override
public void onClose(WSConnection connection) {
LOG.debug("Close connection {} with status {} ", connection, connection.getCloseStatus());
connections.remove(connection.getId());
}
});
}
private WSConnectionContext() {
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy