public void sendNotification(Notification notification, int id) { ServerSession remoteClient = retrieveSessionFromId(id); remoteClient.deliver(serverSession, "/person/notification", notification); }
protected void disconnect(ServerSession session) { if (session != null) { session.disconnect(); } } }
@Override public boolean canSubscribe(BayeuxServer server, ServerSession session, ServerChannel channel, ServerMessage message) { return session != null && session.isLocalSession() || !channel.isMeta(); } }
@Override public boolean canPublish(BayeuxServer server, ServerSession session, ServerChannel channel, ServerMessage message) { return session != null && session.isHandshook() && !channel.isMeta(); }
private MarkedReference<ServerSessionImpl> removeSession(ServerSession session, boolean timedOut) { if (_logger.isDebugEnabled()) { _logger.debug("Removing session {}, timed out: {}", session, timedOut); } ServerSessionImpl removed = _sessions.remove(session.getId()); if (removed != session) { return MarkedReference.empty(); } // Invoke BayeuxServer.SessionListener first, so that the application // can be "pre-notified" that a session is being removed before the // application gets notifications of channel unsubscriptions for (BayeuxServerListener listener : _listeners) { if (listener instanceof SessionListener) { notifySessionRemoved((SessionListener)listener, removed, timedOut); } } boolean connected = removed.removed(timedOut); return new MarkedReference<>(removed, connected); }
@Override public boolean rcvMeta(ServerSession from, Mutable message) { Map<String, Object> ext = message.getExt(false); if (ext != null) { Map<String, Object> sync = (Map<String, Object>)ext.get("timesync"); if (sync != null) { sync.put("ts", System.currentTimeMillis()); Number lag = (Number)sync.get("l"); if (lag != null && from != null) { from.setAttribute(LAG_ATTRIBUTE, lag); } } } return true; }
@Override public boolean rcvMeta(ServerSession session, ServerMessage.Mutable message) { if (Channel.META_HANDSHAKE.equals(message.getChannel())) { session.addExtension(newSessionExtension(session, message)); } return true; }
protected void sweep() { waitForInitialized(); for (ServerSession session : _subscribers) { if (!session.isHandshook()) { unsubscribe(session); } } if (isMeta() || isPersistent()) { return; } if (!_subscribers.isEmpty()) { return; } if (!_authorizers.isEmpty()) { return; } for (ServerChannelListener listener : _listeners) { if (!(listener instanceof ServerChannelListener.Weak)) { return; } } if (_sweeperPasses.incrementAndGet() < 3) { return; } remove(); }
if (wildSubscribers.add(subscriber.getId())) { ((ServerSessionImpl)subscriber).deliver1(session, message, Promise.from(b -> loop.proceed(true), loop::fail)); } else { if (!wildSubscribers.contains(subscriber.getId())) { ((ServerSessionImpl)subscriber).deliver1(session, message, Promise.from(y -> loop.proceed(true), loop::fail)); } else {
private void configureRoom(String roomName) { final String channelName = "/" + roomName + "/members"; ServerChannel channel = bayeuxServer.createChannelIfAbsent(channelName).getReference(); channel.addListener(new SubscriptionListener() { @Override public void subscribed(ServerSession session, ServerChannel channel, ServerMessage message) { // Send back the whole list to the subscriber. session.deliver(sender, channelName, memberList); } });
@Override public boolean canCreate(BayeuxServer server, ServerSession session, String channelId, ServerMessage message) { return session != null && session.isLocalSession() || !ChannelId.isMeta(channelId); }
public class EchoService extends AbstractService { public EchoService(BayeuxServer bayeuxServer) { super(bayeuxServer, "echo"); addService("/echo", "processEcho"); } public void processEcho(ServerSession remote, Map<String, Object> data) { // if you want to echo the message to the client that sent the message remote.deliver(getServerSession(), "/echo", data, null); // if you want to send the message to all the subscribers of the "/myChannel" channel getBayeux().createIfAbsent("/myChannel"); getBayeux().getChannel("/myChannel").publish(getServerSession(), data, null); } }
@Override public void dump(Appendable out, String indent) throws IOException { List<ServerSession> sessions = new ArrayList<>(_sessions.values()); ContainerLifeCycle.dumpObject(out, "sessions: " + sessions.size()); if (isDetailedDump()) { List<ServerSession> locals = new ArrayList<>(); for (Iterator<ServerSession> iterator = sessions.iterator(); iterator.hasNext(); ) { ServerSession session = iterator.next(); if (session.isLocalSession()) { locals.add(session); iterator.remove(); } } ContainerLifeCycle.dump(out, indent, locals, sessions); } } });
/** * @param sender the session delivering the message * @param message the message to deliver * @deprecated use {@link #deliver(Session, ServerMessage.Mutable, Promise)} instead */ @Deprecated public default void deliver(Session sender, ServerMessage.Mutable message) { deliver(sender, message, Promise.noop()); }
/** * @param sender the session delivering the message * @param channel the channel of the message * @param data the data of the message * @deprecated use {@link #deliver(Session, String, Object, Promise)} instead */ @Deprecated public default void deliver(Session sender, String channel, Object data) { deliver(sender, channel, data, Promise.noop()); }
@Service public class GetPlayer { @Session private LocalSession sender; @Listener("/service/player/get") public void perform(ServerSession session, ServerMessage message) { Map<String, Object> player = retrievePlayerInfo(message.get("playerId")); session.deliver(sender, message.getChannel(), player); } }
/** * <p>Sends data to an individual remote client.</p> * <p>The data passed is sent to the client * as the "data" member of a message with the given channel. The * message is not published on the channel and is thus not broadcast to all * channel subscribers, but instead delivered directly to the target client.</p> * <p>Typically this method is only required if a service method sends * response(s) to clients other than the sender, or on different channels. * If the response is to be sent to the sender on the same channel, * then the data can simply be the return value of the method.</p> * * @param toClient The target client * @param onChannel The channel of the message * @param data The data of the message */ protected void send(ServerSession toClient, String onChannel, Object data) { toClient.deliver(_session.getServerSession(), onChannel, data, Promise.noop()); }
private boolean deliver(Object data, boolean successful) { boolean completed = complete.compareAndSet(false, true); if (completed) { ServerMessage.Mutable message = bayeux.newMessage(); message.setId(messageId); message.setSuccessful(successful); message.setChannel(channel); message.setData(data); session.deliver(sender, message, Promise.noop()); } return completed; } }