日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

websocket使用

發布時間:2023/12/10 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 websocket使用 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

websocket

    • 1. 概述
    • 2. websocket的用法
    • 3. js代碼實現
    • 4. 服務器端代碼實現

maven下載地址:

https://mvnrepository.com/artifact/org.java-websocket/Java-WebSocket

1. 概述

  • 什么是websocket
- WebSocket是一種網絡傳輸協議, 可在單個TCP連接上進行全雙工通信,位于OSI模型的應用層。- WebSocket使得客戶端和服務器之間的數據交換變得更加簡單, 允許服務端主動向客戶端推送數據。- 在WebSocket API中,瀏覽器和服務器只需要完成一次握手, 兩者之間就可以創建持久性的連接,并進行雙向數據傳輸。
  • 簡介
WebSocket: 建立一次連接即可 連接斷開 不會自動重連(心跳機制) 雙向發送數據 WebSocket實現比較復雜(使用jar包)
  • sse與websocket的優點
SSE 使用 HTTP 協議,現有的服務器軟件都支持。WebSocket 是一個獨立協議。 SSE 屬于輕量級,使用簡單;WebSocket 協議相對復雜。 SSE 默認支持服務器斷線重連,WebSocket 需要自己實現。 SSE 一般只用來傳送文本,二進制數據需要編碼后傳送,WebSocket 默認支持傳送二進制數據。 SSE 支持自定義發送的消息類型
  • sse與websocket的區別
SSE 與 WebSocket 作用相似, 都是建立瀏覽器與服務器之間的通信渠道, 然后服務器向瀏覽器推送信息。總體來說,WebSocket 更強大和靈活。 因為它是全雙工通道,可以雙向通信; SSE 是單向通道,只能服務器向瀏覽器發送,因為流信息本質上就是下載。 如果瀏覽器向服務器發送信息,就變成了另一次 HTTP 請求

2. websocket的用法

1.啟動webSocket服務 2.使用js發送數據 (使用了心跳機制保持連接) 3.webSocket服務收到消息將消息發送給指定webSocket

3. js代碼實現

  • js實現(假如現在有一個叫jack的用戶連接服務器)
/*** jack 連接服務器websocket js文件*/var websocket = ''; var ajaxPageNum = 1; var last_health; var health_timeout = 10; var tDates = [], tData = []; var rightIndex;if (window.WebSocket) {// 創建websocket連接 當前連接協議 ip 端口websocket = new WebSocket(encodeURI('ws://' + document.domain + ':8888'));websocket.onopen = function() {console.log('已連接');// 作為標識告訴服務器websocket.send("onlinejack");// 心跳機制 每分鐘連接服務器heartbeat_timer = setInterval(function() {keepalive(websocket)}, 60000);};websocket.onerror = function() {console.log('連接發生錯誤');};websocket.onclose = function() {console.log('已經斷開連接');initWs();};// 消息接收 接收到服務器websocket發來的消息websocket.onmessage = function(message) {console.log(message)console.log(message.data)var jsonMsg = JSON.parse(message.data);console.log(jsonMsg);// 業務代碼}; } else {alert("該瀏覽器不支持提醒。<br/>建議使用高版本的瀏覽器,<br/>如 IE10、火狐 、谷歌 、搜狗等"); }// 上面的代碼封裝 var initWs = function() {if (window.WebSocket) {websocket = new WebSocket(encodeURI('ws://' + document.domain + ':8888'));websocket.onopen = function() {console.log('已連接');websocket.send("onlinejack");heartbeat_timer = setInterval(function() {keepalive(websocket)}, 60000);};websocket.onerror = function() {console.log('連接發生錯誤');};websocket.onclose = function() {console.log('已經斷開連接');initWs();};// 消息接收websocket.onmessage = function(message) {console.log(message)console.log(message.data)// 業務代碼};} else {alert("該瀏覽器不支持提醒。<br/>建議使用高版本的瀏覽器,<br/>如 IE10、火狐 、谷歌 、搜狗等");} }// 心跳包 function keepalive(ws) {var time = new Date();if (last_health != -1 && (time.getTime() - last_health > health_timeout)) {// ws.close();} else {if (ws.bufferedAmount == 0) {ws.send('connect again from jack...');}} }

4. 服務器端代碼實現

  • websocket連接池
package websocket;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 WsPool {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連接去除了)* 根據訂單號找到對應的連接對象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);}}}} }
  • websocket服務器 對用戶的操作
package websocket;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);}@Overridepublic void onOpen(WebSocket conn, ClientHandshake handshake) {// ws連接的時候觸發的代碼,onOpen中我們不做任何操作}@Overridepublic void onClose(WebSocket conn, int code, String reason, boolean remote) {//斷開連接時候觸發代碼userLeave(conn);System.out.println(reason);}@Overridepublic void onMessage(WebSocket conn, String message) {//客戶端發送消息給服務器,自動執行此方法System.out.println(message);//服務器端發送消息給客戶端,//conn.send("消息內容");if(null != message &&message.startsWith("online")){userJoin(conn,message);//用戶加入}else if(null != message && message.startsWith("offline")){userLeave(conn);}}@Overridepublic void onError(WebSocket conn, Exception ex) {//錯誤時候觸發的代碼System.out.println("on error");ex.printStackTrace();}/*** 去除掉失效的websocket鏈接* @param conn*/private void userLeave(WebSocket conn){WsPool.removeUser(conn);}/*** 將websocket加入用戶池* @param conn* @param userName*/private void userJoin(WebSocket conn,String userName){WsPool.addUser(userName, conn);}}
  • 配置websocket啟動 8080port(這里使用過濾器)
package filter;import java.io.IOException;import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse;import org.java_websocket.WebSocketImpl;import websocket.WsServer;public class StartWebSocket implements Filter {@Overridepublic void destroy() {}@Overridepublic void doFilter(ServletRequest arg0, ServletResponse arg1,FilterChain arg2) throws IOException, ServletException {}@Overridepublic void init(FilterConfig arg0) throws ServletException {this.startWebSocketInstantMsg();}/*** 啟動websocket 服務*/public void startWebSocketInstantMsg() {System.out.println("開始啟動webSocket服務...");WebSocketImpl.DEBUG = false;// 端口WsServer server = new WsServer(8888);server.start();}}
  • 發送消息為demo
// websocket向客戶端發送消息 // 根據用戶名找到 用戶和服務器連接到的websocket對象 WebSocket wsConn = WsPool.getWsByUser("online" + toName); // 發送單條消息 msg.setMsgDate(new Timestamp(System.currentTimeMillis())); // System.out.println(wsConn + "\t" + JSON.toJSONString(msg)); WsPool.sendMessageToUser(wsConn, JSON.toJSONString(msg)); 創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的websocket使用的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。