久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

什么是socket?什么是websocket,??jī)烧哂惺裁磪^(qū)別,?

 nxhujiee 2019-07-02

HTML5規(guī)范在傳統(tǒng)的web交互基礎(chǔ)上為我們帶來(lái)了眾多的新特性,隨著web技術(shù)被廣泛用于web APP的開(kāi)發(fā),,這些新特性得以推廣和使用,,而websocket作為一種新的web通信技術(shù)具有巨大意義。

什么是socket,?什么是websocket,??jī)烧哂惺裁磪^(qū)別?websocket是僅僅將socket的概念移植到瀏覽器中的實(shí)現(xiàn)嗎,?

我們知道,,在網(wǎng)絡(luò)中的兩個(gè)應(yīng)用程序(進(jìn)程)需要全雙工相互通信(全雙工即雙方可同時(shí)向?qū)Ψ桨l(fā)送消息),需要用到的就是socket,,它能夠提供端對(duì)端通信,,對(duì)于程序員來(lái)講,他只需要在某個(gè)應(yīng)用程序的一端(暫且稱(chēng)之為客戶(hù)端)創(chuàng)建一個(gè)socket實(shí)例并且提供它所要連接一端(暫且稱(chēng)之為服務(wù)端)的IP地址和端口,,而另外一端(服務(wù)端)創(chuàng)建另一個(gè)socket并綁定本地端口進(jìn)行監(jiān)聽(tīng),,然后客戶(hù)端進(jìn)行連接服務(wù)端,服務(wù)端接受連接之后雙方建立了一個(gè)端對(duì)端的TCP連接,,在該連接上就可以雙向通訊了,,而且一旦建立這個(gè)連接之后,通信雙方就沒(méi)有客戶(hù)端服務(wù)端之分了,,提供的就是端對(duì)端通信了,。我們可以采取這種方式構(gòu)建一個(gè)桌面版的im程序,讓不同主機(jī)上的用戶(hù)發(fā)送消息,。從本質(zhì)上來(lái)說(shuō),,socket并不是一個(gè)新的協(xié)議,它只是為了便于程序員進(jìn)行網(wǎng)絡(luò)編程而對(duì)tcp/ip協(xié)議族通信機(jī)制的一種封裝,。

websocket是html5規(guī)范中的一個(gè)部分,,它借鑒了socket這種思想,為web應(yīng)用程序客戶(hù)端和服務(wù)端之間(注意是客戶(hù)端服務(wù)端)提供了一種全雙工通信機(jī)制,。同時(shí),,它又是一種新的應(yīng)用層協(xié)議,websocket協(xié)議是為了提供web應(yīng)用程序和服務(wù)端全雙工通信而專(zhuān)門(mén)制定的一種應(yīng)用層協(xié)議,通常它表示為:ws://echo.websocket.org/?encoding=text HTTP/1.1,,可以看到除了前面的協(xié)議名和http不同之外,,它的表示地址就是傳統(tǒng)的url地址。

可以看到,,websocket并不是簡(jiǎn)單地將socket這一概念在瀏覽器環(huán)境中的移植,,本文最后也會(huì)通過(guò)一個(gè)小的demo來(lái)進(jìn)一步講述socket和websocket在使用上的區(qū)別。

websocket的通信原理和機(jī)制

既然是基于瀏覽器端的web技術(shù),,那么它的通信肯定少不了http,websocket本身雖然也是一種新的應(yīng)用層協(xié)議,,但是它也不能夠脫離http而單獨(dú)存在。具體來(lái)講,,我們?cè)诳蛻?hù)端構(gòu)建一個(gè)websocket實(shí)例,,并且為它綁定一個(gè)需要連接到的服務(wù)器地址,當(dāng)客戶(hù)端連接服務(wù)端的時(shí)候,,會(huì)向服務(wù)端發(fā)送一個(gè)類(lèi)似下面的http報(bào)文

可以看到,,這是一個(gè)http get請(qǐng)求報(bào)文,注意該報(bào)文中有一個(gè)upgrade首部,,它的作用是告訴服務(wù)端需要將通信協(xié)議切換到websocket,如果服務(wù)端支持websocket協(xié)議,,那么它就會(huì)將自己的通信協(xié)議切換到websocket,同時(shí)發(fā)給客戶(hù)端類(lèi)似于以下的一個(gè)響應(yīng)報(bào)文頭

返回的狀態(tài)碼為101,表示同意客戶(hù)端協(xié)議轉(zhuǎn)換請(qǐng)求,,并將它轉(zhuǎn)換為websocket協(xié)議。以上過(guò)程都是利用http通信完成的,,稱(chēng)之為websocket協(xié)議握手(websocket Protocol handshake),,進(jìn)過(guò)這握手之后,客戶(hù)端和服務(wù)端就建立了websocket連接,,以后的通信走的都是websocket協(xié)議了,。所以總結(jié)為websocket握手需要借助于http協(xié)議,建立連接后通信過(guò)程使用websocket協(xié)議,。同時(shí)需要了解的是,,該websocket連接還是基于我們剛才發(fā)起http連接的那個(gè)TCP連接。一旦建立連接之后,,我們就可以進(jìn)行數(shù)據(jù)傳輸了,,websocket提供兩種數(shù)據(jù)傳輸:文本數(shù)據(jù)和二進(jìn)制數(shù)據(jù)。

基于以上分析,,我們可以看到,,websocket能夠提供低延遲,高性能的客戶(hù)端與服務(wù)端的雙向數(shù)據(jù)通信,。它顛覆了之前web開(kāi)發(fā)的請(qǐng)求處理響應(yīng)模式,,并且提供了一種真正意義上的客戶(hù)端請(qǐng)求,服務(wù)器推送數(shù)據(jù)的模式,特別適合實(shí)時(shí)數(shù)據(jù)交互應(yīng)用開(kāi)發(fā),。

在websocket之前,,我們?cè)趙eb上要得到實(shí)時(shí)數(shù)據(jù)交互都采用了哪些方式?

1)定期輪詢(xún)的方式:

客戶(hù)端按照某個(gè)時(shí)間間隔不斷地向服務(wù)端發(fā)送請(qǐng)求,,請(qǐng)求服務(wù)端的最新數(shù)據(jù)然后更新客戶(hù)端顯示,。這種方式實(shí)際上浪費(fèi)了大量流量并且對(duì)服務(wù)端造成了很大壓力。

2)comet技術(shù)

comet并不是一種新的通信技術(shù),,它是在客戶(hù)端請(qǐng)求服務(wù)端這個(gè)模式上的一種hack技術(shù),,通常來(lái)講,它主要分為以下兩種做法

(1)基于長(zhǎng)輪詢(xún)的服務(wù)端推送技術(shù)

具體來(lái)講,,就是客戶(hù)端首先給服務(wù)端發(fā)送一個(gè)請(qǐng)求,,服務(wù)端收到該請(qǐng)求之后如果數(shù)據(jù)沒(méi)有更新則并不立即返回,服務(wù)端阻塞請(qǐng)求的返回,,直到數(shù)據(jù)發(fā)生了更新或者發(fā)生了連接超時(shí),,服務(wù)端返回?cái)?shù)據(jù)之后客戶(hù)端再次發(fā)送同樣的請(qǐng)求,如下所示:

2)基于流式數(shù)據(jù)傳輸?shù)拈L(zhǎng)連接

通常的做法是在頁(yè)面中嵌入一個(gè)隱藏的iframe,然后讓這個(gè)iframe的src屬性指向我們請(qǐng)求的一個(gè)服務(wù)端地址,,并且為了數(shù)據(jù)更新,,我們將頁(yè)面上數(shù)據(jù)更新操作封裝為一個(gè)js函數(shù),將函數(shù)名當(dāng)做參數(shù)傳遞到這個(gè)地址當(dāng)中,,

服務(wù)端收到請(qǐng)求后解析地址取出參數(shù)(客戶(hù)端js函數(shù)調(diào)用名),,每當(dāng)有數(shù)據(jù)更新的時(shí)候,返回對(duì)客戶(hù)端函數(shù)的調(diào)用,,并且將要跟新的數(shù)據(jù)以js函數(shù)的參數(shù)填入到返回內(nèi)容當(dāng)中,,例如返回“<script type="text/javascript">update("data")</script>”這樣一個(gè)字符串,意味著以data為參數(shù)調(diào)用客戶(hù)端update函數(shù)進(jìn)行客戶(hù)端view更新,?;灸P腿缦滤荆?/p>

可以看到comet技術(shù)是針對(duì)客戶(hù)端請(qǐng)求服務(wù)器響應(yīng)模型而模擬出的一個(gè)服務(wù)端推送數(shù)據(jù)實(shí)時(shí)更新技術(shù)。而且由于瀏覽器兼容性不能夠廣泛應(yīng)用,。

當(dāng)然并不是說(shuō)這些技術(shù)沒(méi)有用,,就算websocket已經(jīng)作為規(guī)范被提出并實(shí)現(xiàn),但是對(duì)于老式瀏覽器,,我們依然需要將它降級(jí)為以上方式來(lái)實(shí)現(xiàn)實(shí)時(shí)交互和服務(wù)端數(shù)據(jù)推送,。

到此為止,我們明白了websocket的原理,,下面通過(guò)一個(gè)簡(jiǎn)單的聊天應(yīng)用來(lái)再次加深下對(duì)websocket的理解,。

該應(yīng)用需求很簡(jiǎn)單,就是在web選項(xiàng)卡中打開(kāi)兩個(gè)網(wǎng)頁(yè),,模擬兩個(gè)web客戶(hù)端實(shí)現(xiàn)聊天功能,。

首先是客戶(hù)端如下:

client.html

復(fù)制代碼
<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <style>
        *{
            margin: 0;
            padding: 0;
        }
        .message{
            width: 60%;
            margin: 0 10px;
            display: inline-block;
            text-align: center;
            height: 40px;
            line-height: 40px;
            font-size: 20px;
            border-radius: 5px;
            border: 1px solid #B3D33F;
        }
        .form{
            width:100%;
            position: fixed;
            bottom: 300px;
            left: 0;
        }
        .connect{
            height: 40px;
            vertical-align: top;
            /* padding: 0; */
            width: 80px;
            font-size: 20px;
            border-radius: 5px;
            border: none;
            background: #B3D33F;
            color: #fff;
        }
    </style>
</head>
<body>
<ul id="content"></ul>
<form class="form">
<input type="text" placeholder="請(qǐng)輸入發(fā)送的消息" class="message" id="message"/>
<input type="button" value="發(fā)送" id="send" class="connect"/>
<input type="button" value="連接" id="connect" class="connect"/>
</form>
<script></script>
</body>
</html>
復(fù)制代碼

客戶(hù)端js代碼

復(fù)制代碼
  var oUl=document.getElementById('content');
    var oConnect=document.getElementById('connect');
    var oSend=document.getElementById('send');
    var oInput=document.getElementById('message');
    var ws=null;
    oConnect.onclick=function(){
        ws=new WebSocket('ws://localhost:5000');
         ws.onopen=function(){
             oUl.innerHTML+="<li>客戶(hù)端已連接</li>";
         }
        ws.onmessage=function(evt){
            oUl.innerHTML+="<li>"+evt.data+"</li>";
        }
        ws.onclose=function(){
            oUl.innerHTML+="<li>客戶(hù)端已斷開(kāi)連接</li>";
        };
        ws.onerror=function(evt){
            oUl.innerHTML+="<li>"+evt.data+"</li>";

        };
    };
    oSend.onclick=function(){
        if(ws){
            ws.send(oInput.value);
        }
    }
復(fù)制代碼

這里使用的是w3c規(guī)范中關(guān)于HTML5 websocket API的原生API,,這些api很簡(jiǎn)單,就是利用new WebSocket創(chuàng)建一個(gè)指定連接服務(wù)端地址的ws實(shí)例,,然后為該實(shí)例注冊(cè)onopen(連接服務(wù)端),onmessage(接受服務(wù)端數(shù)據(jù)),,onclose(關(guān)閉連接)以及ws.send(建立連接后)發(fā)送請(qǐng)求。上面說(shuō)了那么多,,事實(shí)上可以看到html5 websocket API本身是很簡(jiǎn)單的一個(gè)對(duì)象和它的幾個(gè)方法而已,。

服務(wù)端采用nodejs,這里需要基于一個(gè)nodejs-websocket的nodejs服務(wù)端的庫(kù),,它是一個(gè)輕量級(jí)的nodejs websocket server端的實(shí)現(xiàn),,實(shí)際上也是使用nodejs提供的net模塊寫(xiě)成的。

server.js

復(fù)制代碼
var app=require('http').createServer(handler);
var ws=require('nodejs-websocket');
var fs=require('fs');
app.listen(80);
function handler(req,res){
    fs.readFile(__dirname+'/client.html',function(err,data){
        if(err){
            res.writeHead(500);
            return res.end('error ');
        }
        res.writeHead(200);
        res.end(data);
    });
}
var server=ws.createServer(function(conn){
    console.log('new conneciton');
    conn.on("text",function(str){
        broadcast(server,str);
    });
    conn.on("close",function(code,reason){
        console.log('connection closed');
    })
}).listen(5000);

function broadcast(server, msg) {
    server.connections.forEach(function (conn) {
        conn.sendText(msg);
    })
}
復(fù)制代碼

首先利用http模塊監(jiān)聽(tīng)用戶(hù)的http請(qǐng)求并顯示client.html界面,,然后創(chuàng)建一個(gè)websocket服務(wù)端等待用戶(hù)連接,,在接收到用戶(hù)發(fā)送來(lái)的數(shù)據(jù)之后將它廣播到所有連接到的客戶(hù)端。

下面我們打開(kāi)兩個(gè)瀏覽器選項(xiàng)卡模擬兩個(gè)客戶(hù)端進(jìn)行連接,,

客戶(hù)端一連接:

請(qǐng)求響應(yīng)報(bào)文如下:

可以看到這次握手和我們之前講的如出一轍,,

客戶(hù)端二的連接過(guò)程和1是一樣的,這里為了查看我們使用ff瀏覽器,,兩個(gè)客戶(hù)端的連接情況如下:

發(fā)送消息情況如下:

可以看到,,雙方發(fā)送的消息被服務(wù)端廣播給了每個(gè)和自己連接的客戶(hù)端。

從以上我們可以看到,,要想做一個(gè)點(diǎn)對(duì)點(diǎn)的im應(yīng)用,,websocket采取的方式是讓所有客戶(hù)端連接服務(wù)端,服務(wù)器將不同客戶(hù)端發(fā)送給自己的消息進(jìn)行轉(zhuǎn)發(fā)或者廣播,,而對(duì)于原始的socket,,只要兩端建立連接之后,就可以發(fā)送端對(duì)端的數(shù)據(jù),,不需要經(jīng)過(guò)第三方的轉(zhuǎn)發(fā),這也是websocket不同于socket的一個(gè)重要特點(diǎn),。

最后,,本文為了說(shuō)明html5規(guī)范中的websocket在客戶(hù)端采用了原生的API,實(shí)際開(kāi)發(fā)中,,有比較著名的兩個(gè)庫(kù)sockjs,它們都對(duì)原始的API做了進(jìn)一步封裝,,提供了更多功能,都分為客戶(hù)端和服務(wù)端的實(shí)現(xiàn),,實(shí)際應(yīng)用中,,可以選擇使用。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,,所有內(nèi)容均由用戶(hù)發(fā)布,,不代表本站觀點(diǎn),。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,,謹(jǐn)防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào),。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶(hù) 評(píng)論公約

    類(lèi)似文章 更多