成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

淺談WebSocket協議在Web領域的應用

網絡
WebSocket是一種雙向通信協議,主要應用在Web瀏覽器,解決服務器端主動向瀏覽器推送消息的問題。WebSocket常見的應用場景有頁游、視頻網站、在線文檔、股票網站等。

Part 01、WebSocket是什么?  

WebSocket是一種在Web應用程序中提供雙向通信的協議。它允許服務器主動向客戶端推送數據,而不是像傳統的HTTP請求-響應模式一樣,客戶端必須發送請求才能獲取數據。WebSocket 最早是在HTML5中引入的,建立在HTTP協議之上,使用握手階段來升級連接,然后通過保持連接的狀態來實現實時通信。

與傳統的HTTP協議相比,WebSocket具有以下優勢:

⑴ 增強實時性

服務器可以隨時主動給客戶端下發數據,相對于HTTP請求需要等待客戶端發起請求服務端才能響應,延遲明顯更少。和傳統的輪詢比較,WebSocket也可以在短時間內更有效率地傳遞數據;

⑵ 維持連接狀態

在一些需要身份認證的場景下,HTTP請求可能需要在每個請求都攜帶狀態信息(服務器不記錄每次的請求和響應信息),而WebSocket一次連接建立后就會保持住會話狀態,這就使其成為一種有狀態的協議,后續通信時就可以省略部分狀態信息;

⑶ 更靈活的擴展支持

開發者可以對WebSocket自定義二進制幀,相對HTTP,可以更輕松地處理二進制內容,此外開發者也自行擴展協議、實現部分自定義的子協議;

⑷ 更好的壓縮效果

WebSocket在適當的擴展支持下,可以沿用之前內容的上下文,在傳遞類似的數據時,可以顯著地提高壓縮率。

Part 02、 Websocket報文 

2.1 報文格式

圖片

- 第0個字節

0位(FIN):0表示報文沒有結束,1表示報文結束。

1-3位(RSV1、RSV2、RSV3):保留字段,一般全部為0。也可用于擴展自己的協議。

4-7位(opcode):報文類型。0 代表一個繼續幀,1代表文本幀,2代表二進制幀,8 代表連接關閉,9 代表ping,10代表pong。

- 第1個字節

8位(MASK):1表示需要掩碼操作,0表示不需要。如果為1,數據幀的masking-key屬性會存在一個值,接收方會利用這個值來進行解掩碼操作,所有從客戶端傳輸到服務器的數據幀的Mask都被設置為1。

9-15位(Payload len):表示Payload data的長度。如果值是0~125,則真實長度就是前7位表示;如果值是126,則真實長度就是后16位(Extended payload length 126);如果值是127,則真實長度就是后64位(Extended payload length 127)

2.2 報文樣例

- ping幀,Opcode=9,Mask=1,Payload len=0,Masking-Key有內容

圖片圖片

- pong幀,Opcode=10,Mask=0,Payload len=0,Masking-Key為空

圖片

- 文本幀,Opcode=1,Mask=0,Payload len=84,Masking-Key為空

圖片

Part 03、  代碼實現  

接下來,一起動手編寫WebSocket服務端和客戶端,這里提供一個java版的服務端demo和一個html版的客戶端demo。

1、服務端demo是一個springboot項目

- 引用spring-boot-starter-websocket依賴

<!-- WebSocket -->
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-websocket</artifactId>
</dependency>

- session管理

public class WsSessionManager {
    public static ConcurrentHashMap<String, WebSocketSession> SESSION_POOL = new ConcurrentHashMap<>();
    public static void add(String key, WebSocketSession session) {
        SESSION_POOL.put(key, session);
    }
    public static WebSocketSession remove(String key) {
        return SESSION_POOL.remove(key);
    }
    public static void removeAndClose(String key) {
        WebSocketSession session = remove(key);
        if (session != null) {
            try {
                session.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    public static WebSocketSession get(String key) {
        return SESSION_POOL.get(key);
    }
}

- 消息處理

@Component
@Slf4j
public class MyWsHandler extends AbstractWebSocketHandler {
    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        log.info("建立ws連接,sessionId:{}", session.getId());
        WsSessionManager.add(session.getId(), session);
    }
    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        // 獲得客戶端傳來的消息
        String payload = message.getPayload();
        log.info("server 接收到消息, sessionId " + session.getId() + ", payload: " + payload);
        session.sendMessage(new TextMessage("server 發送給的消息 " + payload + ",發送時間:" + LocalDateTime.now().toString()));
    }
    @Override
    protected void handleBinaryMessage(WebSocketSession session, BinaryMessage message) {
        log.info("發送二進制消息, sessionId " + session.getId());
    }
    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) {
        log.error("異常處理, sessionId " + session.getId());

- WebSocket配置

@Configuration
@EnableWebSocket
public class WsServerConfig implements WebSocketConfigurer {
    @Autowired
    private MyWsHandler myWsHandler;
    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        registry.addHandler(myWsHandler, "myWs")
                //允許跨域
                .setAllowedOrigins("*");
    }
}

2、客戶端demo是一個html網頁

<!doctype html>
<form name="publish">
  <input type="text" name="message" maxlength="50"/>
  <input type="submit" value="Send"/>
</form>
<div id="messages"></div>
<script>
let url='ws://127.0.0.1:8889/myWs';
let socket = new WebSocket(url);
// send message from the form
document.forms.publish.onsubmit = function() {
  let outgoingMessage = this.message.value;
  socket.send(outgoingMessage);
  return false;
};
// handle incoming messages
socket.onmessage = function(event) {
  let incomingMessage = event.data;
  showMessage(incomingMessage);
};
socket.onclose = event => console.log(`Closed ${event.code}`);
// show message in div#messages
function showMessage(message) {
  let messageElem = document.createElement('div');
  messageElem.textContent = message;
  document.getElementById('messages').prepend(messageElem);

Part 04、 結束語  

WebSocket適用于服務器端需要快速向瀏覽器發送消息的場景,例如網頁游戲、視頻網站、在線文檔、運維工具等。瀏覽器可以看做是一個瘦客戶端,它不提供直接操作tcp長連接的編程接口,也無法簡單地集成消息組件客戶端。在使用瀏覽器作為客戶端的場景下,WebSocket是最常用的服務器端主動推送方案。

當然,有很多種技術可以實現服務器端向客戶端主動推送消息,WebSocket只是其中一種,其他常見的方案還有tcp長連接、消息組件(如mqtt、kafka)等,不過各有優缺點,這個可以在日后進一步學習。

責任編輯:龐桂玉 來源: 移動Labs
相關推薦

2023-12-29 20:25:51

2011-05-18 16:02:08

XML

2010-06-12 17:28:35

協議封裝

2022-11-29 19:44:47

WebOpenResty防火墻

2012-05-31 02:35:43

MySQLWEBNoSQL

2011-09-08 17:48:33

Web Widget

2021-08-05 09:23:56

人工智能大數據物聯網

2023-10-04 00:14:00

WebSocket網絡協議

2024-12-18 14:10:33

2017-12-04 12:50:26

2017-05-16 08:24:37

WebSocket容器應用

2010-06-25 15:22:16

2023-11-28 12:39:40

支付對賬領域

2010-06-28 15:52:17

2020-12-25 13:51:49

大數據醫療大數據

2009-06-29 15:51:48

Spring容器

2023-06-18 19:26:10

藍牙智能家居

2009-09-29 10:46:58

Hibernate領域

2017-08-17 17:48:06

2018-06-14 16:15:10

點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 成人在线观 | 久久久毛片 | 国产欧美在线播放 | 天天综合国产 | 国产精品高清在线 | 2019中文字幕视频 | 久久国产电影 | 国产精品成人一区二区三区吃奶 | 天天干夜夜拍 | 91久久国产综合久久91精品网站 | 91精品国产综合久久久久久 | 欧美激情视频一区二区三区在线播放 | 久久99精品久久久久久国产越南 | 中文字幕欧美一区二区 | 欧州一区 | 色伊人 | 国产资源一区二区三区 | 国产精品久久久久久久一区二区 | 日韩在线观看中文字幕 | 国产 日韩 欧美 中文 在线播放 | 欧美不卡| 日韩超碰| 一本色道精品久久一区二区三区 | 成人国产精品久久 | 国产精品久久久久久影院8一贰佰 | 91大神在线资源观看无广告 | 亚洲精品电影网在线观看 | 热久久999 | 国产精品毛片一区二区在线看 | 一区二区视频免费观看 | 国产四区 | 九七午夜剧场福利写真 | 日本偷偷操| 日本电影免费完整观看 | 蜜桃臀av一区二区三区 | 天堂一区二区三区 | 91色综合| 在线看av网址 | 日日操视频| 国产精品久久久久久亚洲调教 | 国产精品自拍啪啪 |