1. 程式人生 > >基於netty的websocket開發小結

基於netty的websocket開發小結

WebSocket是html5規範新引入的功能,用於解決瀏覽器與後臺伺服器雙向通訊的問題,使用WebSocket技術,後臺可以隨時向前端推送訊息,以保證前後臺狀態統一,在傳統的無狀態HTTP協議中,這是“無法做到”的。

WebSocket提出之前,為了解決後臺推送訊息到前臺的需求,提出了一些解決方案,這些方案使用已有的技術(如ajax,iframe,flashplayer,java applet ...),通過一些變通的處理來實現。

webSocket是html5新引入的技術,允許後臺隨時向前端傳送文字或者二進位制訊息,WebSocket是一種全新的協議,不屬於http無狀態協議,協議名為"ws",這意味著一個websocket連線地址會是這樣的寫法:


ws://127.0.0.1:8080/websocket。ws不是http,所以傳統的web伺服器不一定支援,需要伺服器與瀏覽器同時支援, WebSocket才能正常執行,目前的支援還不普遍,需要特別的web伺服器和現代的瀏覽器。

瀏覽器對WebSocket的支援
Google Chrome瀏覽器最先支援WebSocket,隨後是Safari,Firefox,此外最新版本的Opera和IE(Opera11,IE10)也支援WebSocket。

客戶端WebSocket的主要方法

1 建構函式

Java程式碼 收藏程式碼
  1. var websocket = new WebSocket(
    "ws://127.0.0.1:8080/websocket");  
Java程式碼 收藏程式碼
  1. var websocket = new WebSocket("ws://127.0.0.1:8080/websocket");  


2 事件open/message/close/error
WebSocket#onopen, onmessage, onclose, onerror
連線開啟時,回撥onopen方法,接收到後臺訊息時會觸發到onmessage事件,後臺關閉時呼叫onclose,出現連線異常時可在onerror中捕獲
傳送訊息 - WebSocket#send(data)
關閉連線 - WebSocket#close(optional code, optional reason)



下面是一個簡單的html5連線websocket伺服器測試頁

Html程式碼 收藏程式碼
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <scripttype="text/javascript"charset="utf-8">
  5.   windowwindow.WebSocket = window.WebSocket || window.MozWebSocket;  
  6.  if (!window.WebSocket){  
  7.      alert("WebSocket not supported by this browser");  
  8.      return;  
  9.  };  
  10. var websocket = new WebSocket("ws://127.0.0.1:8080/websocket");  
  11.  websocket.onmessage = function(evt){  
  12.      var data = evt.data;  
  13.       alert("received message: " + data);  
  14.  }  
  15.  function send() {  
  16.  var name = document.querySelector("input[namename=name]").value;  
  17.     alert("websocket send message:"+name);  
  18.     websocket.send(name);  
  19.  }  
  20. </script>
  21. </head>
  22. <body>
  23. <labelfor="name">What’s your name:</label>
  24. <inputtype="text"id="name"name="name"/>
  25. <buttononclick="send()">Send</button>
  26. <divid="message"style="color:red"></div>
  27. </body>
  28. </html>
Html程式碼 收藏程式碼
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <scripttype="text/javascript"charset="utf-8">
  5.   windowwindow.WebSocket = window.WebSocket || window.MozWebSocket;  
  6.  if (!window.WebSocket){  
  7.      alert("WebSocket not supported by this browser");  
  8.      return;  
  9.  };  
  10. var websocket = new WebSocket("ws://127.0.0.1:8080/websocket");  
  11.  websocket.onmessage = function(evt){  
  12.      var data = evt.data;  
  13.       alert("received message: " + data);  
  14.  }  
  15.  function send() {  
  16.  var name = document.querySelector("input[namename=name]").value;  
  17.     alert("websocket send message:"+name);  
  18.     websocket.send(name);  
  19.  }  
  20. </script>
  21. </head>
  22. <body>
  23. <labelfor="name">What’s your name:</label>
  24. <inputtype="text"id="name"name="name"/>
  25. <buttononclick="send()">Send</button>
  26. <divid="message"style="color:red"></div>
  27. </body>
  28. </html>



伺服器對WebSocket的支援
    WebSocket不同於http協議,傳統的web伺服器通常不支援WebSocket.而websocket伺服器端的開發大概有藉助 Socket.IO開發、NodeJS和Socket.IO聯合開發以及藉助netty框架開發等等。這裡只對netty框架下的websocket開發 進行一個簡單的說明!

    websocket的協議比較簡單, 客戶端和普通的瀏覽器一樣通過80或者443埠和伺服器進行請求握手,伺服器根據http header識別是否一個websocket請求,如果是,則將請求升級為一個websocket連線,握手成功後就進入雙向長連線的資料傳輸階段. websocket的資料傳輸是基於幀的方式: 0x00 表示資料開始, 0xff表示資料結束,資料以utf-8編碼.

    簡單的說,第一次請求客戶端傳送的是http請求,請求頭中包含websocket相關的資訊,伺服器端對請求進行驗證:

Java程式碼 收藏程式碼
  1. privatevoid handleHttpRequest(ChannelHandlerContext ctx, HttpRequest req) throws Exception {  
  2.      // Allow only GET methods.
  3.      if (req.getMethod() != GET) {  
  4.          sendHttpResponse(ctx, req, new DefaultHttpResponse(HTTP_1_1, FORBIDDEN));  
  5.          return;  
  6.      }  
  7.      // Send the demo page and favicon.ico
  8.      if (req.getUri().equals("/")) {  
  9.          HttpResponse res = new DefaultHttpResponse(HTTP_1_1, OK);  
  10.          ChannelBuffer content = WebSocketServerIndexPage.getContent(getWebSocketLocation(req));  
  11.          res.setHeader(CONTENT_TYPE, "text/html; charset=UTF-8");  
  12.          setContentLength(res, content.readableBytes());  
  13.          res.setContent(content);  
  14.          sendHttpResponse(ctx, req, res);  
  15.          return;  
  16.      } elseif (req.getUri().equals("/favicon.ico")) {  
  17.          HttpResponse res = new DefaultHttpResponse(HTTP_1_1, NOT_FOUND);  
  18.          sendHttpResponse(ctx, req, res);  
  19.          return;  
  20.      }  
  21.      // Handshake
  22.      WebSocketServerHandshakerFactory wsFactory = new WebSocketServerHandshakerFactory(  
  23.              this.getWebSocketLocation(req), nullfalse);  
  24.      this.handshaker = wsFactory.newHandshaker(req);  
  25.      if (this.handshaker == null) {  
  26.          wsFactory.sendUnsupportedWebSocketVersionResponse(ctx.getChannel());  
  27.      } else {  
  28.          this.handshaker.handshake(ctx.getChannel(), req);  
  29.          System.out.println(WebSocketServer.recipients.size());  
  30.          WebSocketServer.recipients.add(ctx.getChannel());  
  31.          System.out.println(WebSocketServer.recipients.size());  
  32.          System.out.println(ctx.getChannel().getId());  
  33.      }  
  34.  }  
Java程式碼 收藏程式碼
  1. privatevoid handleHttpRequest(ChannelHandlerContext ctx, HttpRequest req) throws Exception {  
  2.      // Allow only GET methods.
  3.      if (req.getMethod() != GET) {  
  4.          sendHttpResponse(ctx, req, new DefaultHttpResponse(HTTP_1_1, FORBIDDEN));  
  5.          return;  
  6.      }  
  7.      // Send the demo page and favicon.ico
  8.      if (req.getUri().equals("/")) {  
  9.          HttpResponse res = new DefaultHttpResponse(HTTP_1_1, OK);  
  10.          ChannelBuffer content = WebSocketServerIndexPage.getContent(getWebSocketLocation(req));  
  11.          res.setHeader(CONTENT_TYPE, "text/html; charset=UTF-8");  
  12.          setContentLength(res, content.readableBytes());  
  13.          res.setContent(content);  
  14.          sendHttpResponse(ctx, req, res);  
  15.          return;  
  16.      } elseif (req.getUri().equals("/favicon.ico")) {  
  17.          HttpResponse res = new DefaultHttpResponse(HTTP_1_1, NOT_FOUND);  
  18.          sendHttpResponse(ctx, req, res);  
  19.          return;  
  20.      }  
  21.      // Handshake
  22.      WebSocketServerHandshakerFactory wsFactory = new WebSocketServerHandshakerFactory(  
  23.              this.getWebSocketLocation(req), nullfalse);  
  24.      this.handshaker = wsFactory.newHandshaker(req);  
  25.      if (this.handshaker == null) {  
  26.          wsFactory.sendUnsupportedWebSocketVersionResponse(ctx.getChannel());  
  27.      } else {  
  28.          this.handshaker.handshake(ctx.getChannel(), req);  
  29.          System.out.println(WebSocketServer.recipients.size());  
  30.          WebSocketServer.recipients.add(ctx.getChannel());  
  31.          System.out.println(WebSocketServer.recipients.size());  
  32.          System.out.println(ctx.getChannel().getId());  
  33.      }  
  34.  }  



驗證成功後,將請求升級為一個websocket連線,之後的通訊就進入雙向長連線的資料傳輸階段。

Java程式碼 收藏程式碼
  1. privatevoid handleWebSocketFrame(ChannelHandlerContext ctx, WebSocketFrame frame) {  
  2.     // Check for closing frame
  3.     if (frame instanceof CloseWebSocketFrame) {  
  4.         this.handshaker.close(ctx.getChannel(), (CloseWebSocketFrame) frame);  
  5. 相關推薦

    PHP-elasticsearch配置+基於elasticsearch全文搜尋引擎的開發小結

    首先參照官網內容下載與自己php以及elasticsearch版本相匹配的Php-elasticsearch,按照官網內容進行配置https://www.elastic.co/guide/en/elasticsearch/client/php-api/current/index.ht

    基於netty的websocket開發小結

    WebSocket是html5規範新引入的功能,用於解決瀏覽器與後臺伺服器雙向通訊的問題,使用WebSocket技術,後臺可以隨時向前端推送訊息,以保證前後臺狀態統一,在傳統的無狀態HTTP協議中,這是“無法做到”的。 WebSocket提出之前,為了解決後臺推

    基於node開發的http請求代理

    oss .... http請求 代理 test 寫到 pan eve 常用 今天把項目中的反向代理腳本程序抽成了一個插件,通過配置文件配置代理的http請求,這樣使用起來比較方便,每位開發成員都可以用自己配置的代理調試代碼。 git proxy-ajax: http

    《TD項目開發小結

    自己的 容易 也不能 批評 筆記 跳槽 客戶 做到 不知道 從7月24號開始就進入了TD項目開發了,到今天退出。一共是7周工作日,不算加班的話。整整35個工作日。這是我跳槽後完完整整的從一個項目的開始做到了項目的上線。之前做的XY項目是差不多已經做完了的,一進去就是改bug

    基於jquery開發的UI框架整理分析

    roi black html屬性 二次 quick src 相關 分析 prim 根據調查得知,現在市場中的UI框架差不多40個左右,不知大家都習慣性的用哪個框架,現在市場中有幾款UI框架稍微的成熟一些,也是大家比較喜歡的一種UI框架,那應該是jQuery,有部分U

    如何基於WKWebView開發一個功能完善的資訊內容頁

    可能 方便 styles 運行 文本框 是我 優雅 pan 主題樣式 前言 對於資訊類的APP來說 良好的閱讀體驗是必不可少的, 那麽如何去開發一個功能完善的資訊文章頁面就是本文要說的重點.相信本文會對很多在做同類功能開發的道友們有很大的幫助 , 如果某只大佬路過也歡迎指點

    130242014025(2)敏捷開發小結

    無法識別 .cn 文字 png image 使用 http 比較 格式 1)分組情況介紹,小組分工合作情況介紹。   我們小組是第一組,大家一起討論研究問題,每一個環節分別由不同的成員負責回答。 2)選題討論   經過小組討論,我們最終選擇了電商系統中的搜索功能模塊作為議題

    後臺接口平臺 基於Laravel 開發 快速開發數據接口

    serve exe 執行 bat 集成 目前 compose pan 圖片處理 laravelPCMS V1.5.0 項目地址:https://github.com/q1082121/laravelcms 喜歡的朋友可以支持下 點點星標 百牛信息技術bainiu.ltd整理

    基於Spring開發的一個BIO-RPC框架(對小白很友好)

    instance 啟動項 jar包 pan 發現 就是 遠程 map 配置 PART1:先來整體看下項目的構成 其中bio-rpc-core就是所謂的rpc框架 bio-rpc-example-client即所謂的服務調用方(你的項目中想要調用服務的地方) bio-rp

    基於pyQt5開發的股價顯示器(原創)

    star ets 時間 class 修改 imp price 內網 pre 1 #/usr/bin/env python 2 # -*- coding: utf-8 -*- 3 ‘‘‘ 4 @author="livermorium116" 5 為了繞開

    Spring基於註解開發異常

    lib con 版本 mil line tex 宋體 開發 style 基於註解開發: 一開始:用的jar包: 百度查到: 導入aop包: 沒用 有的說: Spring版本和jdk版本不匹配 於是我換成了4.0版本 導入的jar包:

    學習手記-基於iTOP4412開發板NFS服務器搭建及測試

    udp 都是 使用 共享目錄 none padding rgb 安裝 通訊 NFS特點:1)基於UDP/IP2)功能和網盤基本上差不多,但性能沒那麽強。NFS服務器搭建步驟:在ubantu上安裝nfs軟件:nfs-kernel-server配置文件1)打開配置文件:/etc

    Django基於Pycharm開發之四[關於靜態文件的使用,配置以及源碼分析](原創)

    OS director 一個 pin mes map text 開發人員 容易 對於django靜態文件的使用,如果開發過netcore程序的開發人員,可能會比較容易理解django關於靜態文件訪問的設計原理,個人覺得,這是一個middlerware的設計,但是在djang

    基於socketserver開發多線程ftp

    邏輯 += 登錄 provide pen edi tell %s tar 完成功能: 用戶加密認證 允許同時多用戶登錄 每個用戶有自己的家目錄 ,且只能訪問自己的家目錄 對用戶進行磁盤配額,每個用戶的可用空間不同 允許用戶在ftp server上隨意切換目錄 允許用戶查看

    如何基於 k8s 開發高可靠服務?容器雲牛人有話說

    容器雲?? k8s 是當前主流的容器編排服務,它主要解決「集群環境」下「容器化應用」的「管理問題」,主要包括如下幾方面:?? 容器集群管理 編排? 調度? 訪問? ? 基礎設施管理 計算資源? 網絡資源? 存儲資源?? k8s 的強大依賴於它良好的設計理念和抽象,吸引了越來越多的開發者投入到 k8

    基於flask開發web微信

    window 自己 網頁 time dal -s 最近聯系人 bin in use 流程 階段一 目標:基於falsk編寫登錄頁面,獲取二維碼 解析:1:、二維碼圖片地址有個後綴字符串 2、圖片生成之前,先獲取到隨機字符串再生成二維碼 3、二維碼的圖片的來源

    一、ESP8266入門(基於LUA開發

    opera 包括 blog 情況 探索 到你 哈哈哈 打開 雜項 序 一入坑便停不下來。。。 還挺有意思的哈,233,,,, 資料雜,自己一個一個去找確實浪費了不少時間,而且大多還都是英文的,需要硬著頭皮看。 這次實踐入門,更是對英語的重要確信無疑。Github必

    [ Python ] Flask 基於 Web開發 大型程序的結構實例解析

    精確 object commit static AS AI .sql version bar      作為一個編程入門新手,Flask是我接觸到的第一個Web框架。想要深入學習,就從《FlaskWeb開發:基於Python的Web應用開發實戰》這本書入手,本書由於是翻譯

    基於CXF開發crm服務

    config 註解 註冊服務 mil 一個 action http emp jdbc 1 基於CXF開發crm服務 1.1 數據庫環境搭建 1.2 web項目環境搭建 第一步:創建動態web項目 第二步:導入CXF相關jar包 第三步:配置web.xml

    一個簡單的nodejs api開發小結

    fin 均衡 serve 分布 分布式 follow ngs 成熟 tee 上周接了一個nodejs的小活,寫16個api,有登錄註冊,和對設備,產品,票據的增改刪查。采用了nodejs+express+mysql,其中express第一次使用,作為簡單的路由。之前都是自己