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();
}
queue = new MessageQueueImpl(transmissionbuffer, session);
addQueue(session, queue);
if (deferred != null) {
deferredQueue.put(queue, deferred);
}
remoteSubscribe(session, queue, BuiltInServices.ClientBus.name());
}
if (isMonitor()) {
busMonitor.notifyQueueAttached(session.getSessionId(), queue);
}
createConversation(message)
.toSubject(BuiltInServices.ClientBus.name())
.command(BusCommands.RemoteSubscribe)
.with(MessageParts.SubjectsList, new HashSet(globalSubscriptions))
.with(MessageParts.PriorityProcessing, "1")
.noErrorHandling().sendNowWith(ServerMessageBusImpl.this, false);
final Message msg = ConversationMessage.create(message)
.toSubject(BuiltInServices.ClientBus.name())
.command(BusCommands.CapabilitiesNotice);
final StringBuilder capabilitiesBuffer = new StringBuilder(25);
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 || webSocketServlet) {
if (!first) {
capabilitiesBuffer.append(',');
}
capabilitiesBuffer.append(Capabilities.WebSockets.name());
/**
* Advertise where the client can find a websocket.
*/
final String webSocketURL;
HttpServletRequest request = message.getResource(HttpServletRequest.class, HttpServletRequest.class.getName());
if (webSocketServlet) {
webSocketURL = "ws://" + request.getHeader("Host") + webSocketPath;
}
else {
webSocketURL = "ws://" + request.getLocalName() + ":" + webSocketPort + webSocketPath;
}
msg.set(MessageParts.WebSocketURL, webSocketURL);
msg.set(MessageParts.WebSocketToken, WebSocketTokenManager.getNewOneTimeToken(session));
}
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 (message.hasPart(MessageParts.WebSocketToken)) {
if (verifyOneTimeToken(session, message.get(String.class, MessageParts.WebSocketToken))) {
LocalContext localContext = LocalContext.get(session);
localContext.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 {
final 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++;
}
}
}