JAVA WebSocket 使用時需要註意的地方
最近在做一個項目,需要用WebSocket與另外一個平臺建立通訊,來獲取項目業務需要的實時數據,因此項目一啟動,後臺就要與另外一個平臺建立WebSocket連接並且要保證他們的之間有且只有一條持續暢通可用的連接(就是要保證這條連接不能斷開,一斷開就要嘗試進行重連),說說我在這個過程中,遇到的一些問題以及解決的方法:
1、WebSocket連接正常,部分請求無響應
原因分析:
服務端/客戶端接收到客戶端/服務端一次性發來的幾百條或更多的請求,瞬間都堆積在會話的緩沖區,又沒做多線程處理,並且每接收到一條請求還要查詢阿裏雲服務器數據庫,加上網絡帶寬過小,處理一條請求就要花費幾十秒;導致線程隊列嚴重堵塞,無法及時響應處理後續的其他請求。
解決方法:
使用了線程池開啟多條線程同時進行處理,將數據庫配置設置為127.0.0.1,這樣就不會經過公網繞一圈回來,這樣大大縮短了一條請求處理要花費的時間,由之前的幾十秒縮短為幾百毫秒。
// 創建線程池 //private static ExecutorService cachedThreadPool = Executors.newCachedThreadPool(); private static ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);
註意幾種線程池的區別,cachedThreadPool
@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 使用時需要註意的地方