I am trying to enable Oort with multicast in our Comet app following this example. I just need the Oort now. Not the Seti part. But Oort doesn't seem to be working. I have the cometd debug enabled and I don't see Oort being initialized.
I also tested by running two instances of Oort nodes in my local(on different ports), say A and B. Have the client connect to node A. I would then publish a message from node A on /user/*
channel and client receives it. But if I publish a message from node B, client doesn't get anything.
Spring Configuration:
import org.cometd.annotation.ServerAnnotationProcessor;
import org.cometd.bayeux.server.BayeuxServer;
import org.cometd.oort.Oort;
import org.cometd.oort.OortMulticastConfigServlet;
import org.cometd.oort.OortMulticastConfigurer;
import org.cometd.server.BayeuxServerImpl;
import org.cometd.server.transport.AsyncJSONTransport;
import org.cometd.server.transport.JSONTransport;
import org.cometd.websocket.server.WebSocketTransport;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.DestructionAwareBeanPostProcessor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.ServletContextAware;
import javax.annotation.PostConstruct;
import javax.servlet.ServletContext;
@Configuration
public class BayeuxInitializer implements DestructionAwareBeanPostProcessor, ServletContextAware {
private ServerAnnotationProcessor processor;
private ServletContext context;
@PostConstruct
private void init() {
BayeuxServer bayeuxServer = bayeuxServer();
this.processor = new ServerAnnotationProcessor(bayeuxServer);
Oort oort = oort();
oort.observeChannel("/user/*");
}
public Object postProcessBeforeInitialization(Object bean, String name) throws BeansException {
processor.processDependencies(bean);
processor.processConfigurations(bean);
processor.processCallbacks(bean);
return bean;
}
public Object postProcessAfterInitialization(Object bean, String name) throws BeansException {
return bean;
}
public void postProcessBeforeDestruction(Object bean, String name) throws BeansException {
processor.deprocessCallbacks(bean);
}
@Bean(initMethod = "start", destroyMethod = "stop")
public BayeuxServer bayeuxServer() {
BayeuxServerImpl bean = new BayeuxServerImpl();
bean.setTransports(new WebSocketTransport(bean), new JSONTransport(bean), new AsyncJSONTransport(bean));
bean.setOption("timeout", 60000);
bean.setOption("ws.timeout", 60000);
bean.setOption("maxSessionsPerBrowser", 20);
bean.setOption(ServletContext.class.getName(), context);
bean.setOption("cometdURLMapping", "/,/svc");
context.setAttribute(BayeuxServer.ATTRIBUTE, bean);
return bean;
}
@Bean(initMethod = "start", destroyMethod = "stop")
public Oort oort() {
Oort oort = new Oort(bayeuxServer(), "http://localhost:8094/comet/svc");
context.setAttribute(Oort.OORT_ATTRIBUTE, oort);
return oort;
}
@Override
public void setServletContext(ServletContext servletContext) {
this.context = servletContext;
}
}
web.xml:
<servlet>
<servlet-name>cometd</servlet-name>
<servlet-class>org.cometd.server.CometDServlet</servlet-class>
<load-on-startup>1</load-on-startup>
<async-supported>true</async-supported>
</servlet>
<servlet-mapping>
<servlet-name>cometd</servlet-name>
<url-pattern>/svc/*</url-pattern>
</servlet-mapping>
Oort seems to be working if I initialize it in web.xml as below:
<servlet>
<servlet-name>cometd</servlet-name>
<servlet-class>org.cometd.server.CometDServlet</servlet-class>
<load-on-startup>1</load-on-startup>
<async-supported>true</async-supported>
</servlet>
<servlet-mapping>
<servlet-name>cometd</servlet-name>
<url-pattern>/svc/*</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>oort</servlet-name>
<servlet-class>org.cometd.oort.OortMulticastConfigServlet</servlet-class>
<init-param>
<param-name>oort.url</param-name>
<param-value>http://localhost:8094/comet/svc</param-value>
</init-param>
<init-param>
<param-name>oort.channels</param-name>
<param-value>/user/*</param-value>
</init-param>
<load-on-startup>2</load-on-startup>
</servlet>
But as per the documentation Oort should be initialized in Spring if BayeuxServer is being initialized in Spring. So my questions are:
cometd version: 3.0.10
jetty version: 9.3.11
Any help appreciated!
When you create an Oort
object via Spring (or other embedded code), you have created a node, but it's not linked to other Oort nodes.
In your code, you call:
Oort oort = oort();
oort.observeChannel("/user/*");
This creates the node, configures it to observe messages on channel /user/*
from other nodes, but it does not connect it with other nodes.
In the example you linked, there is the missing piece, where it calls:
oort.observeComet("http://cloud.cometd.org/cometd");
That call is commented out in the example because, being an example, it does not know the exact URI of the other node, so as an example uses http://cloud.cometd.org/cometd
, but that URI does not point to an existing node - that is why is commented out.
Now, since you want to use multicast, the example you linked suggests to use OortMulticastConfigurer
.
OortMulticastConfigurer
is what is being used by OortMulticastConfigServlet
that you successfully use in your web.xml
.
Let's have a look at how OortMulticastConfigServlet
uses OortMulticastConfigurer
here.
As you can see, OortMulticastConfigurer
is created, configured and started.
If you stay on the default values, the minimum code becomes:
configurer = new OortMulticastConfigurer(oort);
configurer.start();
Add those 2 lines to your BayeuxInitializer.init()
method and you should be good to go.