亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > JavaScript > 正文

WebSocket的簡單介紹及應用

2019-11-19 11:29:13
字體:
來源:轉載
供稿:網友

定時刷新的不足與改進

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

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

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

  • 頻繁的定時網絡請求對瀏覽器(客戶端)和服務器來說都是一種負擔,尤其是當網頁里有多個定時刷新區域的時候。
  • 某幾次的定時任務可能是不必要的,因為服務器可能并沒有新數據,還是返回了和上一次一樣的內容。
  • 頁面內容可能不夠新,因為服務器可能剛更新了數據,但下一輪定時任務還沒有開始。

造成這些不足的原因歸結起來,主要還是由于服務器的響應總是被動的。HTTP協議限制了一次通信總是由客戶端發起請求,再由服務器端來返回響應。

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

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

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

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

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

GET ws://websocket.example.com/ HTTP/1.1Host: websocket.example.comUpgrade: websocketConnection: UpgradeOrigin: http://example.comSec-WebSocket-Key:pAloKxsGSHtpIHrJdWLvzQ==Sec-WebSocket-Version:13

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

HTTP/1.1 101 Switching ProtocolsUpgrade: websocketConnection: UpgradeSec-WebSocket-Accept: nRu4KAPUPjjWYrnzxDVeqOxCvlM=

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

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

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

整個過程像這樣:

簡單的應用示例

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

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

服務器端

以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()可以發送的消息,除了前面用的字符串類型之外,還有兩種可用,它們是BlobArrayBuffer。

它們都代表二進制數據,可用于原始文件數據的發送。比如,這是一個發送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):

<?phpuse 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的事件回調感覺也比定時任務用起來要更親切一些。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
日韩在线精品视频| 久久久最新网址| 国产丝袜一区二区| 欧美精品第一页在线播放| 欧美丰满少妇xxxxx| 日韩av电影在线网| 成人女保姆的销魂服务| 日韩精品极品在线观看播放免费视频| 日韩欧美中文字幕在线播放| 亚洲欧美中文字幕| 欧美日韩亚洲成人| 在线视频欧美性高潮| 91免费看片网站| 欧美激情乱人伦一区| 亚洲国产精品久久91精品| 亚洲精品电影网站| 国产亚洲精品日韩| 91嫩草在线视频| 国产一区二区三区欧美| 亚洲系列中文字幕| 亚洲综合中文字幕68页| 日韩欧美第一页| 欧美成人激情图片网| 欧美精品videosex牲欧美| 2018中文字幕一区二区三区| 欧美大片在线影院| 欧美午夜精品久久久久久人妖| 久久久久久久一区二区三区| 亚洲美腿欧美激情另类| 欧美高清视频在线播放| 大胆人体色综合| 深夜福利日韩在线看| 欧美放荡办公室videos4k| 亚洲综合日韩在线| 色吧影院999| 日韩电影中文字幕| 欧美日韩免费区域视频在线观看| 国产精品日韩欧美大师| 亚洲视频在线观看网站| 91久久久久久久久久| 国产精品一区=区| 欧美精品日韩三级| 欧美午夜片欧美片在线观看| 亚洲第一区第二区| 日韩极品精品视频免费观看| 庆余年2免费日韩剧观看大牛| 亚洲日本欧美日韩高观看| 日韩国产精品一区| 欧美成人午夜激情视频| 精品久久久国产精品999| 亚洲人成亚洲人成在线观看| 精品香蕉在线观看视频一| 欧美激情欧美狂野欧美精品| 日韩中文av在线| 久久躁日日躁aaaaxxxx| 最近2019年中文视频免费在线观看| 九色精品免费永久在线| 欧美刺激性大交免费视频| 亚洲欧美日韩图片| 国产精品一区二区3区| 欧美床上激情在线观看| 欧美午夜无遮挡| 久久九九国产精品怡红院| 在线视频国产日韩| 搡老女人一区二区三区视频tv| 国产性猛交xxxx免费看久久| 亚洲精品国产电影| 亚洲国产古装精品网站| 国产精品久久久久久久久久久久久| 国产成人avxxxxx在线看| 亚洲欧美一区二区三区在线| 国内精品400部情侣激情| 午夜精品久久久久久久99热浪潮| 亚洲热线99精品视频| 国产一区二区三区在线播放免费观看| 日韩小视频网址| 午夜精品久久久99热福利| 欧美日韩国产精品一区二区三区四区| 久久精品电影网站| 色噜噜久久综合伊人一本| 成人免费直播live| 韩国精品久久久999| 日韩中文字幕精品| 国产精品va在线| 亚洲精品美女在线| 狠狠色香婷婷久久亚洲精品| 日本国产精品视频| 日韩极品精品视频免费观看| 久久久噜噜噜久久| 亚洲欧美精品一区二区| 日韩精品久久久久| 亚洲自拍偷拍视频| 欧美日韩免费观看中文| 国产精品视频公开费视频| 久久久影视精品| 午夜精品久久久久久久99热浪潮| 精品无人区太爽高潮在线播放| 国产精品爽黄69天堂a| 97在线免费观看视频| 久久久久亚洲精品成人网小说| 亚洲免费福利视频| 欧美激情视频给我| 92看片淫黄大片欧美看国产片| 亚洲精品wwww| 色婷婷av一区二区三区久久| 亚洲视频在线观看免费| 另类视频在线观看| 欧美激情精品久久久久| 亚洲欧美中文另类| 国产成人涩涩涩视频在线观看| 国产视频精品xxxx| 亚洲色图18p| 日韩欧美在线一区| 欧美电影免费观看高清| 黑人巨大精品欧美一区二区| 51久久精品夜色国产麻豆| 午夜精品一区二区三区在线| 一区国产精品视频| 欧美性猛交99久久久久99按摩| 久久久久久久久久婷婷| 日韩av在线精品| 欧洲精品毛片网站| 在线电影中文日韩| 久久视频在线播放| 欧美激情国内偷拍| 国产精品入口夜色视频大尺度| 精品国产一区久久久| 色av中文字幕一区| 欧美日本啪啪无遮挡网站| 97视频免费看| 亚洲跨种族黑人xxx| 久久久人成影片一区二区三区观看| 国产精品国产福利国产秒拍| 91在线视频成人| 亚洲美女激情视频| 精品香蕉在线观看视频一| 在线免费观看羞羞视频一区二区| 久久亚洲精品中文字幕冲田杏梨| 亚洲欧美日韩一区二区三区在线| 中文精品99久久国产香蕉| 45www国产精品网站| 国产精品丝袜一区二区三区| 亚洲国产成人在线播放| 中文字幕一区二区三区电影| 国产亚洲精品久久久久久牛牛| 全亚洲最色的网站在线观看| 日韩精品在线观看一区| 国产精品一二三在线| 国产日韩在线精品av| 国内精品久久久久久久久| 欧美精品18videos性欧美| 亚洲性猛交xxxxwww| 亚洲精品美女久久久| 久久精品免费播放| 欧美日韩亚洲一区二| 在线观看中文字幕亚洲| 亚洲理论片在线观看| 亚洲成成品网站| 欧美日韩中文在线观看| 亚洲电影免费在线观看| 日韩一区二区三区国产| 欧美在线视频一区二区| 欧美黄色片视频| 精品国产91久久久|