聊一聊Web端的即時通信

聊一聊Web端的即時通信

Web端實現即時通信的方法有哪些?

- 短輪詢 長輪詢 iframe流 Flash Socket
輪詢 客戶端定時向服務器發送Ajax請求,服務器接到請求後立刻返回響應信息並關閉鏈接。 客戶端向服務器發送Ajax請求,服務器接到請求後hold住鏈接,直到有新消息才返回響應信息並關閉鏈接,客戶端處理完響應信息後再向服務器發送新的請求 頁面裏嵌入一個隱蔵iframe,將這個隱蔵iframe的src屬性設爲對一個長鏈接的請求或是採用xhr請求,服務器端就能源源不斷地往客戶端輸入數據 頁面中內嵌入一個使用了Socket類的 Flash 程序JavaScript經過調用此Flash程序提供的Socket接口與服務器端的Socket接口進行通訊
優勢 後端程序編寫比較容易。 在無消息的狀況下不會頻繁的請求,耗費資源小 瀏覽器兼容好 實現真正的即時通訊,而不是僞即時。消息即時到達,不發無用請求
缺點 浪費帶寬和服務器資源。 服務器維護一個長鏈接會增長開銷 IE、Mozilla Firefox會顯示加載沒有完成,圖標會不停旋轉。服務器維護一個長鏈接會增長開銷。 客戶端必須安裝Flash插件;非HTTP協議,沒法自動穿越防火牆
實例 適於小型應用。 WebQQ、Hi網頁版、Facebook IM。 Gmail聊天 網絡互動遊戲

iframe流

前端實現步驟:

  • Iframe設置爲不顯示。
  • src設爲請求的數據地址。
  • 定義個父級函數用戶讓iframe子頁面調用傳數據給父頁面。
  • 定義onload事件,服務器timeout後再次從新加載iframe。

後端輸出內容:

當有新消息時服務端會向iframe中輸入一段js代碼.:javascript

println("<script>父級函數('" + 數據 +"<br>')</script>」);

用於調用父級函數傳數據。html

Websocket VS SSE

websocket介紹


  • WebSocket是HTML5開始提供的一種在單個 TCP 鏈接上進行全雙工通信的協議。
  • 在WebSocket API中,瀏覽器和服務器只須要作一個握手的動做,而後,瀏覽器和服務器之間就造成了一條快速通道。二者之間就直接能夠數據互相傳送。

websocket 兼容性

image

websocket 相關應用

  • 社交聊天
  • 彈幕
  • 多屏互動
  • 多玩家遊戲
  • 協同編輯
  • 股票基金實時報價
  • 體育實況更新
  • 視頻會議/聊天
  • 在線教育
  • 智能家居等須要高實時的場景
  • webpack-dev-server
  • 等等...

主要的類庫

以socket.io爲例子

服務端

var app = require('koa')();
var server = require('http').createServer(app.callback());
var io = require('socket.io')(server);
io.on('connection', function(){
// listen to the event
socket.on('eventB', function(){ /* */ });
// emit an event to the socket
socket.emit('eventA', /* */);
});
server.listen(3000);

前端

<script src="http://localhost:3000/socket.io/socket.io.js"></script>
<script>
    var socket = new io()
        socket.on('eventA', function (res) {
        console.log('⽤戶1接收到信息了了')
    })
    socket.emit('eventB', data)
</script>
本身實現的一個demo,算是簡易版的你畫我猜
地址在這( https://github.com/jamielhf/n...

image

SSE(Server-Sent Events)介紹


HTTP 協議沒法作到服務器主動推送信息。可是,有一種變通方法,就是服務器向客戶端聲明,接下來要發送的是流信息(streaming)。前端

也就是說,發送的不是一次性的數據包,而是一個數據流,會接二連三地發送過來。這時,客戶端不會關閉鏈接,會一直等着服務器發過來的新的數據流,視頻播放就是這樣的例子。本質上,這種通訊就是以流信息的方式,完成一次用時很長的下載。java

SSE 兼容性

image

SSE 實現

客戶端

if(typeof(EventSource)!=="undefined")
    {
        var source=new EventSource("http://localhost:3001/stream");
        // onopen onerror

        source.onmessage=function(event)
        {
            document.getElementById("result").innerHTML+=event.data + "<br>";
        };
    }
    else
    {
        document.getElementById("result").innerHTML="抱歉,你的瀏覽器不支持 server-sent 事件...";
    }

服務端

var http = require("http");

http.createServer(function (req, res) {
  var fileName = "." + req.url;

  if (fileName === "./stream") {
    res.writeHead(200, {
      "Content-Type":"text/event-stream",
      "Cache-Control":"no-cache",
      "Connection":"keep-alive",
      "Access-Control-Allow-Origin": '*',
    });
    res.write("data: " + (new Date()) + "\n\n");

    interval = setInterval(function () {
      res.write("data: " + (new Date()) + "\n\n");
    }, 1000);

    req.connection.addListener("close", function () {
      clearInterval(interval);
    }, false);
  }
}).listen(3001, "127.0.0.1");

對比

Websocket SSE(Server-Sent Events)
通信方式 基於TCP長鏈接通信 http
優勢 全雙工通信協議,性能開銷小、安全性高,有必定可擴展性 實現簡便,開發成本低,默認支持斷線重連
缺點 傳輸數據須要進行二次解析,增長開發成本及難度 瀏覽器兼容問題,單向

原文地址

參考文章&資料

看完讓你完全搞懂Websocket原理
https://www.zhihu.com/questio...
Server-Sent Events 教程node

相關文章
相關標籤/搜索