標籤:get throw led round 這一 font 程式 public private
(原)
往常前後端通訊基本都是以ajax請求或是表單做資料互動的,這是一種無狀態的http協議,如果要做tcp協議的資料互動,能想到的技術也就socket了,可如果後端是JAVA,前端如何做socket呢,其實這裡用JSP就行,其實這裡如果都用JDK內建的socket client 和 socket server 就OK了,如果換成html呢?那麼JAVA就無能為力了,好在有socket.io。下面來看看如何?吧。
1、你必需知道socket.io實現上就是一個js檔案,它可以在這下載。(https://github.com/socketio/socket.io-client)
上面也寫的很清楚了,最簡單的使用方法,也就幾行代碼。
2、你需要知道JAVA端怎麼寫最方便,實現已經有第三方針對於socket.io完成了JAVA端的實現,只用引入JAR包,調用相應的API就行了,它跟socket.io有個相對應的名字,叫netty-socketio。它可以在這裡下載。(https://github.com/mrniko/netty-socketio)
它的文檔裡也寫了一大堆,實際上你要不出錯最快的上手,只需要這一句話就夠了。
netty-socketio的1.6.6版本支援socket.io1.0以下的版本,最新版的netty-socketio支援1.0以上的socket.io版本。
(別混了概念,netty-socketio指的是JAVA端的一個JAR,socket.io指的是一個JS檔案)
3.這裡就以最新版本以例。
先寫前端。
<!DOCTYPE html><html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>demo</title><script src="js/jquery/jquery-1.8.3.min.js" type="text/javascript"></script><script type="text/javascript" src="js/socket.io/socket.io.js"></script></head><body> </body><script type="text/javascript">//建立TCP串連var socket = io.connect(‘http://192.168.0.104:8998‘);//串連成功後會監聽到socket.on(‘connect‘,function() {output(‘<span>串連成功</span>‘);}); socket.on(‘connecting‘,function() { output(‘<span>正在串連...</span>‘); }); socket.on(‘disconnect‘,function() { output(‘<span>中斷連線! </span>‘); }); socket.on(‘reconnecting‘,function() { output(‘<span>正在重連...</span>‘); }); socket.on(‘reconnect‘,function() { output(‘<span>成功重連!</span>‘); }); socket.on(‘connect_failed‘,function() { output(‘<span>串連失敗!</span>‘); }); //想要中斷連線調用此方法 function sendDisconnect() { socket.disconnect(); } //下面的testMessage是自訂的。 socket.emit(‘testMessage‘, ‘Hello‘,function(){ output(‘<span>‘ + data + ‘</span>‘); }); //socket.emit(‘testMessage‘, ‘你好‘,function(){ //output(‘<span>‘ + data + ‘</span>‘); //}); //這裡是監聽服務端返回的testMessage事件 //socket.on(‘testMessage‘,function(data){ // output(‘<span>‘ + data + ‘</span>‘); //}); function output(message) { var currentTime = "<span class=‘time‘ >" + new Date().toLocaleString() + "</span>"; var element = $("<div>" + currentTime + " " + message + "</div>"); $(‘body‘).prepend(element); } </script></html>
我們叫這個頁面為demo.html
然後再寫JAVA後端
只需要二個類,一個是開啟socket服務的類,一個是監聽的類,這裡只監聽用戶端的串連,斷開和發送testMessage訊息。
package com.ewin.ccr;import com.corundumstudio.socketio.AckRequest;import com.corundumstudio.socketio.SocketIOClient;import com.corundumstudio.socketio.SocketIOServer;import com.corundumstudio.socketio.listener.ConnectListener;import com.corundumstudio.socketio.listener.DataListener;import com.corundumstudio.socketio.listener.DisconnectListener;public class SocketListener implements ConnectListener ,DisconnectListener,DataListener<String>{ private SocketIOServer server; public SocketListener(SocketIOServer server){ this.server = server; } @Override public void onConnect(SocketIOClient client) { Integer clientSize = server.getAllClients().size(); System.out.println("剛連上一個用戶端,總共有" + clientSize + "用戶端串連成功。"); } @Override public void onDisconnect(SocketIOClient client) { Integer clientSize = server.getAllClients().size(); System.out.println("剛離開一個用戶端,總共有" + clientSize + "用戶端串連成功。"); } @Override public void onData(SocketIOClient client, String data, AckRequest ackSender) throws Exception { System.out.println("剛有一個資料從用戶端過來" + data); ackSender.sendAckData("服務端訊息收到!-----"); }}
以上為監聽類
package com.ewin.ccr;import com.corundumstudio.socketio.Configuration;import com.corundumstudio.socketio.SocketIOServer;import com.ewin.ccr.listener.TroutingWipHEventListener;import com.ewin.ccr.util.SocketConfig;public class SocketServer { public static void main(String[] args) { Configuration config = new Configuration(); config.setHostname(SocketConfig.getValue("host")); config.setPort(Integer.parseInt(SocketConfig.getValue("port"))); SocketIOServer server = new SocketIOServer(config); SocketListener socketListener = new SocketListener(server); //用戶端串連上時觸發 server.addConnectListener(socketListener); //監聽用戶端訊息 //工單產品執行監控表頭資料,只發一次,需要由用戶端請求後發送 server.addEventListener("testMessage", String.class, new TroutingWipHEventListener()); //客戶斷串連斷開時觸發 server.addDisconnectListener(socketListener); //啟動服務 server.start();// server.stop(); }}
以上為開啟socket服務的類
運行SocketServer這個類
然後進入我們的demo頁面,你會看到如下資訊
後台會是這樣的。
然後我們嘗試關閉頁面。後台會變成這樣。
我們嘗試關掉JAVA服務,頁面會變成這樣。
其實,這還沒完,這裡不知是BUG,還是什麼原因,會有一個問題。
看到頁面這個地方沒有
現在我們來換一下,發送一個中文的"你好"給後台,我們需要把上面的注釋取消,把下面的注釋放開,改成這樣
然後我們把demo.html頁面重新整理一下,關掉,再重開(這樣是為了使修改的JS生效)
OK,前面沒有問題,再看下我們的二個中文字“你好”過去沒有。
看到沒,後端是亂碼,估計這種問題的第一反應,可能絕大數程式員想的跟我一樣,轉碼出了問題,於是各種前後端編碼,字元集的檢查,但是你會發現,以前出現這種問題時,能用上的轉碼,切換字元集的招數都用遍了, 這裡依然無效。
經過我一天的摸索,得到一個好訊息與一個壞訊息。
先說壞的,百度有人說是socket.io版本不夠新,今天是2017年6月4號,最新版是6月2號的2.0.2版本,我試了一下最新的,問題依然存在。
好訊息是我找到了問題的解決辦法,但是過於暴力。
看下面這段代碼:
跟剛才的本質沒有變,只是延遲0.5秒發送訊息,我們再次重新整理demo.html頁面,來看下背景反應。
看到沒,中文傳送過來了。
那有人可能就要問了,如果做一個即時通訊之類的,那豈不是每次發送訊息都要等上半秒鐘,其實不是這樣的,經過我多次的測試,只有在串連剛建立完成以後的一小段時間內發送中文才會有這個問題(上面其實是連建立後等了0.5秒發送的訊息,實際上測的是延遲0.2秒以上再發送訊息 ,後面收到中文的機率已經很大了),後面再發送都不會有這個問題。
html面頁與JAVA通過Socket 通訊