在工作中我們開發接觸最多的協議莫過於HTTP協議了,近些年H5的很多API和技術已經如雨後春筍般開始漸漸發揚光大了,今天我們就來一起討論下其中的一個比較有意思的API,WebSocket
首先,在介紹主角之前,總要有一個鋪墊,那麼我就來三言兩語先說一下最常見的HTTP協議吧,以示區分
三言兩語說說HTTP
HTTP是客戶端/伺服器模式中請求-響應所用的協議,在這種模式中,瀏覽器向伺服器提交HTTP請求,伺服器響應請求的資源
言下之意就是你可以把這種模式,想象成對講機,一個人說,另一個人聽
HTTP是半雙工通訊
這種半雙工通訊的特點就是:
- 同一時刻資料是單向流動的,客戶端向服務端請求資料->
單向,服務端向客戶端返回資料->
單向 - 伺服器不能主動的推送資料給客戶端
以上就是對HTTP協議的簡單概括,那麼下面直接開始進入今天的主題
雙工通訊
在H5的websocket出現之前,為了實現這種推送技術,大家最常用的實現方式有這三種:輪詢、長輪詢和iframe流,但是他們三兄弟或多或少都有些美中不足
於是乎,在大神們的不斷努力下,定義了websocket這個好用的API,來完善了雙工通訊的更好實現方式
WebSocket時代已來,不要錯過!!!
WebSocket
WebSocket實現了,在客戶端和服務端上建立了一個長久的連線,兩邊可以任意發資料嗨皮
當然如果知道的更深一層的話,要知道它屬於應用層的協議,它基於TCP傳輸協議,並複用HTTP的握手通道
說的再多,不如懂它,下面來看看websocket的優勢何在
WebSocket的優勢
- 支援雙向通訊,實時性更強(你可以來做個QQ,微信了,老鐵)
- 更好的二進位制支援
- 較少的控制開銷(連線建立後,ws客戶端、服務端進行資料交換時,協議控制的資料包頭部較少)
那麼廢話說到這裡了,接下來開始實戰,直接檢驗一下成果
一起敲敲WebSocket
我們先來寫下前端頁面的WebSocket,看看基本用法,上程式碼,別猶豫
// 建立一個index.html檔案// 下面直接寫WebSocket// 只需要new一下就可以建立一個websocket的例項// 我們要去連線ws協議// 這裡對應的埠就是服務端設定的埠號9999let ws = new WebSocket('ws://localhost:9999');
// onopen是客戶端與服務端建立連線後觸發ws.onopen = function() {
ws.send('哎呦,不錯哦');
};
// onmessage是當服務端給客戶端發來訊息的時候觸發ws.onmessage = function(res) {
console.log(res);
// 列印的是MessageEvent物件 // 真正的訊息資料是 res.data console.log(res.data);
};
複製程式碼
以上程式碼,除去註釋的話,也就不到10行程式碼,就把websocket的用法寫完了,so easy,使用起來很簡單啊,有木有
那麼做事要做全,我們再寫一下後臺那邊的websocket接收和傳送訊息部分吧,繼續擼
等等,在擼之前,先要安裝一下
// 後臺需要安裝ws包npm i ws -S複製程式碼
這裡我們用node的express來簡單搭個後臺服務,目錄結構也很簡單,如下圖
下面開始擼這個server.js檔案吧
const express = require('express');
const app = express();
// 設定靜態資料夾app.use(express.static(__dirname));
// 監聽3000埠app.listen(3000);
// =============================================// 開始建立一個websocket服務const Server = require('ws').Server;
// 這裡是設定伺服器的埠號,和上面的3000埠不用一致const ws = new Server({
port: 9999
});
// 監聽服務端和客戶端的連線情況ws.on('connection', function(socket) {
// 監聽客戶端發來的訊息 socket.on('message', function(msg) {
console.log(msg);
// 這個就是客戶端發來的訊息 // 來而不往非禮也,服務端也可以發訊息給客戶端 socket.send(`這裡是服務端對你說的話: ${msg
}`);
});
});
複製程式碼
這樣就搭了一個後臺服務了,訪問localhost:3000後,在控制檯就可以看到訊息了
看到這裡,我們會由衷的發現,無論是前端來寫還是後臺來寫,發現其實都很類似,所以用起來比較流暢,多敲幾遍就好了,熟能生巧嘛,哈哈
接下來還沒完,由於websocket是H5標準出的東西,老版本的瀏覽器當然就不能很好的支援了,這時前端就要處理該死的相容問題了
正因如此,世上才會有了另外一個更好用的庫出現,這就是大名鼎鼎的 socket.io
下面趁此雅興,不要停,繼續來學習一下這個全雙工通訊中的王者吧
socket.io
先來看下socket.io的特別有哪些
socket.io的特點
- 易用性:封裝了服務端和客戶端,使用簡單方便
- 跨平臺:支援跨平臺,可以選擇在服務端或是客戶端開發實時應用
- 自適應:會根據瀏覽器來自己決定是使用WebSocket、Ajax長輪詢還是Iframe流等方式去選擇最優方式,甚至支援IE5.5
好了,看完了特點,那就……
少點套路,多點真誠,廢話不說了,直接上手從頭擼一遍吧
socket.io安裝
// 安裝在本地專案npm i socket.io -S複製程式碼
啟動服務,手寫服務端
還是用node中的express框架來搭個服務,程式碼如下
// server.js檔案const express = require('express');
const app = express();
// 設定靜態資料夾app.use(express.static(__dirname));
// 通過node的http模組來建立一個server服務const server = require('http').createServer(app);
// WebSocket是依賴HTTP協議進行握手的const io = require('socket.io')(server);
// 監聽客戶端與服務端的連線io.on('connection', function(socket) {
// send方法來給客戶端發訊息 socket.send('青花瓷');
// 監聽客戶端的訊息是否接收成功 socket.on('message', function(msg) {
console.log(msg);
// 客戶端發來的訊息 socket.send('天青色等煙雨,而我在等你' );
});
});
// 監聽3000埠server.listen(3000);
複製程式碼
辣麼,服務端的程式碼已經寫完了,接下來開始寫前端的部分,擼起袖子加油幹啊!!!
在服務端執行後,客戶端就需要引用一個動態生成的檔案路徑,路徑是固定的直接引用即可(/socket.io/socket.io.js)
// index.html檔案...省略// 引用socket.io的js檔案<
script src="/socket.io/socket.io.js">
<
/script>
<
script>
const socket = io('/');
// 監聽與伺服器連線成功的事件 socket.on('connect', () =>
{
console.log('連線成功');
socket.send('周杰倫');
});
// 監聽服務端發來的訊息 socket.on('message', msg =>
{
// 這個msg就是傳過來的真訊息了,不用再msg.data取值了 console.log(`客戶端接收到的訊息: ${msg
}`);
});
// 監聽與伺服器連線斷開事件 socket.on('disconnect', () =>
{
console.log('連線斷開成功');
});
<
/script>
複製程式碼
☆ 這裡要有個小提示: io建立socket的時候可以接收一個url引數
- url可以是socket服務完整的http地址,如:io(‘http://localhost:3000‘)
- 也可以是相對路徑,如:io(‘/’)
- 不填的話就表示預設連線當前路徑,如:io()
基本用法就是這些了,還有其他的劃分名稱空間、加入房間和廣播等方法沒有講到,本想繼續往下寫的
But接下來要講的,用socket.io做一個聊天室這種大招太耗費內力了,觀眾看到現在也有點疲憊了
所以識時務者為俊傑的時候到了,放在下期來放送給大家吧,辛苦各位的觀看了,886