case ConnectToQueue: {
List<Message> deferred = null;
synchronized (messageQueues) {
if (messageQueues.containsKey(session)) {
MessageQueue q = messageQueues.get(session);
synchronized (q) {
if (deferredQueue.containsKey(q)) {
deferred = deferredQueue.remove(q);
}
}
messageQueues.get(session).stopQueue();
}
addQueue(session, queue = new MessageQueueImpl(transmissionbuffer, session));
if (deferred != null) {
deferredQueue.put(queue, deferred);
}
remoteSubscribe(session, queue, BuiltInServices.ClientBus.name());
}
if (isMonitor()) {
busMonitor.notifyQueueAttached(session.getSessionId(), queue);
}
List<String> subjects = new LinkedList<String>();
for (String service : subscriptions.keySet()) {
if (service.startsWith("local:")) {
}
else if (!remoteSubscriptions.containsKey(service)) {
subjects.add(service);
}
}
createConversation(message)
.toSubject(BuiltInServices.ClientBus.name())
.command(BusCommands.RemoteSubscribe)
.with(MessageParts.SubjectsList, subjects)
.with(MessageParts.PriorityProcessing, "1")
.noErrorHandling().sendNowWith(ServerMessageBusImpl.this, false);
CommandMessage msg = ConversationMessage.create(message);
msg.toSubject(BuiltInServices.ClientBus.name())
.command(BusCommands.CapabilitiesNotice);
StringBuilder capabilitiesBuffer = new StringBuilder();
boolean first;
if (ErraiServiceConfigurator.LONG_POLLING) {
capabilitiesBuffer.append(Capabilities.LongPollAvailable.name());
first = false;
}
else {
capabilitiesBuffer.append(Capabilities.NoLongPollAvailable.name());
first = false;
msg.set(MessageParts.PollFrequency, ErraiServiceConfigurator.HOSTED_MODE_TESTING ? 50 : 250);
}
if (webSocketServer) {
if (!first) {
capabilitiesBuffer.append(',');
}
capabilitiesBuffer.append(Capabilities.WebSockets.name());
/**
* Advertise where the client can find a websocket.
*/
HttpServletRequest request = message.getResource(HttpServletRequest.class, HttpServletRequest.class.getName());
msg.set(MessageParts.WebSocketURL, "ws://" + request.getLocalAddr()
+ ":" + webSocketPort + webSocketPath);
String connectionToken = SecureHashUtil.nextSecureHash("SHA-256", session.getSessionId());
session.setAttribute(MessageParts.WebSocketToken.name(), connectionToken);
msg.set(MessageParts.WebSocketToken, connectionToken);
}
msg.set(MessageParts.CapabilitiesFlags, capabilitiesBuffer.toString());
send(msg, false);
createConversation(message)
.toSubject(BuiltInServices.ClientBus.name())
.command(BusCommands.FinishStateSync)
.with(MessageParts.ConnectionSessionKey, queue.getSession().getSessionId())
.noErrorHandling().sendNowWith(ServerMessageBusImpl.this, false);
break;
}
case WebsocketChannelVerify:
if (session.hasAttribute(MessageParts.WebSocketToken.name())
&& message.hasPart(MessageParts.WebSocketToken)) {
if (message.get(String.class, MessageParts.WebSocketToken)
.equals(session.getAttribute(String.class, MessageParts.WebSocketToken.name()))) {
session.setAttribute(WebSocketServerHandler.SESSION_ATTR_WS_STATUS,
WebSocketServerHandler.WEBSOCKET_ACTIVE);
createConversation(message)
.toSubject(BuiltInServices.ClientBus.name())
.command(BusCommands.WebsocketChannelOpen)
.done().sendNowWith(ServerMessageBusImpl.this, false);
}
}
break;
}
}
catch (Throwable t) {
t.printStackTrace();
}
}
});
addSubscribeListener(new SubscribeListener() {
@Override
public void onSubscribe(SubscriptionEvent event) {
if (event.isLocalOnly() || event.isRemote() || event.getSubject().startsWith("local:")) return;
MessageBuilder.createMessage()
.toSubject(BuiltInServices.ClientBus.name())
.command(BusCommands.RemoteSubscribe)
.with(MessageParts.Subject, event.getSubject())
.noErrorHandling().sendGlobalWith(ServerMessageBusImpl.this);
}
});
addUnsubscribeListener(new UnsubscribeListener() {
@Override
public void onUnsubscribe(SubscriptionEvent event) {
if (event.isLocalOnly() || event.isRemote() || event.getSubject().startsWith("local:")) return;
if (messageQueues.isEmpty()) return;
MessageBuilder.createMessage()
.toSubject(BuiltInServices.ClientBus.name())
.command(BusCommands.RemoteUnsubscribe)
.with(MessageParts.Subject, event.getSubject())
.noErrorHandling().sendGlobalWith(ServerMessageBusImpl.this);
}
});
scheduler.scheduleAtFixedRate(new Runnable() {
int runCount = 0;
boolean lastWasEmpty = false;
@Override
public void run() {
runCount++;
boolean houseKeepingPerformed = false;
List<MessageQueue> endSessions = new LinkedList<MessageQueue>();
int paged = 0, killed = 0;
while (!houseKeepingPerformed) {
try {
Iterator<MessageQueue> iter = ServerMessageBusImpl.this.messageQueues.values().iterator();
MessageQueue q;
while (iter.hasNext()) {
if ((q = iter.next()).isStale()) {
iter.remove();
endSessions.add(q);
killed++;
}
else if (q.isDowngradeCandidate()) {
if (!q.pageWaitingToDisk()) {
paged++;
}
}
}