簡體   English   中英

如何在Java中捕獲Tibrv RVD.DISCONNECTED消息?

[英]How to catch Tibrv RVD.DISCONNECTED message in Java?

我從Java進程開始的Tibrv連接運行時間長。

我很驚訝今天看到此日志條目(打印在stderr上):

2018-02-01 08:15:44 RV:進程未處理TIB /集合錯誤:{ADV_CLASS =“ WARN” ADV_SOURCE =“ SYSTEM” ADV_NAME =“ RVD.DISCONNECTED”}

捕獲此錯誤並重新連接的正確方法是什么?

我的過程需要容錯。 (我認為另一端的服務器已重新啟動。)

連接代碼示例:

Tibrv.open(Tibrv.IMPL_NATIVE);
final TibrvRvdTransport tibrvRvdTransport =
    new TibrvRvdTransport(tibrvService, nullableTibrvNetwork, tibrvDaemon);

根據官方Tibrv文檔 (p282),有一個名為_RV.WARN.SYSTEM.RVD.DISCONNECTED系統咨詢消息 但是,我不知道收聽此消息的正確方法,也不知道收到后即嘗試恢復。

這花了我一段時間才能弄清楚,所以我在回答自己的問題。

簡而言之,Tibrv Java庫使用私有線程來自動監視斷開連接和重新連接。 “用戶空間”監視的目的是優雅地處理這些事件(容錯等)。

技術解決方案是偵聽兩種特殊的RVD消息:

  • _RV.WARN.SYSTEM.RVD.DISCONNECTED
  • _RV.INFO.SYSTEM.RVD.CONNECTED

可以使用帶有主題通配符的單個TibrvListener

final String subjectWildcard = "_RV.*.SYSTEM.RVD.*";
final Object nullableClosure = null;
new TibrvListener(
    Tibrv.defaultQueue(),
    // @NotThreadSafe
    new TibrvMsgCallback() {
        @Override
        public void onMsg(TibrvListener tibrvListener, TibrvMsg tibrvMsg) {
            final String sendSubject = tibrvMsg.getSendSubject();
            if ("_RV.WARN.SYSTEM.RVD.DISCONNECTED".equals(sendSubject)) {
                // TODO
            }
            else if ("_RV.INFO.SYSTEM.RVD.CONNECTED".equals(sendSubject)) {
                // TODO
            }
        }
    },
    tibrvRvdTransport, subjectWildcard, nullableClosure);

// Next: Setup a daemon thread to dispatch incoming Tibrv messages.
{
    final Thread thread = new Thread(() -> {
        final TibrvQueue tibrvQueue = Tibrv.defaultQueue();
        while (true) {
            try {
                tibrvQueue.dispatch();
            }
            catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
    });
    thread.setDaemon(true);
    thread.start();
}

感謝TibrvListenerTibrvQueue.dispatch()

如何測試斷開和重新連接事件:

  1. 從命令行創建Tibrv偵聽器:
    • $ tibrvlisten -service 8800 -daemon tcp:8800 TEST.MESSAGE
  2. 從命令行發送測試消息:
    • $ tibrvsend -service 8800 -daemon ${tibrvlisten.hostname}:8800 TEST.MESSAGE hello
    • tibrvlisten應該記錄: subject=TEST.MESSAGE, message={DATA="hello"}
  3. 在Java中,連接到Tibrv偵聽器: new TibrvRvdTransport("8800", null, "${tibrvlisten.hostname}:8800")
  4. 使用Ctrl + C停止tibrvlisten ,然后終止后台進程rvd ,例如, $ ps -efjww | egrep 'rvd +-listen' | awk '{print $2}' | xargs kill $ ps -efjww | egrep 'rvd +-listen' | awk '{print $2}' | xargs kill
  5. 在Java中,收到斷開連接事件后,立即發送消息:
    • final TibrvMsg m = new TibrvMsg(); m.setSendSubject("TEST.MESSAGE"); m.add("DATA", "hello"); tibrvRvdTransport.send(m);
    • send()將因TibrvException而失敗:error = 21,message =“無法連接到守護程序”
    • 可在此處找到公共字段int TibrvException.error值: TibrvStatus ,例如DAEMON_NOT_CONNECTED = 21
  6. 重新啟動tibrvlisten然后等待Java后台線程自動重新連接。
  7. 在Java中,一旦接收到重新連接事件,就可以再次發送消息而不會出現錯誤。

tibrvlisten

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM