<font id="zqva1"></font>
<rt id="zqva1"></rt>
  • <tt id="zqva1"></tt>
    <cite id="zqva1"></cite>

    <cite id="zqva1"><noscript id="zqva1"></noscript></cite>
      <rp id="zqva1"><meter id="zqva1"></meter></rp>

        <cite id="zqva1"></cite>
          <b id="zqva1"></b>
          <rp id="zqva1"></rp>
          <cite id="zqva1"></cite>

          <rt id="zqva1"></rt>

        1. <rp id="zqva1"></rp>

          WebSocket的原理及WebSocket API的使用,js中如何運用websocket

          時間:?2017-11-08閱讀:?9014標簽:?js知識

          在Websocket出現之前,我們要實現和服務器端保持實時通信,只能采用long poll和ajax輪詢,它們的原理都是讓瀏覽器隔個幾秒就發送一次請求,詢問服務器是否有新信息。都是通過不斷地建立HTTP連接,然后等待服務端處理, 這對應服務器來說消耗是非常大。在這樣的前提下,Websocket就出現了,它很好的解決了http協議的被動型,這樣服務端就能主動推送信息給客戶端了。

          Websocket 是什么? 

          WebSocket是HTML5下一種新的協議,為解決客戶端與服務端實時通信而產生的技術。其本質是先通過HTTP/HTTPS協議進行握手后創建一個用于交換數據的TCP連接,此后服務端與客戶端通過此TCP連接進行實時通信,能更好的節省服務器資源和帶寬并達到實時通訊的目的。但是它和HTTP最大不同是:  

          WebSocket是一種雙向通信協議。在建立連接后,WebSocket服務器端和客戶端都能主動向對方發送或接收數據,就像Socket一樣;
          WebSocket需要像TCP一樣,先建立連接,連接成功后才能相互通信。

          傳統HTTP客戶端與服務器請求響應模式如下:  


          WebSocket客戶端與服務器請求響應模式如:  


          從上圖可以看出:WebSocket只需要經過一次HTTP請求,就可以做到源源不斷的信息傳送了。(在程序設計中,這種設計叫做回調,即:你有信息了再來通知我,而不是我傻乎乎的每次跑來問你),這樣的協議解決了上面同步有延遲,而且還非常消耗資源的這種情況。

          Websocket 的應用場景

          社交聊天、多玩家游戲、彈幕、協同編輯、股票基金實時報價、體育實況更新、視頻會議/聊天、基于位置的應用、在線教育、智能家居等,都需要高實時的場景  

          HTML5 WebSockets API  

          1、瀏覽器支持情況檢測 

          function demo() {  
              if (window.WebSocket) {  
                  //支持 
              } else {  
                  //不支持
              }  
          }

          2、WebSocket對象的創建和服務器連接 

          創建了Websocket實例,WebSocket構造函數的第二個參數既可以是字符串,也可以是字符串組,代表應用能夠使用的協議;其中ws://和wss://前綴分別表示WebSocket連接和安全的WebSocket連接。    

          ws = new WebSocket("ws://127.0.0.1:8080/Server_Test.php");  
          w = new WebSocket(url);
          //或w = new WebSocket(url,['proto1','proto2']);

          3. 建立連接后回調函數

          ws.onopen = function(event){}

          4. 收到服務端消息后回調函數

          ws.onmessage = function(event){}

          5. 關閉連接后回調函數

          ws.onclose = function(event){}

          6. 連接錯誤后回調函數

          ws.onerror = function(event)

          7. 發送數據

          ws.send('服務器,您好');

          8. 查看當前連接狀態

          console.log(ws.readyState)

          9.服務器端的實現(以php為例):

          //1. 創建服務端WebSocket對象,等待客戶端接入             
          $master  = WebSocket("localhost",10000);             
          首先創建Websocket,然后服務端監聽相應端口,等待客戶端接入             
          function WebSocket($address,$port){
          	$master=socket_create(AF_INET, SOCK_STREAM, SOL_TCP)  or die("socket_create() failed");             
          	socket_set_option($master, SOL_SOCKET, SO_REUSEADDR, 1)  or die("socket_option() failed");             
          	socket_bind($master, $address, $port) or die("socket_bind() failed");             
          	socket_listen($master,20) or die("socket_listen() failed");             
          	echo "Server Started : ".date('Y-m-d H:i:s')."\n";             
          	echo "Master socket  : ".$master."\n";             
          	echo "Listening on   : ".$address." port ".$port."\n\n";             
          	return $master;             
          }          
          //2. 從WebSocket中讀取數據             
          $buffer = socket_read($socket,2048);          
          //3. 當收到客戶端首次連接請求后,生成握手信息并回復             
          $return_str = dohandshake($buffer);             
          socket_write($socket,$return_str,strlen($return_str));          
          //4. 連接后,即可接收并解析出客戶端的數據             
          $buffer = socket_read($socket,2048);             
          $data_str = decode($buffer);          
          //5. 接收到用戶數據后,直接回復客戶端             
          socket_write($socket,$return_str,strlen($return_str));          
          //6. 斷開連接             
          socket_close($socket);

          WebSocket例子

          在這里寫一下在Tomcat8下執行的例子。例子由客戶端頁面和WebSocket服務程序組成,功能在Echo基礎上增加一個服務端定時發送信息的功能。

          ws.html代碼:

          <!DOCTYPE html>  
          <html>  
          <head>  
          <meta charset="UTF-8">  
          <title>Test WebSocket</title>  
          <script type="text/javascript">  
              //顯示信息  
              var log = function(s) {  
                  if (document.readyState !== "complete") {  
                      log.buffer.push(s);  
                  } else {  
                      document.getElementById("output").textContent += (s + "\n");  
                      document.getElementById("outputdiv").scrollTop = document.getElementById("outputdiv").scrollHeight;  
                  }  
              }  
              log.buffer = [];  
              //顯示連接狀態  
              function setConnected(status) {  
                  document.getElementById("socketstatus").innerHTML = status;  
              }  
              var ws = null;  
                
              //連接  
              function connect() {  
                  if (ws != null) {  
                      log("現已連接");  
                      return ;  
                  }  
                  url = "ws://localhost:8080/websocket/mywebsocket";  
                  if ('WebSocket' in window) {  
                      ws = new WebSocket(url);  
                  } else if ('MozWebSocket' in window) {  
                      ws = new MozWebSocket(url);  
                  } else {  
                      alert("您的瀏覽器不支持WebSocket。");  
                      return ;  
                  }  
                  ws.onopen = function() {  
                      log("open");  
                      setConnected("已連接");  
                      //設置發信息送類型為:ArrayBuffer  
                      ws.binaryType = "arraybuffer";  
                        
                      //發送一個字符串和一個二進制信息  
                      ws.send("thank you for accepting this WebSocket request");  
                      var a = new Uint8Array([8, 6, 7, 5, 3, 0, 9]);  
                      ws.send(a.buffer);  
                  }  
                  ws.onmessage = function(e) {  
                      log(e.data.toString());  
                  }  
                  ws.onclose = function(e) {  
                      log("closed");  
                  }  
                  ws.onerror = function(e) {  
                      log("error");  
                  }  
              }  
                
              //斷開連接  
              function disconnect() {  
                  if (ws != null) {  
                      ws.close();  
                      ws = null;  
                      setConnected("已斷開");  
                  }  
              }  
                
              window.onload = function() {  
                  connect();  
                  log(log.buffer.join("\n"));  
                  //發送頁面上輸入框的信息  
                  document.getElementById("sendButton").onclick = function() {  
                      if (ws != null) {  
                          ws.send(document.getElementById("inputMessage").value);   
                      }  
                  }  
                  //停止心跳信息  
                  document.getElementById("stopButton").onclick = function() {  
                      if (ws != null) {  
                          var a = new Uint8Array([1, 9, 2, 0, 1, 5, 1, 6]);  
                          ws.send(a.buffer);   
                      }  
                  }  
              }  
          </script>  
          </head>  
          <body onunload="disconnect();">  
              <div>連接狀態:<span id="socketstatus"></span></div>  
              <div>  
                  <input type="text" id="inputMessage" value="Hello, WebSocket!">  
                  <button id="sendButton">發送</button><button id="stopButton" style="margin-left:15px">停止心跳信息</button>  
              </div>  
              <div>  
                  <button id="connect" onclick="connect();">連接</button>  
                  <button id="disconnect" onclick="disconnect();">斷開</button>  
              </div>  
              <div style="height:300px; overflow:auto;" id="outputdiv">  
                  <pre id="output"></pre>  
              </div>  
          </body>  
          </html>

          Websocket服務端java程序代碼:

          package com.test.wsocket;  
           
          import java.io.IOException;  
          import java.nio.ByteBuffer;  
          import java.util.Random;  
          import java.util.Timer;  
          import java.util.TimerTask;  
            
          import javax.websocket.OnClose;  
          import javax.websocket.OnMessage;  
          import javax.websocket.OnOpen;  
          import javax.websocket.PongMessage;  
          import javax.websocket.Session;  
          import javax.websocket.server.ServerEndpoint;  
            
          @ServerEndpoint("/mywebsocket")  
          public class MyWebSocket {  
                
              private Session session;  
              private static final Random random = new Random();  
              private Timer timer = null;  
              //停止信息信息指令  
              private static final ByteBuffer stopbuffer  = ByteBuffer.wrap(new byte[]{1, 9, 2, 0, 1, 5, 1, 6});  
                
              /**  
               * 打開連接時執行  
               * @param session  
               */  
              @OnOpen  
              public void start(Session session) {  
                  this.session = session;  
                  try {  
                      System.out.println("open");  
                      if (session.isOpen()) {  
                          //設置心跳發送信息。每2秒發送一次信息。  
                          timer = new Timer(true);  
                          timer.schedule(task, 1000, 2000);  
                      }  
                  } catch (Exception e) {  
                      try {  
                          session.close();  
                      } catch (IOException e1) {}  
                  }  
              }  
            
              /**  
               * 接收信息時執行  
               * @param session  
               * @param msg 字符串信息  
               * @param last  
               */  
              @OnMessage  
              public void echoTextMessage(Session session, String msg, boolean last) {  
                  try {  
                      if (session.isOpen()) {  
                          System.out.println("string:" + msg);  
                          session.getBasicRemote().sendText(msg, last);  
                      }  
                  } catch (IOException e) {  
                      try {  
                          session.close();  
                      } catch (IOException e1) {  
                          // Ignore  
                      }  
                  }  
              }  
            
              /**  
               * 接收信息時執行  
               * @param session  
               * @param bb 二進制數組  
               * @param last  
               */  
              @OnMessage  
              public void echoBinaryMessage(Session session, ByteBuffer bb, boolean last) {  
                  try {  
                      if (session.isOpen()) {  
                          //如果是停止心跳指令,則停止心跳信息  
                          if (bb.compareTo(stopbuffer) == 0) {  
                              if (timer != null) {  
                                  timer.cancel();  
                              }  
                          } else {  
                              session.getBasicRemote().sendBinary(bb, last);  
                          }  
                      }  
                  } catch (IOException e) {  
                      try {  
                          session.close();  
                      } catch (IOException e1) {  
                          // Ignore  
                      }  
                  }  
              }  
                
              /**  
               * 接收pong指令時執行。  
               *  
               * @param pm    Ignored.  
               */  
              @OnMessage  
              public void echoPongMessage(PongMessage pm) {  
                  // 無處理  
              }  
                
              @OnClose  
              public void end(Session session) {  
                  try {  
                      System.out.println("close");  
                      if (timer != null) {  
                          timer.cancel();  
                      }  
                  } catch(Exception e) {  
                  }  
              }  
                
              /*  
               * 發送心跳信息  
               */  
              public void sendLong(long param) {  
                  try {  
                      if (session.isOpen()) {  
                          this.session.getBasicRemote().sendText(String.valueOf(param));  
                      }  
                  } catch (IOException e) {  
                      try {  
                          this.session.close();  
                      } catch (IOException e1) {}  
                  }  
              }  
                
              /**  
               * 心跳任務。發送隨機數。  
               */  
              TimerTask task = new TimerTask() {  
                  public void run() {     
                      long param = random.nextInt(100);  
                      sendLong(param);  
                  }     
              };  
          }

          Web.xml代碼

          <?xml version="1.0" encoding="UTF-8"?>  
          <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">  
            <display-name>websocket</display-name>  
            <welcome-file-list>  
              <welcome-file>index.html</welcome-file>  
            </welcome-file-list>  
              
            <filter>  
                  <filter-name>Set Character Encoding</filter-name>  
                  <filter-class>org.apache.catalina.filters.SetCharacterEncodingFilter</filter-class>  
                  <init-param>  
                      <param-name>encoding</param-name>  
                      <param-value>UTF-8</param-value>  
                  </init-param>  
                  <init-param>  
                      <param-name>ignore</param-name>  
                      <param-value>true</param-value>  
                  </init-param>  
              </filter>  
                
              <filter-mapping>  
                  <filter-name>Set Character Encoding</filter-name>  
                  <url-pattern>/*</url-pattern>  
              </filter-mapping>  
          </web-app>

          將以上程序部署到Tomcat8下,啟動服務。 

          完結~~~~~~~~~~

           



          站長推薦

          1.阿里云: 本站目前使用的是阿里云主機,安全/可靠/穩定。點擊領取2000元代金券、了解最新阿里云產品的各種優惠活動點擊進入

          2.騰訊云: 提供云服務器、云數據庫、云存儲、視頻與CDN、域名等服務。騰訊云各類產品的最新活動,優惠券領取點擊進入

          3.廣告聯盟: 整理了目前主流的廣告聯盟平臺,如果你有流量,可以作為參考選擇適合你的平臺點擊進入

          鏈接: http://www.modern-decoration.com.cn/article/detial/64

          javascript中什么是句柄?

          一個句柄是指使用的一個唯一的整數值,即一個4字節(64位程序中為8字節)長的數值,來標識應用程序中的不同對象和同類中的不同的實例。

          javascript不可變性是什么?

          不可變性即某個變量在進行了某個操作之后,其本身沒有發生變化,比如對于字符串而言,對字符串的任何操作都會改變字符串本身的值,而是在字符串的基礎上復制出來一個然后再改變,這樣我們就說是不可變的

          為什么javascript不起作用?

          JavaScript是一種屬于網絡的腳本語言,已經被廣泛用于Web應用開發,常用來為網頁添加各式各樣的動態功能,為用戶提供更流暢美觀的瀏覽效果。通常JavaScript腳本是通過嵌入在HTML中來實現自身的功能的。

          javascript怎么判斷按鈕被點擊?

          JavaScript可以通過Event對象的target事件或srcElement(IE瀏覽器支持)來判斷按鈕是否被點擊。Event對象代表事件的狀態,比如事件在其中發生的元素、鍵盤按鍵的狀態、鼠標的位置、鼠標按鈕的狀態。

          javascript由幾部分組成?

          JavaScript有三部分組成。分別為核心(ECMAScript) 、文檔對象模型(DOM)、瀏覽器對象模型(BOM)。這三部分分別描述了該語言的語法和基本對象、處理網頁內容的方法和接口、與瀏覽器進行交互的方法和接口。

          Js輸出方式有哪些?

          在編寫JavaScript代碼的時候, 一定要記住每一句代碼后面都需要添加一個分號, 并且這個分號必須是英文的分號,我們會發現有時候不寫分號程序也能夠運行, 這里并不是因為不需要分號, 而是瀏覽器自動幫助我們添加了分號

          7個常見的 JavaScript 測驗及解答

          我相信學習新事物并評估我們所知的東西對自己的進步非常有用,可以避免了我們覺得自己的知識過時的情況。在本文中,我將介紹一些常見的 JavaScript 知識。請享用!

          JavaScript中“javascript:void(0) ”是什么意思

          expression 是一個要計算的 Javascript 標準的表達式。表達式外側的圓括號是可選的,鑒于規范化,以及養成好習慣,建議寫上去。當我們使用 void 操作符指定超級鏈接時,表達式會被計算但是不會在當前文檔處裝入任何內容。

          Js中constructor指向問題

          首先用一個例子指出來constructor存在形式。由上面的代碼我們總結出結論1:上面的代碼在控制臺可以看出constructor是指向構造器Fruit的引用。這個地方就有點奇怪了。這個constructor到底指向的是那個實例的構造器?

          javascript難點是什么?

          javascript難點是什么?下面本篇文章就來給大家介紹一下10個JavaScript難點,感興趣的小伙伴們可以參考一下,希望對大家有所幫助。立即執行函數,即Immediately Invoked Function Expression (IIFE),正如它的名字

          內容以共享、參考、研究為目的,不存在任何商業目的。其版權屬原作者所有,如有侵權或違規,請與小編聯系!情況屬實本人將予以刪除!

          文章投稿關于web前端網站點搜索站長推薦網站地圖站長QQ:522607023

          小程序專欄: 土味情話心理測試腦筋急轉彎幽默笑話段子句子語錄成語大全運營推廣

          国产精品高清视频免费 - 视频 - 在线观看 - 影视资讯 - 唯爱网