The SpringContinuationCometdServlet
is configured to handle all
Comet requests. It only needs the asyncDeliver value set on
it and the other values you would normally set on ContinuationCometdServlet
are all set on SpringContinuationBayeux
in the Spring configuration.
<?xml version="1.0" encoding="ISO-8859-1"?> <web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5"> <display-name>Spring Cometd Test WebApp</display-name> <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/web-application-context.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <servlet> <servlet-name>cometd</servlet-name> <servlet-class>org.springbyexample.cometd.continuation.SpringContinuationCometdServlet</servlet-class> <init-param> <param-name>asyncDeliver</param-name> <param-value>false</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>cometd</servlet-name> <url-pattern>/cometd/*</url-pattern> </servlet-mapping> </web-app>
[ { "channels": "/**", "filter" : "org.mortbay.cometd.filter.NoMarkupFilter", "init" : {} }, { "channels": "/chat/*", "filter" : "org.mortbay.cometd.filter.RegexFilter", "init" : [ [ "[Ss]pring [Bb]y [Ee]xample","Spring by Example" ], [ "[Ss][Bb][Ee]","Spring by Example" ] ] }, { "channels": "/chat/**", "filter" : "org.mortbay.cometd.filter.RegexFilter", "init" : [ [ "teh ","the "], [ "sring ","spring "] ] } ] ]]> </value> </property> </bean>
The only difference in this compared to a standard BayeuxService
is that this Bayeux implementation is instantiated by Spring and
the Bayuex instance is injected into it's constructor.
@Component public class ChatService extends BayeuxService { final Logger logger = LoggerFactory.getLogger(ChatService.class); final ConcurrentMap<String, Set<String>> _members = new ConcurrentHashMap<String, Set<String>>(); /** * Constructor */ @Autowired public ChatService(Bayeux bayeux) { super(bayeux, "chat"); subscribe("/chat/**", "trackMembers"); } /** * Tracks chat clients. */ public void trackMembers(Client joiner, String channel, Map<String, Object> data, String id) { if (Boolean.TRUE.equals(data.get("join"))) { Set<String> m = _members.get(channel); if (m == null) { Set<String> new_list = new CopyOnWriteArraySet<String>(); m = _members.putIfAbsent(channel, new_list); if (m == null) { m = new_list; } } final Set<String> members = m; final String username = (String) data.get("user"); members.add(username); joiner.addListener(new RemoveListener() { public void removed(String clientId, boolean timeout) { members.remove(username); logger.info("members: " + members); } }); logger.info("Members: " + members); send(joiner, channel, members, id); } } }