Reputation: 479
Hello im having the next issue using cometd + jquery + java doing some testing in broadcasting a message.
This is my web.xml, im using the Annotations implementation of cometd:
<!-- Cometd Servlet -->
<servlet>
<servlet-name>cometd</servlet-name>
<servlet-class>org.cometd.java.annotation.AnnotationCometdServlet</servlet-class>
<init-param>
<param-name>timeout</param-name>
<param-value>60000</param-value>
</init-param>
<init-param>
<param-name>logLevel</param-name>
<param-value>3</param-value>
</init-param>
<init-param>
<param-name>services</param-name>
<param-value>com.api.services.UserStatusService</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
<async-supported>true</async-supported>
</servlet>
<servlet-mapping>
<servlet-name>cometd</servlet-name>
<url-pattern>/do/cometd/*</url-pattern>
</servlet-mapping>
This is the service i registered:
package com.api.services;
import java.util.HashMap;
import javax.inject.Inject;
import org.cometd.bayeux.Message;
import org.cometd.bayeux.client.ClientSession;
import org.cometd.bayeux.client.ClientSessionChannel;
import org.cometd.bayeux.server.BayeuxServer;
import org.cometd.java.annotation.Service;
import org.cometd.java.annotation.Session;
import org.cometd.java.annotation.Subscription;
@Service
public class UserStatusService
{
@Inject
private BayeuxServer bayeux;
@Session
private ClientSession bayeuxClient;
@Subscription("/userStatus")
public void userStatus (Message message)
{
HashMap<String, String> mapa = new HashMap<String,String>();
String channel = message.getChannel();
System.out.println("*** The Channel is "+channel+" ***");
ClientSessionChannel chann = bayeuxClient.getChannel(channel);
mapa.put("canal", channel);
mapa.put("mensaje", "Hola Wi!!");
mapa.put("ServChan", bayeux.getChannels().get(0).toString());
chann.publish(mapa);
}
}
And this is the JS jQuery code im using to subscribe and publish (is part of a larger object so im just pasting the main thing related to this):
/** On document ready i call this one **/
initBroad:function(){
$.cometd.unregisterTransport('websocket');
$.cometd.init('http://localhost/MyApp/do/cometd');
console.log("Set cometd initialization");
main.broadListener();
},
count:0,
subscription:null,
refresh:function(){
this.appUnsubscribe();
this.appSubscribe();
},
appUnsubscribe:function(){
if (this.subscription)
$.cometd.unsubscribe(this.subscription);
this.subscription = null;
},
appSubscribe:function(){
func = function(msg){
/** I had to do this in order to avoid ALL the 500 times it does it :S **/
if(main.count < 1){
console.log(main.count + ": " + msg.data.mensaje);
}
main.count++;
};
this.subscription = $.cometd.subscribe("/userStatus",func);
},
broadListener:function(){
console.log("Set the broadListener");
main.refresh();
},
publishBroad:function(){
main.refresh();
$.cometd.publish('/userStatus', {mensaje:"Hola"});
},
Well, after trying to run the method publishBroad over the console, it actually runs, but 450-500 times IN THE SERVER with just one click/request (yes it is just one request from browser to the java server, the 450-500 times get repeated only on the server side and reaches the browser in the response that many times)!!
What have i done wrong? Im using the latests cometd.js and jquery.cometd.js from cometd official site.
Also, when i check this in the console (im using JBoss AS7), i left some output log lines to see if my call entered the method ( the Sys out println that says The Channel is:. and it also shows that log line 450-500 times in JBoss console!
Can anyone please help me to fix this up??
Thanks!!
Upvotes: 0
Views: 933
Reputation: 18637
Your problem is that you're using a ClientSession in your service.
If, in your service, you just want to reply to the sender, then do this:
@Service
public class UserStatusService
{
@Session
private LocalSession session;
@Subscribe("/userStatus")
public void userStatus(ServerSession remoteClient, ServerMessage message)
{
Map<String, String> map = new HashMap<String,String>();
map.put("mensaje", "Hola Wi!!");
remoteClient.deliver(session, message.getChannel(), map, null);
}
}
Please refer to the CometD concepts to understand the difference between a ClientSession, a ServerSession and a LocalSession, and to the annotated services reference.
The reason for the loop you noticed (1 request caused the service to be executed 500+ times) is because you're re-broadcasting to the same channel in the last line if your service.
Upvotes: 1