对于我的项目,我必须使用 pubsub 和 cometD 订阅者 . 我使用Oracle Weblogic 应用程序服务器进行两次应用程序 . 其中一个向pubsubs Channels 发布一些消息,另一个订阅 Channels 以显示消息 . 我的pubsub服务器也在weblogic应用服务器上,并配置了一些xml文件(weblogic.xml和weblogic-pubsub.xml) . 以下是我的pubsub服务器的配置方式(weblogic-pubsub.xml):
<wlps:channel>
<wlps:channel-pattern>/gip/**</wlps:channel-pattern>
</wlps:channel>
<wlps:channel-constraint>
<wlps:channel-resource-collection>
<wlps:channel-resource-name>all-permissions</wlps:channel-resource-name>
<wlps:description>Grant all permissions for everything by everyone</wlps:description>
<wlps:channel-pattern>/gip/*</wlps:channel-pattern>
</wlps:channel-resource-collection>
</wlps:channel-constraint>
它运行良好,因为我的第二个应用程序可以使用 cometD subscirber javascript API 和dojo工具包进行通道 . 因此,由于此Javascript API,现在订阅已在我的Web应用程序的客户端完成 .
以下是使用dojo工具包完成订阅客户端(Javascript API)的方法:
//Initialize Dojo (CometD) for pubsub events
dojo.require("dojo.io.script");
dojo.require("dojox.cometd");
dojo.require("dojox.cometd.callbackPollTransport");
dojo.addOnLoad(function ()
{
console.log("on load dojo");
dojox.cometd.init("/WebInterface/cometd", {
});
dojox.cometd.subscribe("/gip/**", onEvent);
initMap();
});
这个 client side 实现运行良好,当消息到达pubsub通道时,onEvent()函数被很好地触发 .
现在,我希望订阅和消息处理完成 server side . 为此,我了解到CometD还有一个客户端Java API,允许订阅pubsub通道并处理消息 . 但我没有成功做到这一点 .
以下是我在CometD 3文档(https://docs.cometd.org/current/reference/#_java_client)之后尝试为服务器端做的事情:
import com.vaadin.ui.CustomComponent;
import java.util.HashMap;
import java.util.Map;
import org.cometd.bayeux.Channel;
import org.cometd.bayeux.Message;
import org.cometd.bayeux.client.ClientSession;
import org.cometd.bayeux.client.ClientSessionChannel;
import org.cometd.client.BayeuxClient;
import org.cometd.client.transport.ClientTransport;
import org.cometd.client.transport.LongPollingTransport;
import org.eclipse.jetty.client.HttpClient;
public class WireServerCometD extends CustomComponent {
private static final String CHANNEL = "/gip";
private final ClientSessionChannel.MessageListener gipListener = new GIPListener();
public WireServerCometD() {
System.out.println("Wire CometD constructor");
setSizeFull();
setWidth(50, Unit.PERCENTAGE);
setHeight(300, Unit.PIXELS);
addStyleName("customBackground");
try {
// Create (and eventually set up) Jetty's HttpClient:
HttpClient httpClient = new HttpClient();
// Here set up Jetty's HttpClient, for example:
// Prepare the transport
Map<String, Object> options = new HashMap<String, Object>();
ClientTransport transport = new LongPollingTransport(options, httpClient);
// Create the BayeuxClient
ClientSession client = new BayeuxClient("http://localhost:8080/WebInterface/cometd", transport);
client.getChannel(CHANNEL).addListener(new ClientSessionChannel.MessageListener() {
public void onMessage(ClientSessionChannel channel, Message message) {
if (message.isSuccessful()) {
// Here handshake is successful
System.out.println("Handshake is successfull");
}
}
});
client.handshake();
} catch (Exception ex) {
ex.printStackTrace();
}
}
private static class GIPListener implements ClientSessionChannel.MessageListener {
public void onMessage(ClientSessionChannel channel, Message message) {
System.out.println("message received");
}
}
}
这是一个Vaadin框架组件,通道订阅和消息监听器在try块中完成 . 我在代码行HttpClient httpClient = new HttpClient(); : SEVERE: java.lang.IncompatibleClassChangeError:org / eclipse / jetty / client / HttpClient
并且onMessage函数永远不会被触发......
你能给我一些帮助吗?
谢谢,
1 回答
首先,我认为WebLogic可能会发布一个非常旧版本的CometD,或者是一个非常定制的版本,与CometD project中的官方版本不匹配 .
dojox.cometd.callbackPollTransport
不是CometD项目中曾经存在的东西,它可能是CometD为0.x时的尝试草案,或者未正式发布的东西,或WebLogic创建的东西 .您有机会使用官方CometD 3.x客户端使用WebLogic提供的“CometD”非常渺茫 . 我怀疑他们是否兼容 .
此外,我不认为Vaadin能够在JavaScript中翻译您在上面编写的组件 . 前段时间,人们在JavaScript中为CometD编写了绑定,但那些从未正式进入CometD项目(缺乏牵引力,见https://github.com/cometd/cometd/issues/63),所以我不确定他们现在处于什么状态 .
IncompatibleClassChangeError
可能是因为您使用的JDK早于JDK 7,而CometD 3.x仅适用于JDK 7 .我担心你将不得不重新考虑整个系统 .
我建议坚持使用服务器上的官方CometD(不是WebLogic提供的),如果你真的必须使用Vaadin / GWT看看人们过去如何编写这些绑定,如果你有可能会复制它们不能使用那些库 .
一旦你有Vaadin / GWT绑定,服务器中的官方CometD和JDK 7,你应该是好的 .