似乎javascript客户端无法订阅广播 Channels 或从其接收消息 . 下面是spring-cometd服务代码,它在收到来自外部事件的消息后在 notification Channels 上广播消息 . java-cometd客户端可以非常接收广播消息 . 即使是javascript客户端也可以在 service channels 上发布和订阅消息,但不能在广播 Channels 上发布和订阅消息 . 订阅在握手后完成 .
JavaScript代码:
var cometd = $.cometd;
cometd.addListener('/meta/handshake', _metaHandshake);// handshake listener
cometd.addListener('/meta/connect', _metaConnect);//connection connect listener
cometd.addListener('/meta/disconnect', _metaDisconnect);
cometd.handshake();
function _metaHandshake(handshake)
{
if (handshake.successful === true)
{
cometd.batch(function()
{
cometd.subscribe('/notification', function(m) {alert("hi"); });
});
}
当javascript客户端订阅广播 Channels 时会出现什么问题 .
@javax.inject.Named // Tells Spring that this is a bean
@javax.inject.Singleton // Tells Spring that this is a singleton
@Service("notificationService")
public class NotificationService {
private static final String channelName="/notification";
private static ServerChannel serverChannel;
private Logger logger = Logger.getLogger(this.getClass());
@Inject
private BayeuxServer bayeuxServer;
@Session
private LocalSession session;
@PostConstruct
public void init()
{
logger.debug("Notification Service Initialized");
channelSetUp();
session = bayeuxServer.newLocalSession("external");
session.handshake();
}
public void channelSetUp()
{
MarkedReference<ServerChannel> channelCreated = bayeuxServer.createChannelIfAbsent(channelName, new ServerChannel.Initializer()
{
public void configureChannel(ConfigurableServerChannel channel)
{
channel.setPersistent(true);// channel persistent
channel.addAuthorizer(GrantAuthorizer.GRANT_SUBSCRIBE_PUBLISH);
}
});
if(channelCreated.isMarked())
{
serverChannel = bayeuxServer.getChannel(channelName);
}
}
public void onExternalEvent( Map<String, Object> data)
{
// ServerChannel serverChannel = this.bayeuxServer.getChannel(channelName);
// logger.debug("Notify MessageData from JMS ::" + data.toString());
if (serverChannel != null)
{
// Broadcast the data
serverChannel.publish(session, data, null);
}
}
@Listener(Channel.META_SUBSCRIBE)
public void processSubscription(ServerSession remote, ServerMessage message)
{
// What channel the client wants to subscribe to ?
String channel = (String)message.get(Message.SUBSCRIPTION_FIELD);
logger.debug("Client Channel ::"+channel);
}
}
1 回答
您的客户端代码是正确的 .
您的服务器代码可以改进,特别是:
您无需在
init()
中创建本地会话:@Session
注释为您完成 .您无需在
init()
中调用channelSetup()
:只需使用@Configure
注释即可 .您不需要存储对
ServerChannel
的引用:因为您使通道持久化,所以在_2793719中只需执行:bayeuxServer.getChannel(channelName).publish(...);
如果您正确地遵循了文档中描述的Spring integration的文档,并且避免了创建2
BayeuxServer
实例(使用Spring时的典型错误),那么您应该很高兴 .我建议您在客户端和服务器中使用enable debug logging并查看日志,这应该可以解释为什么您的JavaScript客户端不接收消息 .
希望有所帮助!