WebSocket

WebSocket API是下一代客戶端-服務(wù)器的異步通信方法。該通信取代了單個的TCP套接字,使用ws或wss協(xié)議,可用于任意的客戶端和服務(wù)器程序。WebSocket目前由W3C進(jìn)行標(biāo)準(zhǔn)化。WebSocket已經(jīng)受到Firefox 4、Chrome 4、Opera 10.70以及Safari 5等瀏覽器的支持。

WebSocket API最偉大之處在于服務(wù)器和客戶端可以在給定的時間范圍內(nèi)的任意時刻,相互推送信息。WebSocket并不限于以Ajax(或XHR)方式通信,因為Ajax技術(shù)需要客戶端發(fā)起請求,而WebSocket服務(wù)器和客戶端可以彼此相互推送信息;XHR受到域的限制,而WebSocket允許跨域通信。

Ajax技術(shù)很聰明的一點是沒有設(shè)計要使用的方式。WebSocket為指定目標(biāo)創(chuàng)建,用于雙向推送消息。

ajax輪詢

客戶端:啦啦啦,有沒有新信息(Request)
服務(wù)端:沒有(Response)
客戶端:啦啦啦,有沒有新信息(Request)
服務(wù)端:沒有。。(Response)
客戶端:啦啦啦,有沒有新信息(Request)
服務(wù)端:你好煩啊,沒有啊。。(Response)
客戶端:啦啦啦,有沒有新消息(Request)
服務(wù)端:好啦好啦,有啦給你。(Response)
客戶端:啦啦啦,有沒有新消息(Request)
服務(wù)端:。。。。。沒。。。。沒。。。沒有(Response) —- loop

WebSocket

客戶端:啦啦啦,我要建立Websocket協(xié)議,需要的服務(wù):chat,Websocket協(xié)議版本:17(HTTP Request)
服務(wù)端:ok,確認(rèn),已升級為Websocket協(xié)議(HTTP Protocols Switched)
客戶端:麻煩你有信息的時候推送給我噢。。
服務(wù)端:ok,有的時候會告訴你的。
服務(wù)端:balabalabalabala
服務(wù)端:balabalabalabala
服務(wù)端:哈哈哈哈哈啊哈哈哈哈
服務(wù)端:笑死我了哈哈哈哈哈哈哈

socket.io

node.js提供了高效的服務(wù)端運(yùn)行環(huán)境,但是由于瀏覽器端對HTML5的支持不一,為了兼容所有瀏覽器,提供卓越的實時的用戶體驗,并且為程序員提供客戶端與服務(wù)端一致的編程體驗,于是socket.io誕生。Socket.io將Websocket和輪詢 (Polling)機(jī)制以及其它的實時通信方式封裝成了通用的接口,并且在服務(wù)端實現(xiàn)了這些實時機(jī)制的相應(yīng)代碼。也就是說,Websocket僅僅是 Socket.io實現(xiàn)實時通信的一個子集。那么,Socket.io都實現(xiàn)了Polling中的那些通信機(jī)制呢?

  • Adobe? Flash? Socket
  • AJAX long polling
  • AJAX multipart streaming
  • Forever Iframe
  • JSONP Polling

使用socket.io制作聊天室

  1. 初始化package.json文件
    在項目文件夾主目錄下執(zhí)行以下命令

    $ cnpm init -y
    
  2. 安裝對應(yīng)的包

    • express 服務(wù)器端路由的制作

      $ cnpm install --save express
      

      ?

    • socket.io WebScoket的封裝庫

      $ cnpm install --save socket.io
      
  3. 編寫server.js服務(wù)器文件
    創(chuàng)建server.js文件,作為服務(wù)器,使用express模塊進(jìn)行路由的編寫

    // 引入對應(yīng)的模塊
    var app = require('express')();
    var http = require('http').Server(app);
    
    // 訪問首頁即訪問index.html文件
    app.get('/', function(req, res) {
        res.sendfile(__dirname + '/index.html');
    });
    
    // 設(shè)置端口以及回調(diào)
    http.listen(8888, function() {
        console.log('listening on *:3000');
    });
    
  4. 編寫index.html文件

    <!DOCTYPE html>
    <html>
        <head>
            <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
            <meta charset="utf-8">
            <title></title>
            <style media="screen">
                * { margin: 0; padding: 0; }
                html, body { width: 100%; height: 100%; }
                #messages { list-style-type: none; }
                #messages li { padding: 5px 10px; }
                #messages li:nth-child(odd) { background: #eee; }
                form { position: fixed; left: 0; right: 0; bottom: 0; height: 50px; background-color: #333; }
                form input { width: 80%; height: 40px; margin-top: 5px; border: none; }
                form button { width: 18%; height: 100%; background-color: cyan; border: none; }
            </style>
        </head>
        <body>
    
            <div class="container">
                <ul id="messages"></ul>
                <form action="">
                    <input id="m" type="text" name="" value="">
                    <button type="submit">Send</button>
                </form>
            </div>
    
        </body>
    </html>
    
  5. 在終端執(zhí)行node server.js命令,即可運(yùn)行服務(wù)器,打開瀏覽器輸入http://localhost:8888,即可看到效果

  6. server.js中添加代碼,進(jìn)行socket.io的數(shù)據(jù)傳輸事件的注冊,并重啟服務(wù)

    // 引入對應(yīng)的模塊
    var app = require('express')();
    var http = require('http').Server(app);
    
    // 新增代碼++++++++++++++++++++++++++
    // 引入socket.io模塊
    var io = require('socket.io')(http);
    
    // 訪問首頁即訪問index.html文件
    app.get('/', function(req, res) {
        res.sendFile(__dirname + '/index.html');
    });
    
    // 新增代碼++++++++++++++++++++++++++
    // 注冊事件,連接成功即可執(zhí)行
    io.on('connection', function (socket) {
        console.log('鏈接已成功');
    
        // 注冊事件,連接斷開即可執(zhí)行
        io.on('disconnection', function (socket) {
            console.log('鏈接已斷開');
        });
    });
    
    // 設(shè)置端口以及回調(diào)
    http.listen(8888, function() {
        console.log('listening on *:3000');
    });
    
  7. index.html中添加代碼,創(chuàng)建一個socket對象,即可觸發(fā)server.js中注冊的事件

    <script src="/socket.io/socket.io.js"></script>
    <script type="text/javascript">
        var socket = io();
    </script>
    

    刷新網(wǎng)頁的時候,即可看到如下的輸出結(jié)果:

    lidaze-MBP-2:chat-room lidaze$ node server.js
    listening on *:3000
    鏈接已成功
    鏈接已斷開
    鏈接已成功
    鏈接已斷開
    鏈接已成功
    
  8. 繼續(xù)index.html文件代碼的編寫

    <script src="/socket.io/socket.io.js"></script>
    <script src="https://code.jquery.com/jquery-1.11.1.js"></script>
    <script type="text/javascript">
        $(function () {
            // 創(chuàng)建socket對象
            var socket = io();
    
            // 設(shè)置表單提交事件
            $('form').submit(function () {
                // 使用socket觸發(fā)事件,通過傳參的方式將數(shù)據(jù)傳遞給服務(wù)器
                socket.emit('chat message to server', $('#m').val());
                $('#m').val('');
                return false;
            });
        });
    </script>
    
  9. 當(dāng)點擊網(wǎng)頁中的發(fā)送按鈕時,會觸發(fā)socket觸發(fā)事件,進(jìn)行數(shù)據(jù)的傳遞,同樣的,也需要在服務(wù)器端進(jìn)行事件的監(jiān)聽
    server.js中添加如下代碼,進(jìn)行數(shù)據(jù)的獲取

    // 注冊事件,連接成功即可執(zhí)行
    io.on('connection', function (socket) {
        console.log('鏈接已成功');
    
        // 新增代碼++++++++++++++++++++++++++
        // 用于接收數(shù)據(jù)的監(jiān)聽
        socket.on('chat message to server', function (msg) {
            console.log('message: ' + msg);
        });
    
        // 注冊事件,連接斷開即可執(zhí)行
        socket.on('disconnect', function (socket) {
            console.log('鏈接已斷開');
        });
    });
    

    重啟服務(wù)器,在網(wǎng)頁中輸入內(nèi)容,然后點擊發(fā)送按鈕,即可看到控制臺中有內(nèi)容輸出

  10. 現(xiàn)在已經(jīng)實現(xiàn)了前端向后臺發(fā)送數(shù)據(jù),下面來實現(xiàn)服務(wù)器向瀏覽器返回數(shù)據(jù)。并重啟服務(wù)

// 用于接收數(shù)據(jù)的監(jiān)聽
socket.on('chat message to server', function (msg) {
    console.log('message: ' + msg);
    // 新增代碼++++++++++++++++++++++++++
    // 使用io對象進(jìn)行事件的觸發(fā),將數(shù)據(jù)從服務(wù)器發(fā)送到瀏覽器
    io.emit('chat message to browser', msg);
});
  1. index.html中接收服務(wù)器返回的數(shù)據(jù)

    // 注冊事件,用于接收瀏覽器返回的數(shù)據(jù)
    socket.on('chat message to browser', function (msg) {
        // 接收到數(shù)據(jù)后創(chuàng)建li標(biāo)簽,并拼接到頁面中
        $('#messages').append($('<li>').text(msg));
    });
    
  2. 代碼至此已經(jīng)編寫完畢,使用瀏覽器打開兩個網(wǎng)頁,均訪問http://localhost:8888地址,在一張網(wǎng)頁中輸入內(nèi)容,即可發(fā)現(xiàn)在另一個網(wǎng)頁中效果同步。這就是借助了WebSocket的及時通訊。

    除了實現(xiàn)瀏覽器端向服務(wù)器端發(fā)送數(shù)據(jù)外,服務(wù)器端也可以同時發(fā)送數(shù)據(jù)到瀏覽器中.

參考資料

https://socket.io/

https://socket.io/get-started/chat/

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,406評論 6 538
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,034評論 3 423
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,413評論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,449評論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 72,165評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,559評論 1 325
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,606評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,781評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,327評論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 41,084評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,278評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,849評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,495評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,927評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,172評論 1 291
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,010評論 3 396
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 48,241評論 2 375

推薦閱讀更多精彩內(nèi)容

  • WebSocket簡介 談到Web實時推送,就不得不說WebSocket。在WebSocket出現(xiàn)之前,很多網(wǎng)站為...
    吧啦啦小湯圓閱讀 8,171評論 15 75
  • 帶來兩大好處:1:Header互相溝通的Header是很小的,大概只有2 Bytes2:Server Push服務(wù)...
    liuboxx1閱讀 487評論 0 2
  • Web領(lǐng)域的實時推送技術(shù),也被稱作Realtime技術(shù)。這種技術(shù)要達(dá)到的目的是讓用戶不需要刷新瀏覽器就可以獲得實時...
    潘良虎閱讀 44,651評論 6 78
  • websocket的原理和應(yīng)用 在繼續(xù)本文之前,讓我們了解下websocket的原理: websocket通信協(xié)議...
    蔣跑跑轉(zhuǎn)圈閱讀 1,199評論 0 1
  • 為了最大程度的吸收笑來老師專欄內(nèi)容;為了最大程度的理解笑來老師言傳身教的概念;為了能夠做到通過這些概念,結(jié)結(jié)實...
    李建勇閱讀 190評論 0 0