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);
}
}
}