瀏覽器多個標(biāo)簽頁之間的通信

一:websocket通訊

全雙工(full-duplex)通信自然可以實(shí)現(xiàn)多個標(biāo)簽頁之間的通信

WebSocket是HTML5新增的協(xié)議哥桥,它的目的是在瀏覽器和服務(wù)器之間建立一個不受限的雙向通信的通道,比如說壮不,服務(wù)器可以在任意時刻發(fā)送消息給瀏覽器由缆。為什么傳統(tǒng)的HTTP協(xié)議不能做到WebSocket實(shí)現(xiàn)的功能注祖?這是因?yàn)镠TTP協(xié)議是一個請求-響應(yīng)協(xié)議,請求必須先由瀏覽器發(fā)給服務(wù)器均唉,服務(wù)器才能響應(yīng)這個請求是晨,再把數(shù)據(jù)發(fā)送給瀏覽器。

也有人說舔箭,HTTP協(xié)議其實(shí)也能實(shí)現(xiàn)啊罩缴,比如用輪詢或者Comet。這個機(jī)制的缺點(diǎn)一是實(shí)時性不夠层扶,二是頻繁的請求會給服務(wù)器帶來極大的壓力箫章。

Comet本質(zhì)上也是輪詢,但是在沒有消息的情況下怒医,服務(wù)器先拖一段時間炉抒,等到有消息了再回復(fù)。這個機(jī)制暫時地解決了實(shí)時性問題稚叹,但是它帶來了新的問題:以多線程模式運(yùn)行的服務(wù)器會讓大部分線程大部分時間都處于掛起狀態(tài)焰薄,極大地浪費(fèi)服務(wù)器資源。另外扒袖,一個HTTP連接在長時間沒有數(shù)據(jù)傳輸?shù)那闆r下塞茅,鏈路上的任何一個網(wǎng)關(guān)都可能關(guān)閉這個連接,而網(wǎng)關(guān)是我們不可控的季率,這就要求Comet連接必須定期發(fā)一些ping數(shù)據(jù)表示連接“正常工作”野瘦。

WebSocket并不是全新的協(xié)議,而是利用了HTTP協(xié)議來建立連接。為什么WebSocket連接可以實(shí)現(xiàn)全雙工通信而HTTP連接不行呢鞭光?實(shí)際上HTTP協(xié)議是建立在TCP協(xié)議之上的吏廉,TCP協(xié)議本身就實(shí)現(xiàn)了全雙工通信,但是HTTP協(xié)議的請求-應(yīng)答機(jī)制限制了全雙工通信惰许。WebSocket連接建立以后席覆,其實(shí)只是簡單規(guī)定了一下:接下來,咱們通信就不使用HTTP協(xié)議了汹买,直接互相發(fā)數(shù)據(jù)吧佩伤。安全的WebSocket連接機(jī)制和HTTPS類似。首先晦毙,瀏覽器用wss://xxx創(chuàng)建WebSocket連接時生巡,會先通過HTTPS創(chuàng)建安全的連接,然后见妒,該HTTPS連接升級為WebSocket連接孤荣,底層通信走的仍然是安全的SSL/TLS協(xié)議。

WebSocket連接必須由瀏覽器發(fā)起徐鹤,特點(diǎn):

(1)建立在 TCP 協(xié)議之上垃环,服務(wù)器端的實(shí)現(xiàn)比較容易邀层。

(2)與 HTTP 協(xié)議有著良好的兼容性返敬。默認(rèn)端口也是80和443,并且握手階段采用 HTTP 協(xié)議寥院,因此握手時不容易屏蔽劲赠,能通過各種 HTTP 代理服務(wù)器。

(3)數(shù)據(jù)格式比較輕量秸谢,性能開銷小凛澎,通信高效。

(4)可以發(fā)送文本估蹄,也可以發(fā)送二進(jìn)制數(shù)據(jù)塑煎。

(5)沒有同源限制,客戶端可以與任意服務(wù)器通信臭蚁。

(6)協(xié)議標(biāo)識符是ws(如果加密最铁,則為wss),服務(wù)器網(wǎng)址就是 URL垮兑。

二:定時器setInterval+cookie

在頁面A設(shè)置一個使用?setInterval?定時器不斷刷新冷尉,檢查?Cookies?的值是否發(fā)生變化,如果變化就進(jìn)行刷新的操作系枪。

由于?Cookies?是在同域可讀的雀哨,所以在頁面 B 審核的時候改變?Cookies?的值,頁面 A 自然是可以拿到的。

這樣做確實(shí)可以實(shí)現(xiàn)我想要的功能雾棺,但是這樣的方法相當(dāng)浪費(fèi)資源膊夹。雖然在這個性能過盛的時代,浪費(fèi)不浪費(fèi)也感覺不出來捌浩,但是這種實(shí)現(xiàn)方案割疾,確實(shí)不夠優(yōu)雅。

三:使用localstorage

localstorage是瀏覽器多個標(biāo)簽共用的存儲空間嘉栓,所以可以用來實(shí)現(xiàn)多標(biāo)簽之間的通信(ps:session是會話級的存儲空間宏榕,每個標(biāo)簽頁都是單獨(dú)的)。

直接在window對象上添加監(jiān)聽即可:

window.onstorage = (e) => {console.log(e)}// 或者這樣window.addEventListener('storage', (e) => console.log(e))

onstorage以及storage事件侵佃,針對都是非當(dāng)前頁面對localStorage進(jìn)行修改時才會觸發(fā)麻昼,當(dāng)前頁面修改localStorage不會觸發(fā)監(jiān)聽函數(shù)。然后就是在對原有的數(shù)據(jù)的值進(jìn)行修改時才會觸發(fā)馋辈,比如原本已經(jīng)有一個key會a值為b的localStorage抚芦,你再執(zhí)行:localStorage.setItem('a', 'b')代碼,同樣是不會觸發(fā)監(jiān)聽函數(shù)的迈螟。

四:html5瀏覽器的新特性SharedWorker

普通的webworker直接使用new Worker()即可創(chuàng)建叉抡,這種webworker是當(dāng)前頁面專有的。然后還有種共享worker(SharedWorker)答毫,這種是可以多個標(biāo)簽頁褥民、iframe共同使用的。

SharedWorker可以被多個window共同使用洗搂,但必須保證這些標(biāo)簽頁都是同源的(相同的協(xié)議消返,主機(jī)和端口號)

首先新建一個js文件worker.js,具體代碼如下:

// sharedWorker所要用到的js文件耘拇,不必打包到項(xiàng)目中撵颊,直接放到服務(wù)器即可let data = ''onconnect = function (e) {? let port = e.ports[0]? port.onmessage = function (e) {? ? if (e.data === 'get') {? ? ? port.postMessage(data)? ? } else {? ? ? data = e.data? ? }? }}

webworker端(暫且這樣稱呼)的代碼就如上,只需注冊一個onmessage監(jiān)聽信息的事件惫叛,客戶端(即使用sharedWorker的標(biāo)簽頁)發(fā)送message時就會觸發(fā)倡勇。

注意webworker無法在本地使用,出于瀏覽器本身的安全機(jī)制嘉涌,所以我這次的示例也是放在服務(wù)器上的妻熊,worker.js和index.html在同一目錄。

因?yàn)榭蛻舳撕蛍ebworker端的通信不像websocket那樣是全雙工的洛心,所以客戶端發(fā)送數(shù)據(jù)和接收數(shù)據(jù)要分成兩步來處理固耘。示例中會有兩個按鈕,分別對應(yīng)的向sharedWorker發(fā)送數(shù)據(jù)的請求以及獲取數(shù)據(jù)的請求词身,但他們本質(zhì)上都是相同的事件--發(fā)送消息厅目。

webworker端會進(jìn)行判斷,傳遞的數(shù)據(jù)為'get'時,就把變量data的值回傳給客戶端损敷,其他情況葫笼,則把客戶端傳遞過來的數(shù)據(jù)存儲到data變量中。下面是客戶端的代碼:

// 這段代碼是必須的拗馒,打開頁面后注冊SharedWorker路星,顯示指定worker.port.start()方法建立與worker間的連接

? ? if (typeof Worker === "undefined") {

? ? ? alert('當(dāng)前瀏覽器不支持webworker')

? ? } else {

? ? ? let worker = new SharedWorker('worker.js')

? ? ? worker.port.addEventListener('message', (e) => {

? ? ? ? console.log('來自worker的數(shù)據(jù):', e.data)

? ? ? }, false)

? ? ? worker.port.start()

? ? ? window.worker = worker

? ? }

// 獲取和發(fā)送消息都是調(diào)用postMessage方法,我這里約定的是傳遞'get'表示獲取數(shù)據(jù)诱桂。

window.worker.port.postMessage('get')

window.worker.port.postMessage('發(fā)送信息給worker')

頁面A發(fā)送數(shù)據(jù)給worker洋丐,然后打開頁面B,調(diào)用window.worker.port.postMessage('get')挥等,即可收到頁面A發(fā)送給worker的數(shù)據(jù)友绝。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市肝劲,隨后出現(xiàn)的幾起案子迁客,更是在濱河造成了極大的恐慌,老刑警劉巖辞槐,帶你破解...
    沈念sama閱讀 216,997評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件掷漱,死亡現(xiàn)場離奇詭異,居然都是意外死亡榄檬,警方通過查閱死者的電腦和手機(jī)卜范,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,603評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來丙号,“玉大人先朦,你說我怎么就攤上這事∪В” “怎么了?”我有些...
    開封第一講書人閱讀 163,359評論 0 353
  • 文/不壞的土叔 我叫張陵棉浸,是天一觀的道長怀薛。 經(jīng)常有香客問我,道長迷郑,這世上最難降的妖魔是什么枝恋? 我笑而不...
    開封第一講書人閱讀 58,309評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮嗡害,結(jié)果婚禮上焚碌,老公的妹妹穿的比我還像新娘。我一直安慰自己霸妹,他們只是感情好十电,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,346評論 6 390
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般鹃骂。 火紅的嫁衣襯著肌膚如雪台盯。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,258評論 1 300
  • 那天畏线,我揣著相機(jī)與錄音静盅,去河邊找鬼。 笑死寝殴,一個胖子當(dāng)著我的面吹牛蒿叠,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播蚣常,決...
    沈念sama閱讀 40,122評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼栈虚,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了史隆?” 一聲冷哼從身側(cè)響起魂务,我...
    開封第一講書人閱讀 38,970評論 0 275
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎泌射,沒想到半個月后粘姜,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,403評論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡熔酷,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,596評論 3 334
  • 正文 我和宋清朗相戀三年孤紧,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片拒秘。...
    茶點(diǎn)故事閱讀 39,769評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡号显,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出躺酒,到底是詐尸還是另有隱情押蚤,我是刑警寧澤,帶...
    沈念sama閱讀 35,464評論 5 344
  • 正文 年R本政府宣布羹应,位于F島的核電站揽碘,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏园匹。R本人自食惡果不足惜雳刺,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,075評論 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望裸违。 院中可真熱鬧掖桦,春花似錦、人聲如沸供汛。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,705評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至料饥,卻和暖如春蒲犬,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背岸啡。 一陣腳步聲響...
    開封第一講書人閱讀 32,848評論 1 269
  • 我被黑心中介騙來泰國打工原叮, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人巡蘸。 一個月前我還...
    沈念sama閱讀 47,831評論 2 370
  • 正文 我出身青樓奋隶,卻偏偏與公主長得像,于是被迫代替她去往敵國和親悦荒。 傳聞我的和親對象是個殘疾皇子唯欣,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,678評論 2 354

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