Проблемы с CometD при публикации данных на канал
Я новичок в кометде. Я планировал отправить сообщение на сервер и получить сообщение в своем браузере с помощью комед. Если я отправляю сообщение, оно успешно отправляется на сервер, но не удается получить его в браузере.
private void testService() {
String channelName = "/service/out";
log.info("Channel Name = " + channelName);
log.info("bayeuxServer : " + (bayeuxServer == null ? "Is Null" : "Is Not Null"));
System.out.println("CHANNELS : " + bayeuxServer.getChannels().toString());
System.out.println("Subscribers on /service/in = "+bayeuxServer.getChannel("/service/in").getSubscribers().toString());
System.out.println("Subscribers on /service/out = "+bayeuxServer.getChannel("/service/out").getSubscribers().toString());
// convert to cometd format
Map<String, Object> data = new HashMap<String, Object>(4);
data.put("serverMsg", getDetails());
ServerChannel channel = bayeuxServer.getChannel(channelName);
subscribers = channel.getSubscribers().size();
log.info("Subscribers = " + subscribers);
log.info("channel = " + channel);
channel.publish(sender, data, null);
System.out.println("Session subscriptions :" + sender.getServerSession().getSubscriptions());
System.out.println("Listeners on /service/out = "+bayeuxServer.getChannel("/service/out").getListeners().toString());
System.out.println("Subscribers on /service/out = "+bayeuxServer.getChannel("/service/out").getSubscribers().toString());
}
Но этот не работает
@Subscription("/service/out")
public void echo(Message message)
{
System.out.println("Echo service published " + message);
}
Журналы:
1
7:48:18,775 INFO ClientHelloService [] Bayeux server =org.cometd.server.BayeuxServerImpl@1436088
17:48:18,775 INFO ClientHelloService [] Message = Hello world
17:48:18,775 INFO ClientHelloService [] remote Client Id = 3renjdwk25ercglzli36tudpl
17:48:18,776 INFO ClientHelloService [] Local session = L:_21w17u5f3mvvluvp71c27yaqvt
17:48:18,776 INFO ClientHelloService [] session = 3renjdwk25ercglzli36tudpl - last connect 1 ms ago
17:48:18,776 INFO ClientHelloService [] Channel Name = /service/out
17:48:18,776 INFO ClientHelloService [] bayeuxServer : Is Not Null
CHANNELS : [/service/out, /meta/subscribe, /service, /service/*, /meta, /meta/handshake, /meta/disconnect, /service/in, /meta/connect, /meta/unsubscribe]
Subscribers on /service/in = []
Subscribers on /service/out = []
17:48:18,777 INFO ClientHelloService [] msg = Hello world
17:48:18,777 INFO ClientHelloService [] Subscribers = 0
17:48:18,777 INFO ClientHelloService [] channel = /service/out
17:48:18,777 DEBUG 21192840 [] < {data={serverMsg=Hello world}, channel=/service/out}
17:48:18,777 INFO ClientHelloService [] publish the channel
Session subscriptions :[]
Listeners on /service/out = []
Subscribers on /service/out = []
application.js
var sendChannel = '/service/in'; // Message from jsp
var receiveChannel = '/service/*'; // Message from server
/*var cometdServerURL = 'http://127.0.0.1:8080/cometd';*/
require(['dojox/cometd', 'dojo/dom', 'dojo/domReady!'], function(cometd, dom)
{ // // configuration object
// cometd.websocketEnabled = true;
// Open connection to CometD server
cometd.configure({
url: location.protocol + '//' + location.host + config.contextPath + '/cometd',
logLevel: 'debug'
});
cometd.addListener('/meta/*', function(message)
{
if (message.successful)
{
dom.byId('status').innerHTML += '<div>CometD handshake successful</div>';
cometd.subscribe(receiveChannel, function(message) {
dom.byId('results').innerHTML +=' Message from server ' + message.data;
dom.byId('results').innerHTML +=' Subscription to ' + receiveChannel;
});
}
else if(_connectionBroken()){
dom.byId('status').innerHTML += '<div>CometD Connection Broken</div>';
}
else
{
dom.byId('status').innerHTML += '<div>CometD handshake failed</div>';
}
});
dom.byId('greeter').onclick = function()
{
var text = dom.byId('msg').value;
cometd.publish(sendChannel, 'Hello world');
dom.byId('msg').value = "" ;
dom.byId('results').innerHTML +='Message send to server' ;
};
cometd.handshake();
});
2 ответа
var sendChannel = '/service/in'; // Message from jsp
var receiveChannel = '/service/out'; // Message from server
/*var cometdServerURL = 'http://127.0.0.1:8080/cometd';*/
require(['dojox/cometd', 'dojo/dom', 'dojo/domReady!','dojo/_base/unload'], function(cometd, dom)
{ // // configuration object
// Open connection to CometD server
cometd.configure({
url: location.protocol + '//' + location.host + config.contextPath + '/cometd',
logLevel: 'debug'
});
cometd.addListener('/meta/connect', function(message) {
var wasConnected;
if(cometd.isDisconnected()) {
dom.byId('status').innerHTML +=' Disconnected from the server = ' + message;
} else{
/* dom.byId('status').innerHTML +=' Disconnected from the server = ' + message.data;*/
}
});
// listener for handshake
cometd.addListener('/meta/handshake', function(message)
{
if (message.successful)
{
dom.byId('status').innerHTML += '<div>CometD handshake successful</div>';
cometd.batch(function()
{
cometd.subscribe(receiveChannel, function(message) {
dom.byId('results').innerHTML +=' Message from server ' + message.data;
dom.byId('results').innerHTML +=' Subscription to ' + receiveChannel;
});
// cometd.publish('/service/in', { name: 'World' });
});
}
else if(_connectionBroken()){
dom.byId('status').innerHTML += '<div>CometD Connection Broken</div>';
}
else
{
dom.byId('status').innerHTML += '<div>CometD handshake failed</div>';
}
});
dom.byId('greeter').onclick = function()
{
var text = dom.byId('msg').value;
cometd.publish(sendChannel, 'Hello world');
dom.byId('msg').value = "" ;
dom.byId('results').innerHTML +='Message send to server' ;
};
cometd.handshake();
});
Теперь также не может публиковать на каналах
@Service
public class ClientHelloService {
static Logger log = Logger.getLogger(
ClientHelloService.class.getName());
String details;
@Inject
private BayeuxServer bayeuxServer;
@Session
private LocalSession sender;
@Session
private ClientSession bayeuxClient;
@Session
ServerSession session;
int subscribers;
// represent callback
@Listener("/service/in")
public void processClientHello(ServerSession session, ServerMessage message)
{
log.info("Bayeux server =" + bayeuxServer);
log.info("Message = " + message.getData());
log.info("remote Client Id = " + session.getId());
log.info("Local session = " + sender);
log.info("session = " + getSession());
// log.info("sender = " + sender);
details = (String) message.getData();
// session.deliver(sender,"/service/out",getDetails() , null);
testService();
}
private void testService() {
// Create the channel name using the symbol
String channelName = "/service/out";
log.info("Channel Name = " + channelName);
log.info("bayeuxServer : " + (bayeuxServer == null ? "Is Null" : "Is Not Null"));
// Initialize the channel, making it persistant
// new sendChannel
bayeuxServer.createIfAbsent(channelName, new ConfigurableServerChannel.Initializer() {
public void configureChannel(ConfigurableServerChannel channel) {
log.info("Configurable channel " + channel);
// channel exists even if it has no subscribers
channel.setPersistent(true);
channel.setLazy(true);
}
});
System.out.println("CHANNELS : " + bayeuxServer.getChannels().toString());
System.out.println("Subscribers on /service/out = "+bayeuxServer.getChannel("/service/out").getSubscribers().toString());
// convert to cometd format
Map<String, Object> data = new HashMap<String, Object>(4);
data.put("serverMsg", getDetails());
log.info("msg = " + data.get("serverMsg"));
// Publish the channel to all
ServerChannel channel = bayeuxServer.getChannel(channelName);
subscribers = channel.getSubscribers().size();
log.info("Subscribers = " + subscribers);
log.info("channel = " + channel);
// publish the message
try {
channel.publish(getSession(), data, null);
log.info("publish the channel");
}
catch (Exception e){
System.out.println(" Exception = " + e);
}
System.out.println("Session subscriptions :" + sender.getServerSession().getSubscriptions());
System.out.println("Listeners on /service/out = "+bayeuxServer.getChannel("/service/out").getListeners().toString());
System.out.println("Subscribers on /service/out = "+bayeuxServer.getChannel("/service/out").getSubscribers().toString());
publishData(data);
}
public ServerSession getSession() {
return session;
}
public void setSession(ServerSession session) {
this.session = session;
}
private void publishData(Map<String, Object> data) {
System.out.println("Published data = " + data);
}
/* @org.cometd.annotation.Subscription("/service/out")*/
@Subscription("/service/out")
public void echo(Message message)
{
System.out.println("Echo service published " + message);
}
public String getDetails() {
return details;
}
public void setDetails(String details) {
this.details = details;
}
}
В вашем коде есть несколько ошибок, указанных ниже.
Во-первых, вы не хотите, чтобы в вашем JavaScript добавлялся слушатель /meta/*
обрабатывать подписки в if (message.successful)
ветка. Эта ветвь будет выполняться для любого ответа мета-сообщения, например, также для ответов на подписки (которые отправляются через /meta/subscribe
), выполнение кода несколько раз, когда это не является намерением.
Изменить слушателя, чтобы слушать /meta/handshake
канал и выполнить подписку в этом слушателе.
Точно так же вы хотите выполнить if (_connectionBroken())
филиал в /meta/connect
слушатель.
Пожалуйста, обратитесь к учебнику для создания правильного каркаса вашего приложения. Кроме того, следуйте инструкциям, чтобы лучше понять роли ваших слушателей.
Во-вторых, не рекомендуется подписываться от клиента на сервисные каналы. Ознакомьтесь с концепциями CometD, чтобы понять разницу между служебным каналом и широковещательным каналом, а также разницу между добавлением прослушивателя и подпиской.
В-третьих, когда у вас есть сервисный канал, publish()
является локальным действием, поэтому удаленные клиенты не будут доставлять сообщения. Правильный API для использования в этом случае ServerSession.deliver(...)
, если вы действительно хотите использовать сервисные каналы.
Наконец, ваш сценарий использования описан в руководствах, поэтому я рекомендую вам следовать им, и ваше приложение будет работать.
Надеюсь, что это помогло.