【问题标题】:CometD client Java APIn how to?CometD 客户端 Java APIn 如何?
【发布时间】:2016-10-30 20:49:44
【问题描述】:

对于我的项目,我必须使用 pubsubcometD 订阅者。 我将 Oracle Weblogic 应用服务器用于两个应用程序。 其中一个将一些消息发布到 pubsubs 频道,另一个订阅频道以显示消息。 我的 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 工具包订阅频道。 所以现在订阅是在我的 Web 应用程序的客户端完成的,这要归功于这个 Javascript API。

以下是使用 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();
}); 

这个客户端实现运行良好,onEvent() 函数在消息到达 pubsub 通道时被很好地触发。

现在,我希望在服务器端完成订阅和消息处理。为此,我了解到 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(); 处出现以下错误: 严重: java.lang.IncompatibleClassChangeError: org/eclipse/jetty/client/HttpClient

并且永远不会触发 onMessage 函数...

你能给我一些帮助吗?

谢谢,

【问题讨论】:

    标签: javascript java vaadin publish-subscribe cometd


    【解决方案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 7 的 JDK,而 CometD 3.x 仅适用于 JDK 7+。

    恐怕你将不得不重新考虑整个系统。

    我建议坚持使用服务器上的官方 CometD(不是 WebLogic 提供的),如果您真的必须使用 Vaadin/GWT,请查看过去人们是如何编写这些绑定的,也许可以复制如果您不能使用这些库,请使用它们。

    一旦你有 Vaadin/GWT 绑定、服务器中的官方 CometD 和 JDK 7+,你应该很好。

    【讨论】:

    • 感谢您的回复@sbordet。我在我的项目中使用的 CometD API 包含在 maven 中。我不使用 WebLogic 提供的那个。 dojox.cometd.callbackPollTransport 是我的 Javascript 客户端实现,用于订阅和处理消息,但是它可以工作。我将检查我的 JDK 版本并使用 JDK 8 重试,看看是否会再次出现异常。我不希望 Vaadin 将组件翻译成 Javascript,相反我希望它在服务器端进行管理,而不是在客户端。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-05
    相关资源
    最近更新 更多