/** * {@inheritDoc} */ @Override public <EventType> CometdPushNode<EventType> installNode(final Component component, final IPushEventHandler<EventType> handler) { CometdPushBehavior behavior = _findPushBehaviour(component); if (behavior == null) { behavior = new CometdPushBehavior(); component.add(behavior); } final CometdPushNode<EventType> node = behavior.addNode(handler); _onConnect(node); return node; }
private ServerChannel _getBayeuxServerChannel(final CometdPushNode<?> node) { return _getBayeuxServer().getChannel(node.getCometdChannelId()); }
<EventType> CometdPushNode<EventType> addNode( final IPushEventHandler<EventType> pushEventHandler) { final CometdPushNode<EventType> node = new CometdPushNode<EventType>(_cometdChannelId); _handlers.put(node, pushEventHandler); return node; }
/** * {@inheritDoc} */ @Override public <EventType> void publish(final IPushNode<EventType> node, final EventType event) { if (node instanceof CometdPushNode) { final ServerChannel cchannel = _getBayeuxServerChannel((CometdPushNode<?>)node); if (cchannel == null) LOG.warn("No cometd channel found for {}", node); else { @SuppressWarnings("unchecked") final PushNodeState<EventType> state = (PushNodeState<EventType>)_nodeStates.get(node); if (state != null) { synchronized (state.queuedEventsLock) { state.queuedEvents.add(new CometdPushEventContext<EventType>(event, null, this)); } cchannel.publish(null, "pollEvents", state.node.getCometdChannelEventId()); } } } else LOG.warn("Unsupported push node type {}", node); }
/** * {@inheritDoc} */ @Override protected void respond(final AjaxRequestTarget target) { final CometdPushService pushService = CometdPushService.get(); // retrieve all collected events and process them for (final Entry<CometdPushNode, IPushEventHandler> entry : _handlers.entrySet()) { final CometdPushNode node = entry.getKey(); for (final Iterator<CometdPushEventContext<?>> it = pushService.pollEvents(node) .iterator(); it.hasNext();) { final CometdPushEventContext<?> ctx = it.next(); try { entry.getValue().onEvent(target, ctx.getEvent(), node, ctx); } catch (final RuntimeException ex) { LOG.error("Failed while processing event", ex); } } } } }
/** * {@inheritDoc} */ @Override public void renderHead(final IHeaderResponse response) { super.renderHead(response); response.renderJavascriptReference(COMETD); // Add all extension... response.renderJavascriptReference(COMETD_ACK); response.renderJavascriptReference(COMETD_RELOAD); response.renderJavascriptReference(COMETD_TIMESTAMP); response.renderJavascriptReference(COMETD_TIMESYNC); response.renderJavascript(_renderInitScript(), "cometd-push-initialization"); response.renderJavascript(_renderEventHandlerScript(), null); response.renderJavascript(_renderSubscribeScript(), null); }
/** * Directly sends JavaScript code to the node via a cometd channel without an additional Wicket * AJAX request roundtrip. */ public <EventType> void publishJavascript(final CometdPushNode<EventType> node, final String javascript) { final ServerChannel channel = _getBayeuxServerChannel(node); if (channel == null) LOG.warn("No cometd channel found for {}", node); else channel.publish(null, "javascript:" + javascript, node.getCometdChannelEventId()); }
private <EventType> void _onConnect(final CometdPushNode<EventType> node) { _nodeStates.put(node, new PushNodeState<EventType>(node)); List<CometdPushNode<?>> nodes = _nodesByCometdChannelId.get(node.getCometdChannelId()); if (nodes == null) { // create a new list final List<CometdPushNode<?>> newList = new ArrayList<CometdPushNode<?>>(2); // put the list, a list object is returned in case it was put in the meantime nodes = _nodesByCometdChannelId.putIfAbsent(node.getCometdChannelId(), newList); if (nodes == null) newList.add(node); else nodes.add(node); } }
/** * {@inheritDoc} */ @Override public void uninstallNode(final Component component, final IPushNode<?> node) { if (node instanceof CometdPushNode) { final CometdPushBehavior behavior = _findPushBehaviour(component); if (behavior == null) return; if (behavior.removeNode(node) == 0) component.remove(behavior); } else LOG.warn("Unsupported push node type {}", node); } }
/** * {@inheritDoc} */ @Override public boolean isConnected(final IPushNode<?> node) { if (node instanceof CometdPushNode) return _getBayeuxServerChannel((CometdPushNode<?>)node) != null; LOG.warn("Unsupported push node type {}", node); return false; }
public static CometdPushService get(final WebApplication application) { CometdPushService service = INSTANCES.get(application); if (service == null) { service = new CometdPushService(application); INSTANCES.put(application, service); } return service; }
public static CometdPushService get() { return get(WebApplication.get()); }
/** * Directly sends JavaScript code to all nodes listeing to the given push channel via a cometd * channel without an additional Wicket AJAX request roundtrip. */ @SuppressWarnings("unchecked") public <EventType> void publishJavascript(final PushChannel<EventType> channel, final String javascript) { if (channel == null) throw new IllegalArgumentException("Argument [channel] must not be null"); final Set<IPushNode<?>> pnodes = nodesByChannels.get(channel); if (pnodes == null) throw new IllegalArgumentException("Unknown channel " + channel); // publish the event to all registered nodes for (final IPushNode<?> node : pnodes) publishJavascript((CometdPushNode<EventType>)node, javascript); }
/** * @return JavaScript string containing the client side logic when a new event comes into the * channel. */ private String _renderEventHandlerScript() { final Map<String, Object> map = new HashMap<String, Object>(); map.put("COMETD_CHANNEL_ID", _cometdChannelIdWithoutSlash); map.put("CALLBACK_URL", getCallbackUrl().toString()); return TEMPLATE_EVENT_HANDLER.asString(map); }
@SuppressWarnings("unchecked") <EventType> List<CometdPushEventContext<EventType>> pollEvents( final CometdPushNode<EventType> node) { final PushNodeState<EventType> state = (PushNodeState<EventType>)_nodeStates.get(node); if (state == null) { LOG.debug("Reconnecting push node {}...", node); _onConnect(node); return Collections.EMPTY_LIST; } if (state.queuedEvents.size() == 0) return Collections.EMPTY_LIST; synchronized (state.queuedEventsLock) { final List<CometdPushEventContext<EventType>> events = state.queuedEvents; state.queuedEvents = new ArrayList<CometdPushEventContext<EventType>>(2); return events; } }
private void _onDisconnect(final CometdPushNode<?> node) { if (_nodeStates.remove(node) != null) { LOG.debug("Cometd push node {} disconnected.", node); disconnectFromAllChannels(node); for (final IPushNodeDisconnectedListener listener : _disconnectListeners) try { listener.onDisconnect(node); } catch (final RuntimeException ex) { LOG.error("Failed to notify " + listener, ex); } } }
_getBayeuxServer().addListener(new ChannelListener() _getBayeuxServer().addListener(new SessionListener() _getBayeuxServer().addListener(new SubscriptionListener()
/** * Javascript allowing cometd to be initialized on commetd * * @return javascript to initialize cometd on client side */ private String _renderInitScript() { final Map<String, Object> params = new HashMap<String, Object>(); final String configurationType = Application.get().getConfigurationType(); if (configurationType.equalsIgnoreCase(Application.DEVELOPMENT)) params.put("logLevel", "info"); else params.put("logLevel", "error"); params.put("cometdServletPath", getCometdServletPath()); return TEMPLATE_INIT.asString(params); }
throw new IllegalArgumentException("Unknown channel " + channel); final CometdPushEventContext<EventType> ctx = new CometdPushEventContext<EventType>(event, channel, this); final CometdPushNode<EventType> node = (CometdPushNode<EventType>)pnode; final ServerChannel cchannel = _getBayeuxServerChannel(node); if (cchannel == null) cchannel.publish(null, "pollEvents", state.node.getCometdChannelEventId());