近幾年,基于WebRTC的電話終端工具在通訊行業(yè)中越來越流行,客戶服務(wù)可以直接通過瀏覽器撥打電話來實現(xiàn)。目前業(yè)內(nèi)大多數(shù)Web電話工具僅支持單個頁面使用,無法支撐美團多業(yè)務(wù)復(fù)雜的外呼場景,美團在WebRTC領(lǐng)域不斷探索,實現(xiàn)了多頁面多域名共用的Web端電話SDK。在 RTE 2020 實時互聯(lián)網(wǎng)大會上,美團前端技術(shù)專家楊尚林分享了美團是如何通過共享線程來解決多頁面多域名下共享通話狀態(tài)的業(yè)界難題的。
??點擊「閱讀原文」可觀看視頻回放,獲取 PPT
以下為演講實錄:
大家好我是來自美團網(wǎng)的楊尚林,很高興來參加今年的實時互聯(lián)網(wǎng)大會,在這里我將也會跟大家交流一些我在美團這邊一些日常的工作。
今天我主要跟大家分享的題目是美團的webRTC電話終端工具實踐。下面開始我今天的分享,我今天的分享將會進行五個部分講解,分別是工具介紹、項目背景、項目目標(biāo)、實現(xiàn)方案以及最后的項目成果的展示,希望跟大家一起進行探討。
首先我會先介紹一下我們的終端工具到底是個什么樣的東西,大家首先可以看到一個demo的展示,那么相信在很多做通信公司里面都有的,很多公司都會做自己內(nèi)部電話的系統(tǒng),它其實本身是包括外呼、接聽、轉(zhuǎn)接、掛斷、呼叫保持、通話計時、通話質(zhì)量檢測,最后其實還包括一個很重要的多頁面的使用,我不知道各位公司里面會不會有這樣的功能??赐炅怂鞘裁粗螅覀儊砜匆幌滤捻椖勘尘笆鞘裁?,首先目前來說各個目前各大公司其實都有自己的云呼叫中心,或者有自己內(nèi)部自建的通信系統(tǒng),那么它本身是需要提供一些基礎(chǔ)的通話能力和坐席能力,比如說最基本的語音通話能力、坐席、技能、隊列等等能力,包括智能IVR、機器人的能力,同時它還會提供一套客戶關(guān)系管理或者工單系統(tǒng),那么會兼容其他的數(shù)據(jù)報表等系統(tǒng),包括知識庫。
其實我們可以看到語音通信能力是語音呼叫中心最基礎(chǔ)最基本的能力,語音通話能力一般情況下怎么樣去做呢。
現(xiàn)在的做法是說去實現(xiàn)一個桌面的軟件化,比如說我們平時經(jīng)常用的ESPhone/X-Lite,在PC端的情況下,那么在Web端我們一般依賴于WebRTC,比如說我們會實現(xiàn)一個電話條的工具或者一個單獨的頁面,給我們業(yè)務(wù)方去提供使用。
那么Web電話一般的使用場景是什么呢,首先我們會用一種電話條UI組建的方式去嵌入業(yè)務(wù)方的頁面中,這個頁面可能包括工單系統(tǒng)CRM等,它的功能包括電銷、回訪、客服這種常見的功能,因為它需要滿足我們正常的通話操作。比如說外呼、撥號、掛斷等等,它還需要去保持我們的通話狀態(tài),我們的坐席是需要實時的感知到電話的狀態(tài)的,比如說通話中、掛斷、忙線等。其實還有一些非常必要的功能。
目前來說我發(fā)現(xiàn)市面上其實很多的電話功能是不具備的,比如說多頁面、多系統(tǒng)、同狀態(tài),這三者分別是什么意思呢,第一點就是其實我們的業(yè)務(wù)方式需要在多個瀏覽器標(biāo)簽里進行外呼和掛斷的,其實目前來說大多數(shù)的這種電話工具都只是在單個tab頁里去發(fā)起外呼和接聽,或者只支持單個tab頁的注冊動作。這個需求是重點,就是說業(yè)務(wù)方其實是不關(guān)心自己的tab頁的行為是什么樣的,用戶也不需要關(guān)心自己所做的操作是什么,他們所關(guān)心的其實只是日常的工作,比如說他們接打電話、處理工單、回訪用戶等一系列。同時這個業(yè)務(wù)方還可能使用多個系統(tǒng),那么他們在真正接入的時候在對于同一個業(yè)務(wù)方的兩個系統(tǒng)來說,一個是工單系統(tǒng),一個是CRM系統(tǒng),他們所需要的接入信息是一樣的,因為這個坐席它可能是同時使用兩個系統(tǒng)的,那么當(dāng)一通電話呼入的時候它不可能說只是某一個頁面進行響應(yīng),或者是兩個同時響應(yīng),它是需要同時兩個響應(yīng)的話接起任意一個,所以說業(yè)務(wù)方式可能使用多個系統(tǒng)的,每個系統(tǒng)都需要具備外呼的能力,在這種狀態(tài)下這種同頁面多系統(tǒng)狀態(tài)下的,每一個標(biāo)簽頁都需要保持統(tǒng)一的狀態(tài)。
比如說我們在A頁面進行外呼的時候,我們這時候切換到B頁面把它掛斷到,其實電話所做的操作是一樣的,A、B頁面的電話都會被掛斷掉。
像這里就是展示了一個我們平時內(nèi)部的一個demo頁,我們可以在多個tab頁內(nèi)保持通話狀態(tài),并且在多個tab業(yè)同時進行通話。本次這個項目目標(biāo)我們是針對前面我們前面我們需要的功能去做一些分析。
第一個我們必須支持多頁面的使用,當(dāng)然除了基本的電話功能之外,那么它支持多頁面多系統(tǒng)同時注冊和使用,并且使用的注冊信息是相同的,比如說我們使用同一個分機號去進行注冊。
第二個多頁面、多系統(tǒng)的時候狀態(tài)是需要完全同步的。
第三個它的業(yè)務(wù)接入是需要非常簡單,因為我們的業(yè)務(wù)方它僅需要引入我們的組件就可以接入我們的工具了,而不是要關(guān)注我們?yōu)槎囗撁娑嘞到y(tǒng)開發(fā)的成本所帶來的變化。比如說它不需要為我們支持他們進行多頁面而進行任何的適配工作。
第四個就是我們的用戶體驗必須是良好的,首先保持良好的UI和交互,要有完美的錯誤回調(diào)和說明,也要提供很好的質(zhì)量檢測與設(shè)備探測功能。
我們在實現(xiàn)這個電話條中所經(jīng)歷的哪些過程,首先這個電話工具它其實是有三個難點的,第一個就是多Tab業(yè)注冊是很難的,第二個多連接管理是非常難的,第三個我們會給大家介紹一個新的方案,引入這個新的方案我們帶來了很多相關(guān)的問題。
首先我們看一下多Tab業(yè)為什么注冊難,我想這個問題大家都是非常清楚的,因為我們都是有共性的,我們知道在WebRTC SDP交換過程中,首先我們是需要對端的地址和端口號的,我們的媒體服務(wù)器其實會為每一個注冊的動作去事先分配好一個IP+端口號去用于日后的傳輸。如果說我們有多個Tab頁的時候,比如說當(dāng)Tab A已經(jīng)完成了注冊并且已經(jīng)完成了SDP的交互,并且在建立語音的情況下,就是說我們的媒體服務(wù)器已經(jīng)為他分配好了一個端口號去進行UDP的傳輸,我們的Tab B又發(fā)起了注冊,這個時候我們的媒體服務(wù)器又會為Tab B重新分配一個端口號去用于后續(xù)的傳輸,其實這個時候我們媒體服務(wù)器用于中轉(zhuǎn)語音流的端口其實是已經(jīng)變化了,就會導(dǎo)致當(dāng)前的通話直接被斷掉。
在我們?nèi)粘鼍爸袑嶋H上是面臨這個問題,我理解其實我們?nèi)粘I罟ぷ髦兴媾R的問題是大同小異的,所以說其實我們的結(jié)論在我們美團內(nèi)部的結(jié)論是顯而易見的,多個Tab頁其實我們只能為他進行一次的注冊動作。
那么其實我們怎么樣讓多個Tab只進行一次注冊動作呢,其實我們在這之間去引用sharedWorker,那首先我們先不去sharedWorker是什么,我們首先來看一下shared Worker在其中起到的作用是什么,我們目前來說,假如說我們有兩個Tab頁的話那么shared Worker在中間起到一個橋梁的作用,它會溝通兩個Tab頁,它會為兩個Tab頁之間建立一定的聯(lián)系,并且我們在Tab頁中間只保持一個sharedWorker,我們僅通過這個sharedWorker在我們的遠端發(fā)起單個連接,可以理解為TabA和TabB它們兩個共用了同一個連接。
這個時候這樣的話我們的注冊命令其實就很好實現(xiàn),因為在我們看來我們的電話工具其實是只有一個,我們其實不需要關(guān)心我們有幾個Tab頁,Tab A和Tab B目前來說對我們來說都已經(jīng)只是一個頁面了,我們只需要通過sharedWorker去發(fā)起同步的操作就可以了。
那么sharedWorker是什么呢,它是一個共享多線程,它本身代表了一種特定類型的Worker,可以從瀏覽器的上下文中訪問,比如說在幾個窗口內(nèi)iFrame或者其他的Worker中,它本身是有自己的全局作用域的,并且它還使用Post Message進行通信的。
它其實是有很多限制,比如說同源限制,那么我們其實規(guī)定加載的Worker腳本必須與我們的宿主頁面是同源的,并且shared Worker在連接不同頁面的時候,這些頁面也必須是同源的,就是說天然規(guī)定的我們所接觸的業(yè)務(wù)方它的域名必須是同源的,請注意我們之前提到過,我們是支持業(yè)務(wù)方使用多系統(tǒng)的,并且這些系統(tǒng)可能是不同域名的,后面會介紹我們怎么去處理這種現(xiàn)象。
第三個就是作用域是無法訪問DOM的,并且它無法在共享線程中使用任何WebRTC的相關(guān)API。7
下面有一個sharedWorker使用的例子。它的兼容性其實在我們看來是非常好的,目前來說在不考慮IE的情況下它的兼容性基本上與WebRTC相關(guān)的生態(tài)是同步的,并且國產(chǎn)瀏覽器同樣是支持,在國內(nèi)環(huán)境中。唯一的問題是隱身模式是無法使用的,但是這個其實不是問題,因為它和localStorage這些特性其實是一樣的。
首先我們來看同源限制,為什么我們需要去考慮這個同源限制呢,因為畢竟我們作為平臺方的話我們所有的資源腳本都是要去給業(yè)務(wù)方引用的,所以我們勢必會被為業(yè)務(wù)方提供一個npm包或是一個JS的腳本,這個時候勢必會與業(yè)務(wù)方的域起沖突,所以我們一定要想辦法解決這個同域的限制,我們這里研究出來兩個方法,分別一個是Data URL,一個是iFrame。
Data URL其實我們之前用過,比如說我們在引用Base64的時候其實都是去使用過的。我們怎么樣去使用它呢,我在下面也給出了一個例子,是通過本身的importScripts API去引入官方域下的sharedWorker腳本。
iFrame方案其實通過iFrame代理去進入sharedWorker腳本。舉個例子,我有兩個域名,分別是A域名和B域名,我其實是無法再兩個域名中間去建立使用同一個shared Worker的,但是我可以在A和B兩個域名中引用同樣域的iFrame,我們使用同樣域的iFrame去引入同樣的sharedWorker,那這個時候其實我們就間接的讓A和B共同的使用了shared Worker的腳本,之后我們再配合post Message進行消息中轉(zhuǎn)就可以了,相當(dāng)于iFrame在中間起到代理層的作用。
我們看一下架構(gòu)圖,針對單個域名的時候sharedWorker就是一個代理,我們是通過Data URL這種方案去引用的,意思就是我們使用sharedWorker的腳本地址是一個Data URL地址,之后它會為我們?nèi)ソ⑦B接,跟我們之前說的流程是完全一樣的。
其實很多人會擔(dān)心這種Data URL方式會不會更多的是一種hack,其實我們之前也是有擔(dān)心的,就是在我們比如嘗試摸索出Data URL這種方式之后,其實我們是專門去查證的原碼,最后是發(fā)現(xiàn)chromium是專門放開了Data URL這種跨域的限制,原碼也在這里,大家可以放心去使用的,因為這條commit是可以加上去的。
那么iFrame方案其實更多的是針對多個域名的情況,比如說像之前講到的我們存在兩個域名,我們可以同時引入相同域的官方iFrame腳本,并且引入同樣的sharedWorker去達到我們不同的域名不同頁面使用同一個sharedWorker的目的,并且通過這個sharedWorker幫我們做資源的分發(fā)連接,那么這里面其實與Data URL相比iFrame,我們?yōu)槭裁磿袃蓚€方案呢。就是因為iFrame其實大家都是比較清楚的,它相對來說耗費的資源要相對多一點,它的速度要相對慢一點,但是在絕對速度上來說其實也是在毫秒級別的,所以說業(yè)務(wù)方其實可以是自行選擇去采用多域名或者單域名的配置,我們僅僅是通過一個配置項就可以給他們提供到。這里面相對來說我們?nèi)绻f業(yè)務(wù)方只有單個域名的話使用Data URL這種方案可能會稍微快一點。
其實在這個方案的背后我們是有很多的問題的,這些問題其實是非常頭疼也是非常必要的,我們現(xiàn)在看一下我們?yōu)榱酥С治覀兊亩囗撁鏁肽男﹩栴},并且我們是如何解決這些問題。
我目前總結(jié)的這些問題應(yīng)該是支持多頁面里面并且是sharedWorker方案里面應(yīng)該是最棘手的問題了,底下分成三部分去講解。
首先我們就會面臨一個通話頁異常關(guān)閉的現(xiàn)象,那么它的現(xiàn)象是什么呢,就是因為我們的sharedWorker,我們之前講過它其實是無法使用WebRTC相關(guān)生態(tài)里的任何對象的,比如說MediaDevices,也就是說明我們的WebRTC相關(guān)設(shè)備連接邏輯必須是存在于我們業(yè)務(wù)方系統(tǒng)的某一個頁面內(nèi)。所以我們勢必會出現(xiàn),當(dāng)我們把那個頁面關(guān)閉掉的時候,如果業(yè)務(wù)方使用多個頁面,那其實多個頁面的整個這種呼叫都會被掛斷掉。
比如說我們關(guān)閉了發(fā)起外乎或者接聽的這種頁面的話,頁面的流就會被斷掉,下面有一個示意圖,其實我們?nèi)魏蔚倪@種多頁面的情況下,每時每刻都只有一個頁面的Web RTC其實真正的邏輯是在工作中的。它的原因是很明顯的,比如說我們在進行呼入的時候其實我們會在直接外呼的頁面上建立peerConnection的連接。比如說我們存在呼入的時候其實我們會在接聽的那個頁面上去進行peerConnection的連接。
下面是有例子的,比如說我有三個訂單頁,其實當(dāng)我的訂單A是真正的WebRTC承載頁,那如果說我不小心把它關(guān)掉了,我們大家想一下真實邏輯的處理流程,比如說我是一名客服,我要處理三個訂單,我很容易在跟一個用戶咨詢完電話之后我不小心,或者說在中途中,其實我切換了好多頁面,我是不小心把某個頁面關(guān)掉了,但是恰好這個頁面是我真正WebRTC承載的頁面,這個時候其實整個電話都會掛斷掉。這個只是我個人一個不小心的行為會導(dǎo)致整個頁面掛掉,但是我們不能把這個問題去歸咎去讓客服同學(xué)注意這種行為。
其實我們是需要給一定解決方案的,這個解決方案其實是比較簡單的,我們只需要去給到我們的開發(fā)同學(xué)一個正在通話的狀態(tài)就好了,我們讓他根據(jù)這個通話狀態(tài)去進行一個提示,比如說通話中我們不允許他關(guān)閉頁面,當(dāng)然這種方法是非常簡單非常高效的。但是其實我們有另外一種方法去完全規(guī)避這種開發(fā)的問題,這個時候我們會增加一個設(shè)備頁面,設(shè)備頁面它其實是用來創(chuàng)建WebRTC實例,并且建立peerConnection連接的頁面,其實這個設(shè)備頁面在我們提出這個方案之前它是存在一個業(yè)務(wù)方的邏輯里面的,就是業(yè)務(wù)方的頁面里面的,雖然跟我們的SDK在一起,最終我們是希望我們增加這個設(shè)備頁面去始終通過這個設(shè)備頁面去管理我們的語音,并且承載我們的通話。
我們看打開這個設(shè)備頁面的邏輯,設(shè)備頁面建立的時機是什么呢,比如說我們有呼入或者來電的時候,我們首先會去檢查設(shè)備頁面是否存在了,如果沒存在我們會把設(shè)備頁面拉起并且建立起來,并且建立它的WebRTC相關(guān)的邏輯。
他打開的策略是這個設(shè)備頁面會以最小的窗口進行打開,比方說我們給它高100像素的一個大小,并且它會顯示電話的狀態(tài),并且它會置于所有的tab頁之后,平時是不可見的。我們還會做一個邏輯,比如說當(dāng)我們的業(yè)務(wù)頁面全部關(guān)閉的時候,我們會自動觸發(fā)關(guān)閉這個tab頁的操作,其實用戶他不會感知到我們這個設(shè)備頁面的存在。就好比他是運行在所有tab頁之后的一個幽靈一樣。所有的操作同學(xué)他其實可以自由的使用他的頁面,關(guān)閉任何一個頁面都不會影響到設(shè)備頁面,只有說當(dāng)我們把所有的頁面全部關(guān)閉之后才會對設(shè)備頁面進行關(guān)閉的操作。
那么現(xiàn)在我們其實可以看一下整個的架構(gòu),因為我們其實是引入了sharedWorker,其實正是因為我們有sharedWorker我們才得以去實現(xiàn)這種設(shè)備頁面的這種操作,設(shè)備頁面其實與業(yè)務(wù)頁面他們之間都是通過sharedWorker去進行共享電話的狀態(tài)和操作的,比如說業(yè)務(wù)頁面進行電話的這種狀態(tài)的展示,設(shè)備頁面去執(zhí)行語音的動作,其實我們可以理解為每一個頁面包括設(shè)備頁面包括業(yè)務(wù)頁面他們都是可以從sharedWorker中獲取一定信息的。
當(dāng)然只是說他們執(zhí)行不同的動作而已,而只有設(shè)備頁面去承載語音的質(zhì)量,而且他是唯一承載語音質(zhì)量的頁面。
那么我們還會面臨版本升級混亂的問題,怎么去理解這個問題呢,其實可能多數(shù)沒有使用過sharedWorker同學(xué)完全想象不到這個問題的,但是這個問題在我們的升級開發(fā)中是非常非常嚴(yán)重的問題,因為他會導(dǎo)致我們整個電話系統(tǒng)不可用,并且每次當(dāng)我們發(fā)布新版本的時候都會存在這樣的問題,就是我們升級一個新版本,業(yè)務(wù)方卻完全不可用了,它是怎么回事呢,當(dāng)我們的sharedWorker腳本進行升級的時候,也就是對我們的SDK進行升級的時候,我們是需要對版本進行區(qū)分的。
因為sharedWorker它原理是跟webWorker一樣的,就是我們?nèi)绻胍獙λM行替換的話,我們需要去改變它的URL,所以我們需要用不同的版本對它的資源加以區(qū)分才可以替換。
比如說我們想把0.0.1的Worker去換掉0.0.2的Worker,我們真正期望的是多個頁面共享的sharedWorker,它其實能與正常的前端發(fā)布一樣,用戶是不需要關(guān)注頁面刷新或者說資源發(fā)布時機的,它可以正常的使用,完全無憂無慮的去用,我們來看一下這個問題是怎么造成的呢,其實在升級版本之前用戶的版本都是統(tǒng)一的。
比如說Worker的狀態(tài)其實也可以共享一例,所有的狀態(tài)都是可以同步的,比如說我們可以看一下左圖,當(dāng)我們沒有升級版本之前大家的版本都是0.0.1,包括sharedWorker它本身的腳本也是0.0.1。那我們升級版本之后用戶刷新了某個頁面會導(dǎo)致這個頁面版本升級,從而引入新的Worker腳本,這樣會導(dǎo)致多個頁面間狀態(tài)是無法同步的。
因為我們底層出現(xiàn)了兩個Worker腳本,它會與我們的遠端進行兩個連接,并且他們的上層所有這些業(yè)務(wù)頁面是無法再進行通信了,相當(dāng)于我們又開辟出來一個新的業(yè)務(wù)頁面,他們之間再也沒有關(guān)系了。這個例子大家是可以理解的。
比如說我們?nèi)齻€頁面中某一個頁面刷新了它變成0.0.2了,它勢必會引入新的shared Worker的資源,也變成0.0.2,這個時候其實我們底層的shared Worker會創(chuàng)建兩個事例,因為它們不再是同樣的URL了。
我們怎么去解決這個問題呢,其實我們需要引入一套shared Worker這種本身的升級機制的,去避免這種多頁面版本升級時和這種刷新動作帶來的這種不可用的現(xiàn)象,所以說我們可以通過我們總結(jié)出來的流程,去實現(xiàn)Worker的這種自我檢測和自我升級的。首先其實我們在運行過程中,我們是需要時時刻刻知道我們當(dāng)前的版本是什么。
比如說我們在我們打包的過程中,把我們當(dāng)前的版本給打入到我們的包里面去,在我們運行的過程中,其實我們在加載的初期是時刻需要對我們的Worker版本進行探測的。首先我們需要感知到當(dāng)前在活著所有的Worker它是一個什么樣的版本,而我們刷新之后我們新引入我們希望升級的Worker是一個什么樣的版本,其實我們怎么樣在我們刷新頁面的時候,知道我們當(dāng)前活著的就是其他頁面引用的Worker是什么呢。
因為這個時候我們還沒有建立這個shared Worker連接,其實我們是無法進行交互的,所以我們是需要先引入原先的shared Worker首先進行一個探測,去探測我們其他的頁面,目前的shared Worker是一個什么樣的狀態(tài),同時我們需要把這個狀態(tài)去存入我們的localStorage之中。就好比是,如果我們進來之后發(fā)現(xiàn)我們當(dāng)前已經(jīng)使用了localStorage里面某一個版本的版本號的話,那么我們會跟自己的狀態(tài)自身版本號進行對比,自身版本號發(fā)現(xiàn)不一致的情況下,我們會給它進行一個升級并且替換,這個升級替換規(guī)則是什么呢。
比如說我當(dāng)前是0.0.1我需要把自己替換成0.0.2,首先我需要同樣先引入0.0.1的這個sharedWorker,這樣的話我才能跟其他的頁面引入的sharedWorker的版本是一致的,我們大家都引入0.0.1的版本,這個時候sharedWorker是保持一列的,之后我再傳入一系列命令,去告訴我的sharedWorker你要把你自己替換成0.0.2的版本,然后shared Worker會先所有業(yè)務(wù)頁面同步狀態(tài),所有的業(yè)務(wù)頁面都會把自己對0.0.1版本的shared Worker的引用銷毀掉,并且把自己升級成0.0.2的版本。我們目前建立一種shared Worker自更新自升級的機制。
如果其實想實現(xiàn)一個Web電話工具,我們是需要有其他優(yōu)化內(nèi)容的,比如說我們需要去提供一些懶加載機制,避免業(yè)務(wù)方自身的懶加載。
第二我們需要一系列設(shè)備檢測,幫助我們客戶快速的定位問題,去檢測他們的設(shè)備當(dāng)前是否可用的,語音質(zhì)量是如何的。
第三個,我們需要去提供一些網(wǎng)絡(luò)檢測的工具或者說頁面,或者最好把它集成到我們的電話工具里面去,還需要對我們云監(jiān)控質(zhì)量進行一個通信的大盤,還需要給用戶在通話過程中進行一個Notification的提示,包括可視化的一個質(zhì)量信號實時的抖動。
還有我們每通電話它通信過程中發(fā)生的一些問題,如何快速定位問題,進行一個可視化的鏈路的監(jiān)控。
如果說在這個鏈路監(jiān)控中出現(xiàn)問題的時候,我們還需要對我們的操作人員或者說我們的開發(fā)人員進行一個實時的告警。
這里其實為大家展示了一個整體的架構(gòu)(如上圖所示),它其實會包括很多的東西,因為shared Worker是我們整個方案的核心,整個方案里面不光是有sharedWorker,其實它包含了很多內(nèi)容,所以工程化的能力其實也是需要去思考的,這里面也有我們的架構(gòu)圖可以給大家展示一下,最終我們其實是達成了一些成果的,有些成果是在我們意料之內(nèi),有些成果其實是在我們完成之后又去發(fā)現(xiàn)的,首先我們的業(yè)務(wù)收益其實是目前支撐了我們美團數(shù)千名坐席的日常電話服務(wù)。包括電銷、面試、銷售等各種各樣場景。
其實它是同時滿足業(yè)務(wù)方快速接入的,業(yè)務(wù)方其實只需要引入我們的資源就可以了,并且它執(zhí)行一個初始化的方法,他是不需要關(guān)心多個頁面帶來的問題的,接入是非常簡單的。
其實它是有一些技術(shù)收益的,比如說我們?nèi)ヒ雜haredWorker這個方案之后,大家知道我們是保持單個連接,單個連接大大的降低了我們后端系統(tǒng)復(fù)雜度的,比如說我們不需要再用MQ去同步機器之間的狀態(tài),我們不需要再去維護多個鏈接同步狀態(tài)去進行復(fù)雜的邏輯。
第二個我們是大大降低了并發(fā)的,不光是前端的連接,包括后端需要同步狀態(tài),MQ連接,包括數(shù)據(jù)庫查詢連接,包括我們Redis的連接等各個查詢連接,我們都是降低了很多并發(fā)流量的。
第三點我們知道,我們本次的方案是多個tab頁我們只引用了一個連接,其實我們的日志是只需要打印一路就可以了,多個tab頁其實對于我們來說更像是只存在一個電話,所以我們的日志也只需要一路了,否則的話我們需要打印多路日志,這些日志其實是有大量的冗余的,并且我們查起來其實所有日志的事件是交錯在一起的。
以上就是我本次的分享,本次分享里我也介紹了我們美團在電話業(yè)務(wù)上的一些實踐,為大家介紹了sharedWorker這種方案,其實sharedWorker這種方案不光是在電話的場景中,其實在日常工作中,比如IM系統(tǒng)中也是可以去使用的。
標(biāo)簽:迪慶
鞍山
咸寧
游戲
內(nèi)蒙古