JS使用WebSocket實現與Java圖形介面(swing)進行通訊
阿新 • • 發佈:2018-12-09
背景:做專案的時候有過這樣的一個需求,在訪問某個網頁的時候進行登入,需要瀏覽器獲取電腦的硬體資源,但是通過瀏覽器直接讀取的方式有些不便,所以想到使用Java開發一個圖形應用介面的程式讀取電腦程式通過socket通訊傳輸給html頁面用於驗證。
寫在前面:在Java伺服器這端開發中,使用到一個jar包,Java-WebSocket-1.3.0.jar,首先引入這個包,這個核心包就是用來複制Java進行WebSocket伺服器的。
步驟1. 然後開始服務端編碼,建立核心服務類WsServer
import java.net.InetSocketAddress; import org.java_websocket.WebSocket; import org.java_websocket.handshake.ClientHandshake; import org.java_websocket.server.WebSocketServer; public class WsServer extends WebSocketServer { public WsServer(int port) { super(new InetSocketAddress(port)); } public WsServer(InetSocketAddress address) { super(address); } @Override public void onOpen(WebSocket conn, ClientHandshake handshake) { // ws連線的時候觸發的程式碼,onOpen中我們不做任何操作 } @Override public void onClose(WebSocket conn, int code, String reason, boolean remote) { //斷開連線時候觸發程式碼 userLeave(conn); System.out.println(reason); } @Override public void onMessage(WebSocket conn, String message) { String msg = "收到資訊:"+message; System.out.println(msg); userJoin(conn,message);//使用者加入 WsUtil.sendMessageToUser(conn,msg); } @Override public void onError(WebSocket conn, Exception ex) { //錯誤時候觸發的程式碼 System.out.println("on error"); ex.printStackTrace(); } /** * 去除掉失效的websocket連結 * @param conn */ private void userLeave(WebSocket conn){ WsUtil.removeUser(conn); } /** * 將websocket加入使用者池 * @param conn * @param userName */ private void userJoin(WebSocket conn,String userName){ WsUtil.addUser(userName, conn); } }
步驟2. 裡面用到了工具類WsUtil,程式碼如下:
import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import org.java_websocket.WebSocket; public class WsUtil { private static final Map<WebSocket, String> wsUserMap = new HashMap<WebSocket, String>(); /** * 通過websocket連接獲取其對應的使用者 * * @param conn * @return */ public static String getUserByWs(WebSocket conn) { return wsUserMap.get(conn); } /** * 根據userName獲取WebSocket,這是一個list,此處取第一個 * 因為有可能多個websocket對應一個userName(但一般是隻有一個,因為在close方法中,我們將失效的websocket連線去除了) * * @param user */ public static WebSocket getWsByUser(String userName) { Set<WebSocket> keySet = wsUserMap.keySet(); synchronized (keySet) { for (WebSocket conn : keySet) { String cuser = wsUserMap.get(conn); if (cuser.equals(userName)) { return conn; } } } return null; } /** * 向連線池中新增連線 * * @param inbound */ public static void addUser(String userName, WebSocket conn) { wsUserMap.put(conn, userName); // 新增連線 } /** * 獲取所有連線池中的使用者,因為set是不允許重複的,所以可以得到無重複的user陣列 * * @return */ public static Collection<String> getOnlineUser() { List<String> setUsers = new ArrayList<String>(); Collection<String> setUser = wsUserMap.values(); for (String u : setUser) { setUsers.add(u); } return setUsers; } /** * 移除連線池中的連線 * * @param inbound */ public static boolean removeUser(WebSocket conn) { if (wsUserMap.containsKey(conn)) { wsUserMap.remove(conn); // 移除連線 return true; } else { return false; } } /** * 向特定的使用者傳送資料 * * @param user * @param message */ public static void sendMessageToUser(WebSocket conn, String message) { if (null != conn && null != wsUserMap.get(conn)) { conn.send(message); } } /** * 向所有的使用者傳送訊息 * * @param message */ public static void sendMessageToAll(String message) { Set<WebSocket> keySet = wsUserMap.keySet(); synchronized (keySet) { for (WebSocket conn : keySet) { String user = wsUserMap.get(conn); if (user != null) { conn.send(message); } } } } }
步驟3. 最後在Main類中開啟主服務:
import org.java_websocket.WebSocketImpl;
public class Main {
public static void main(String[] args) {
WebSocketImpl.DEBUG = false;
int port = 9090; // 埠
WsServer s = new WsServer(port);//例項化一個監聽伺服器
s.start();//啟動伺服器
}
}
步驟4. 點選執行按鈕就可以在9090埠開啟該服務,接下來進行HTML的編碼
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>WebSocket</title>
</head>
<body>
<script>
var socket;
function connectServer(){
var socket_ip="127.0.0.1";
socket= new WebSocket('ws://'+socket_ip+':9090');
socket.onopen = function(event)
{
console.log("連線服務成功!");
sendMsg()
};
// 監聽訊息
socket.onmessage = function(event)
{
console.log('Client received a message',event);
console.log(event.data);
};
// 監聽Socket的關閉
socket.onclose = function(event)
{
};
socket.onerror = function(event) {
//alert('無法連線到:' + socket_ip);
};
}
connectServer()
function sendMsg(){
socket.send("你好!");
}
</script>
</body>
</html>
結果展示:html連線上Java服務程式後併發送“你好”字樣,Java收到後並給與了回覆