【问题标题】:Writing my own trivial Bayeux client编写我自己的琐碎的 Bayeux 客户端
【发布时间】:2016-02-12 11:16:30
【问题描述】:

我正在尝试了解 Bayeux 协议。我还没有找到详细解释bayeux 客户端在技术上如何工作的网络资源。

来自this 资源,

Bayeux 协议要求新客户端发送的第一条消息 是握手消息(在 /meta/handshake 通道上发送的消息)。

客户端处理握手回复,如果成功, 开始——在幕后——与服务器的心跳机制,通过 交换连接消息(在 /meta/connect 上发送的消息 频道)。

这种心跳机制的细节取决于客户端 使用了传输,但可以看作是客户端发送连接 消息并期待一段时间后的回复。

连接消息继续在客户端和服务器之间流动,直到 任何一方决定通过发送断开消息(a 在 /meta/disconnect 通道上发送的消息)。

我用 Java 编写了首先进行握手,然后订阅特定频道的方法。我利用 Apache HttpClient 库来执行 HTTP POST 请求。

现在是连接部分。

我的理解是,我需要保持对bayeux服务器的请求开放,并且每当我收到响应时,就发出另一个请求。

我已经编写了以下代码。我的理解是否正确,这个bayeux客户端是否表现出正确的连接功能? (请忽略缺少的断开连接、取消订阅方法)

另外,我已经针对 Bayeux 服务器测试了代码,它可以正常工作。

/* clientId - Unique clientId returned by bayeux server during handshake
    responseHandler - see interface below */

private static void connect(String clientId, ResponseHandler responseHandler) 
        throws ClientProtocolException, UnsupportedEncodingException, IOException {
    String message = "[{\"channel\":\"/meta/connect\"," 
                    + "\"clientId\":\"" + clientId + "\"}]"; 
    CloseableHttpClient httpClient = HttpClients.createDefault();
    

    Thread t = new Thread(new Runnable() {

        @Override
        public void run() {
            while (!doDisconnect) {
                try {
                    CloseableHttpResponse response = HttpPostHelper.postToURL(ConfigurationMock.urlRealTime,
                            message, httpClient, ConfigurationMock.getAuthorizationHeader());

                    responseHandler.handleResponse(response);
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } 
            }
        
            try {
                httpClient.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

    });
    t.start();
        
}

/*Simple interface to define what happens with the response when it arrives*/

private interface ResponseHandler {
    void handleResponse(CloseableHttpResponse httpResponse);
}

public static void main(String[] args) throws Exception{
    String globalClientId = doHandShake();  //assume this method exists
    subscribe(globalClientId,"/measurements/10500"); //assume this method exists
    connect(globalClientId, new ResponseHandler() {
        @Override
        public void handleResponse(CloseableHttpResponse httpResponse) {
            try {
                System.out.println(HttpPostHelper.toStringResponse(httpResponse));
            } catch (ParseException | IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            
        }
    });
}

【问题讨论】:

    标签: java bayeux


    【解决方案1】:

    您的代码不正确。

    /meta/connect 频道上的消息没有 subscription 字段。

    订阅必须通过/meta/subscribe 频道发送。

    您想研究Bayeux Specification 以了解更多详细信息,尤其是meta messages sectionevent messages section

    一个建议是launch the CometD Demo 并查看客户端交换的消息,并在您的实现中模仿这些消息。

    【讨论】:

    • 是的,你说得对,connect 没有订阅字段。在我的示例中,它在服务器端被忽略(并且代码正常工作)。你的意思是说除此之外,我的实现正确吗?我写了一个订阅函数,它在之前的调用中订阅了一个频道。
    • 您的代码不正确。它不考虑advice 字段来决定是否以及何时发出/meta/connect 消息。如果发生异常,您将处于烧毁 CPU 的自旋循环中。如果发生非IOException,则关闭 HTTP 客户端并退出。您的实现是阻塞的,这对于一个简单的示例来说很好,但通常您不想这样做,因为它无法扩展。您不希望应用程序调用您的 connect 方法,这应该由实现在内部完成。
    • 正如我在回答中所说,您想研究 Bayeux 协议和 CometD implementation,看看那里是如何完成的。
    猜你喜欢
    • 1970-01-01
    • 2011-10-05
    • 1970-01-01
    • 2011-02-18
    • 1970-01-01
    • 2011-11-17
    • 1970-01-01
    • 1970-01-01
    • 2013-03-11
    相关资源
    最近更新 更多