<span id="mktg5"></span>

<i id="mktg5"><meter id="mktg5"></meter></i>

        <label id="mktg5"><meter id="mktg5"></meter></label>
        最新文章專題視頻專題問答1問答10問答100問答1000問答2000關鍵字專題1關鍵字專題50關鍵字專題500關鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關鍵字專題關鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
        問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
        當前位置: 首頁 - 科技 - 知識百科 - 正文

        WebSocket的簡單介紹及應用

        來源:懂視網 責編:小采 時間:2020-11-27 21:56:18
        文檔

        WebSocket的簡單介紹及應用

        WebSocket的簡單介紹及應用:定時刷新的不足與改進 web開發中可能遇到這樣的場景:網頁里的某一塊區域里寫了一些內容,但這些內容不是固定的,即使看網頁的人沒有做任何操作,它們也會隨時間不斷變化。股票行情、活動或游戲的榜單都是比較常見的例子。 對此,一般的做法是用setTime
        推薦度:
        導讀WebSocket的簡單介紹及應用:定時刷新的不足與改進 web開發中可能遇到這樣的場景:網頁里的某一塊區域里寫了一些內容,但這些內容不是固定的,即使看網頁的人沒有做任何操作,它們也會隨時間不斷變化。股票行情、活動或游戲的榜單都是比較常見的例子。 對此,一般的做法是用setTime

        定時刷新的不足與改進

        web開發中可能遇到這樣的場景:網頁里的某一塊區域里寫了一些內容,但這些內容不是固定的,即使看網頁的人沒有做任何操作,它們也會隨時間不斷變化。股票行情、活動或游戲的榜單都是比較常見的例子。

        對此,一般的做法是用setTimeout()或setInverval()定時執行任務,任務內容是Ajax訪問一次服務器,并在成功拿到返回數據后去更新頁面。

        這種定時刷新的做法會有這樣一些感覺不足的地方:

      1. 頻繁的定時網絡請求對瀏覽器(客戶端)和服務器來說都是一種負擔,尤其是當網頁里有多個定時刷新區域的時候。
      2. 某幾次的定時任務可能是不必要的,因為服務器可能并沒有新數據,還是返回了和上一次一樣的內容。
      3. 頁面內容可能不夠新,因為服務器可能剛更新了數據,但下一輪定時任務還沒有開始。
      4. 造成這些不足的原因歸結起來,主要還是由于服務器的響應總是被動的。HTTP協議限制了一次通信總是由客戶端發起請求,再由服務器端來返回響應。

        因此,如果讓服務器端也可以主動發送信息到客戶端,就可以很大程度改進這些不足。WebSocket就是一個實現這種雙向通信的新協議。

        WebSocket是基于HTTP的功能追加協議

        WebSocket最初由html5提出,但現在已經發展為一個獨立的協議標準。WebSocket可以分為協議(Protocol)和API兩部分,分別由IETF和W3C制定了標準。

        先來看看WebSocket協議的建立過程。

        為了實現WebSocket通信,首先需要客戶端發起一次普通HTTP請求(也就是說,WebSocket的建立是依賴HTTP的)。請求報文可能像這樣:

        GET ws://websocket.example.com/ HTTP/1.1
        Host: websocket.example.com
        Upgrade: websocket
        Connection: Upgrade
        Origin: http://example.com
        Sec-WebSocket-Key:pAloKxsGSHtpIHrJdWLvzQ==
        Sec-WebSocket-Version:13

        其中HTTP頭部字段Upgrade: websocket和Connection: Upgrade很重要,告訴服務器通信協議將發生改變,轉為WebSocket協議。支持WebSocket的服務器端在確認以上請求后,應返回狀態碼為101 Switching Protocols的響應:

        HTTP/1.1 101 Switching Protocols
        Upgrade: websocket
        Connection: Upgrade
        Sec-WebSocket-Accept: nRu4KAPUPjjWYrnzxDVeqOxCvlM=

        其中字段Sec-WebSocket-Accept是由服務器對前面客戶端發送的Sec-WebSocket-Key進行確認和加密后的結果,相當于一次驗證,以幫助客戶端確信對方是真實可用的WebSocket服務器。

        驗證通過后,這個握手響應就確立了WebSocket連接,此后,服務器端就可以主動發信息給客戶端了。此時的狀態比較像服務器端和客戶端接通了電話,無論是誰有什么信息想告訴對方,開口就好了。

        一旦建立了WebSocket連接,此后的通信就不再使用HTTP了,改為使用WebSocket獨立的數據幀(這個幀有辦法看到,見后文)。

        整個過程像這樣:

        簡單的應用示例

        應用WebSocket有這樣幾件事要做:

      5. 選用支持WebSocket的瀏覽器。
      6. 網頁內添加創建WebSocket的代碼。
      7. 服務器端添加使用WebSocket通信的代碼。
      8. 服務器端

        以Node的服務器為例,我們使用ws這個組件,這樣搭建一個支持WebSocket的服務器端:

        var request = require("request");
        var dateFormat = require("dateformat");
        var WebSocket = require("ws"),
         WebSocketServer = WebSocket.Server,
         wss = new WebSocketServer({
         port: 8080,
         path: "/guest"
         });
        
        // 收到來自客戶端的連接請求后,開始給客戶端推消息
        wss.on("connection", function(ws) {
         ws.on("message", function(message) {
         console.log("received: %s", message);
         });
         sendGuestInfo(ws);
        });
        
        function sendGuestInfo(ws) {
         request("http://uinames.com/api?region=china",
         function(error, response, body) {
         if (!error && response.statusCode === 200) {
         var jsonObject = JSON.parse(body),
         guest = jsonObject.name + jsonObject.surname,
         guestInfo = {
         guest: guest,
         time: dateFormat(new Date(), "HH:MM:ss")
         };
        
         if (ws.readyState === WebSocket.OPEN) {
        
         // 發,送
         ws.send(JSON.stringify(guestInfo));
        
         // 用隨機來“裝”得更像不定時推送一些
         setTimeout(function() {
         sendGuestInfo(ws);
         }, (Math.random() * 5 + 3) * 1000);
         }
         }
         });
        }
        

        這個例子使用了姓名生成站點uinames的API服務,來生成{guest: "人名", time: "15:26:01"}這樣的數據。函數sendGuestInfo()會不定時執行,并把包含姓名和時間的信息通過send()方法發送給客戶端。另外,注意send()方法需要以字符串形式來發送json數據。

        這就像是服務器自己在做一些事,然后在需要的時候會通知客戶端一些信息。

        客戶端

        客戶端我們使用原生javascript來完成(僅支持WebSocket的瀏覽器):

        var socket = new WebSocket("ws://localhost:8080/guest");
        
        socket.onopen = function(openEvent) {
         console.log("WebSocket conntected.");
        };
        
        socket.onmessage = function(messageEvent) {
         var data = messageEvent.data,
         dataObject = JSON.parse(data);
         console.log("Guest at " + dataObject.time + ": " + dataObject.guest);
        };
        
        socket.onerror = function(errorEvent) {
         console.log("WebSocket error: ", errorEvent);
        };
        
        socket.onclose = function(closeEvent) {
         console.log("WebSocket closed.");
        };

        WebSocket的URL格式是ws://與wss://。因此,需要注意下URL地址的寫法,這也包括注意WebSocket服務器端的路徑(如這里的/guest)等信息。因為是本地的示例所以這里是localhost。

        客戶端代碼的流程很簡單:創建WebSocket對象,然后指定onopen、onmessage等事件的回調即可。其中onmessage是客戶端與服務器端通過WebSocket通信的關鍵事件,想要在收到服務器通知后做點什么,寫在onmessage事件的回調函數里就好了。

        效果及分析

        通過node server(假定服務器端的文件名為server.js)啟動WebSocket服務器后,用瀏覽器打開一個引入了前面客戶端代碼的html(直接文件路徑file:///就可以),就可以得到像這樣的結果:

        聯系前面客戶端的代碼可以想到,實際從創建WebSocket對象的語句開始,連接請求就會發送,并很快建立起WebSocket連接(不出錯誤的話),此后就可以收到來自服務器端的通知。如果此時客戶端還想再告訴服務器點什么,這樣做:

        socket.send("Hello, server!");

        服務器就可以收到:

        當然,這也是因為前面服務器端的代碼內同樣設置了message事件的回調。在這個客戶端和服務器都是javascript的例子中,無論是服務器端還是客戶端,都用send()發送信息,都通過message事件設置回調,形式上可以說非常一致。

        其他可用的數據類型

        WebSocket的send()可以發送的消息,除了前面用的字符串類型之外,還有兩種可用,它們是Blob和ArrayBuffer。

        它們都代表二進制數據,可用于原始文件數據的發送。比如,這是一個發送Blob類型數據以完成向服務器上傳圖片的例子:

        var fileEl = document.getElementById("image_upload");
        var file = fileEl.files[0];
        socket.send(file);

        然后服務器端可以這樣把文件保存下來:

        var fs = require("fs");
        
        wss.on("connection", function(ws) {
         ws.on("message", function(message) {
         fs.writeFile("upload.png", message, "binary", function(error) {
         if (!error) {
         console.log("File saved.");
         }
         });
         });
        });
        

        在客戶端接收二進制數據時,需注意WebSocket對象有一個屬性binaryType,初始值為"blob"。因此,如果接收的二進制數據是ArrayBuffer,應在接收之前這樣做:

        socket.binaryType = "arraybuffer";

        其他WebSocket服務器端

        其他語言來做WebSocket服務器是怎樣的呢?下面是一個php的WebSocket服務器的例子(使用Ratchet):

        <?php
        use Ratchet\ConnectionInterface;
        use Ratchet\MessageComponentInterface;
        
        require __DIR__ . '/vendor/autoload.php';
        
        class GuestServer implements MessageComponentInterface {
        
         public function onOpen(ConnectionInterface $conn) {
         $conn->send('The server is listening to you now.');
         }
        
         public function onMessage(ConnectionInterface $conn, $msg) {
         $conn->send($this->generateGuestInfo());
         }
        
         public function onClose(ConnectionInterface $conn) {
         }
        
         public function onError(ConnectionInterface $conn, \Exception $e) {
         $conn->close();
         }
        
         private function generateGuestInfo() {
         $jsonString = file_get_contents('http://uinames.com/api?region=china');
         $jsonObject = json_decode($jsonString, true);
         $guest = $jsonObject['name'] . $jsonObject['surname'];
         $guestInfo = array(
         'guest' => $guest,
         'time' => date('H:i:s', time()),
         );
        
         return json_encode($guestInfo);
         }
        }
        
        $app = new Ratchet\App('localhost', 8080);
        $app->route('/guest', new GuestServer(), array('*'));
        $app->run();
        ?>

        這個例子也同樣是由服務器返回{guest: "人名", time: "15:26:01"}的json數據,不過由于php不像Node那樣可以用setTimeout()很容易地實現異步定時任務,這里改為在客戶端發送一次任意信息后,再去uinames取得信息并返回。

        也可以看到,php搭建的WebSocket服務器仍然是近似的,主要通過WebSocket的open、message等事件來實現功能。

        在Chrome開發工具中查看WebSocket數據幀

        Chrome開發工具中選擇Network,然后找到WebSocket的那個請求,里面可以選擇Frames。在Frames里看到的,就是WebSocket的數據幀了:

        可以看到很像聊天記錄,其中用淺綠色標注的是由客戶端發送給服務器的部分。

        結語

        總的來說,把服務器和客戶端拉到了一個聊天窗口來辦事,這確實是很棒的想法。

        即使只從形式上說,WebSocket的事件回調感覺也比定時任務用起來要更親切一些。

        聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

        文檔

        WebSocket的簡單介紹及應用

        WebSocket的簡單介紹及應用:定時刷新的不足與改進 web開發中可能遇到這樣的場景:網頁里的某一塊區域里寫了一些內容,但這些內容不是固定的,即使看網頁的人沒有做任何操作,它們也會隨時間不斷變化。股票行情、活動或游戲的榜單都是比較常見的例子。 對此,一般的做法是用setTime
        推薦度:
        標簽: 應用 簡單 簡介
        • 熱門焦點

        最新推薦

        猜你喜歡

        熱門推薦

        專題
        Top
        主站蜘蛛池模板: 永久免费AV无码网站在线观看| 无码区日韩特区永久免费系列 | 亚洲色精品三区二区一区| 午夜不卡久久精品无码免费| 久久久影院亚洲精品| 亚洲免费人成在线视频观看| 亚洲国产精品一区二区成人片国内| 国产一级一毛免费黄片| 亚洲中文字幕无码一区| 三上悠亚电影全集免费 | 理论秋霞在线看免费| 可以免费观看的一级毛片| 成人久久久观看免费毛片| 久久久亚洲精品蜜桃臀| 你是我的城池营垒免费看| 亚洲天天做日日做天天欢毛片| 1000部免费啪啪十八未年禁止观看| 亚洲综合综合在线| AV免费网址在线观看| 妇女自拍偷自拍亚洲精品| 国产精品亚洲不卡一区二区三区| 中国一级全黄的免费观看| 午夜亚洲www湿好大| 999久久久免费精品国产| 亚洲AV成人无码网站| 国产亚洲精久久久久久无码AV| 久久免费美女视频| 亚洲制服丝袜第一页| 免费一级毛片在级播放| 国产麻豆一精品一AV一免费| 亚洲成人免费在线观看| 日本高清免费网站| 成全视成人免费观看在线看| 亚洲欧洲高清有无| 九月婷婷亚洲综合在线| 无码一区二区三区免费| 亚洲精品无码久久久久秋霞| 亚洲日韩精品一区二区三区| 中文字幕影片免费在线观看| 国产va免费精品| 国产精品高清视亚洲一区二区 |