1. 程式人生 > >JAVA WebSocket 使用時需要註意的地方

JAVA WebSocket 使用時需要註意的地方

max 需要 exce 自動 code 一段 過多 機制 數據庫配置

最近在做一個項目,需要用WebSocket與另外一個平臺建立通訊,來獲取項目業務需要的實時數據,因此項目一啟動,後臺就要與另外一個平臺建立WebSocket連接並且要保證他們的之間有且只有一條持續暢通可用的連接(就是要保證這條連接不能斷開,一斷開就要嘗試進行重連),說說我在這個過程中,遇到的一些問題以及解決的方法:

1、WebSocket連接正常,部分請求無響應

原因分析:

服務端/客戶端接收到客戶端/服務端一次性發來的幾百條或更多的請求,瞬間都堆積在會話的緩沖區,又沒做多線程處理,並且每接收到一條請求還要查詢阿裏雲服務器數據庫,加上網絡帶寬過小,處理一條請求就要花費幾十秒;導致線程隊列嚴重堵塞,無法及時響應處理後續的其他請求。

解決方法:

使用了線程池開啟多條線程同時進行處理,將數據庫配置設置為127.0.0.1,這樣就不會經過公網繞一圈回來,這樣大大縮短了一條請求處理要花費的時間,由之前的幾十秒縮短為幾百毫秒。

    // 創建線程池
    //private static ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
    private static ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);

註意幾種線程池的區別,cachedThreadPool

只有非核心線程,最大線程數很大,它會為每一個任務添加一個新的線程,它有一個超時機制,當空閑的線程超過60s內沒有用到的話,就會被回收。cachedThreadPool缺點就是沒有考慮到系統的實際內存大小。fixedThreadPool是一個可以指定線程數的線程池,有核心的線程,裏面有固定的線程數量,響應的速度快。正規的並發線程,多用於服務器。核心線程是沒有超時機制的,隊列大小沒有限制,除非線程池關閉了核心線程才會被回收。還有singleThreadPoll、scheduledThreadPoll這裏就不做過多的介紹了。

    @OnMessage
    public void onMessage(String datas,Session session) {
        Runnable t 
= new Runnable() { @Override public void run() { // TODO Auto-generated method stub // 業務代碼 } }; //cachedThreadPool.submit(t); fixedThreadPool.submit(t); }

註意,要給session加上同步鎖,否則會出現多個線程同時往同一個session寫數據,導致報錯的情況。

    public void send(String data) throws Exception {
        synchronized (session) {
            session.getBasicRemote().sendText(data);
        }
    }

2、發現WebSocket連接老是每隔一、兩分鐘就斷開重連

原因分析:

一段時間內,WebSocket連接無數據傳輸就會自動斷開連接

解決方法:

增加心跳機制維持連接,每隔一段時間就向服務端發送一次自定義請求,或者調用sendPing()來保持住連接。

3、WebSocket定時發送sendPing()後,還會反復出現接收/發送幾個請求就斷開連接的情況

原因分析:

無論是作服務端還是客戶端,發現每次都是接收到同一個請求的信息後連接就斷開了,經過反復的摸索發現,是由於接收到的這個請求傳輸的數據量過大,超出了WebSocket會話接收信息的緩沖區的大小(可使用session.getMaxTextMessageBufferSize()查看緩沖大小,默認為8192),引起的WebSocket連接的異常斷開。

解決方法:

重新設置WebSocket緩沖區大小,

int maxSize = 200 * 1024;  // 200K

// 可以緩沖的傳入二進制消息的最大長度

session.setMaxBinaryMessageBufferSize(maxSize);

// 可以緩沖的傳入文本消息的最大長度

session.setMaxTextMessageBufferSize(maxSize);

JAVA WebSocket 使用時需要註意的地方