老熟女激烈的高潮_日韩一级黄色录像_亚洲1区2区3区视频_精品少妇一区二区三区在线播放_国产欧美日产久久_午夜福利精品导航凹凸

重慶分公司,新征程啟航

為企業(yè)提供網(wǎng)站建設(shè)、域名注冊、服務(wù)器等服務(wù)

go語言ws協(xié)議,go語言tcp

為什么 Go 語言的性能還不如java

Go語言自亮相以來并沒有展示一個明確的方向,Google員工將Go語言稱為一個“試驗性語言”,稱其試圖融合Python等動態(tài)語言的開發(fā)速度和C或C++等編譯語言的性能和安全。一位Go語言的支持者概括而言Go語言如下:簡單、快速、安全、并發(fā)、快樂編程、開源;但Go語言缺乏方向以及其“集大成者”的嘗試很容易會導(dǎo)致其學(xué)貓不成學(xué)狗也不成,淪為四不像。盡管如此,編者仍然覺得Go語言有相當(dāng)大的潛力:很多開發(fā)者對它感興趣——不僅它的最初設(shè)計者陣容強大,而且在參與修改源代碼的人群中也不乏大牛級人物。這很有可能幫助Go語言找到適合自己的方向,開拓系統(tǒng)編程的新方向。

創(chuàng)新互聯(lián)公司堅持“要么做到,要么別承諾”的工作理念,服務(wù)領(lǐng)域包括:做網(wǎng)站、成都網(wǎng)站制作、企業(yè)官網(wǎng)、英文網(wǎng)站、手機端網(wǎng)站、網(wǎng)站推廣等服務(wù),滿足客戶于互聯(lián)網(wǎng)時代的黃石網(wǎng)站設(shè)計、移動媒體設(shè)計的需求,幫助企業(yè)找到有效的互聯(lián)網(wǎng)解決方案。努力成為您成熟可靠的網(wǎng)絡(luò)建設(shè)合作伙伴!

WebSocket+SLB(負載均衡)會話保持解決重連問題

寫在最前面:由于現(xiàn)在游戲基本上采用全球大區(qū)的模式,全球玩家在同一個大區(qū)進行游戲,傳統(tǒng)的單服模式已經(jīng)不能夠滿足當(dāng)前的服務(wù)需求,所以現(xiàn)在游戲服務(wù)器都在往微服務(wù)架構(gòu)發(fā)展。當(dāng)前我們游戲也是利用微服務(wù)架構(gòu)來實現(xiàn)全球玩家同服游戲。

玩家每次斷線(包括切換網(wǎng)絡(luò)/超時斷線)后應(yīng)該會重新連接服務(wù)器,重連成功的話可以繼續(xù)當(dāng)前情景繼續(xù)游戲,但是之前寫的底層重連機制一直不能生效,導(dǎo)致每次玩家斷線后重連都失敗,要從賬號登陸開始重新登陸,該文章寫在已經(jīng)定位了重連問題是由SLB引起后,提出的解決方案。

每次重連后,客戶端向SLB發(fā)送建立連接,SLB都會重新分配一個網(wǎng)關(guān)節(jié)點,導(dǎo)致客戶端連接到其他網(wǎng)關(guān),重連失敗。

會話保持的作用是什么?

開啟SLB會話保持功能后,SLB會記錄客戶端的IP地址,在一定時間內(nèi),自動將同一個IP的連接轉(zhuǎn)發(fā)到上次連接的網(wǎng)關(guān)。

在網(wǎng)絡(luò)不穩(wěn)定的情況下,游戲容易心跳或者發(fā)包超時,開啟會話保持,能解決大部分情況下的重連問題。

但是在切換網(wǎng)絡(luò)的時候,手機網(wǎng)絡(luò)從Wifi切換成4G,自身IP會變,這時候連接必定和服務(wù)器斷開,需要重新建立連接。由于IP已經(jīng)變化,SLB不能識別到是同一個客戶端發(fā)出的請求,會將連接轉(zhuǎn)發(fā)到其他網(wǎng)關(guān)節(jié)點。所以使用TCP連接的情況下,SLB開啟會話保持并不能解決所有的重連問題。

另外某些時刻,手機頻繁開啟和斷開WI-FI,有時候可能不會斷開網(wǎng)絡(luò),這并不是因為4G切換WI-FI時網(wǎng)絡(luò)沒斷開,從4G切換到Wi-Fi網(wǎng)絡(luò),因為IP變了,服務(wù)器不能識別到新的IP,連接肯定是斷開的。這時候網(wǎng)絡(luò)沒斷開,主要是因為現(xiàn)在智能手機會對4G和Wi-Fi網(wǎng)絡(luò)做個權(quán)重判斷,當(dāng)Wi-Fi網(wǎng)絡(luò)頻繁打開關(guān)閉時,手機會判斷Wi-Fi網(wǎng)絡(luò)不穩(wěn)定,所有流量都走4G。所以網(wǎng)絡(luò)沒斷開是因為一直使用4G連接,才沒有斷開。想要驗證,只需要切換Wi-Fi時,把4G網(wǎng)絡(luò)關(guān)閉,這樣流量就必定走Wi-Fi。

上面說過,四層的TCP協(xié)議主要是基于IP來實現(xiàn)會話保持。但是切換網(wǎng)絡(luò)的時候客戶端的IP會變。所以要解決切換網(wǎng)絡(luò)時的重連問題,只有兩個方法:1. 當(dāng)客戶端成功連接網(wǎng)關(guān)節(jié)點后,記錄下網(wǎng)關(guān)節(jié)點的IP,下次重連后不經(jīng)過SLB,直接向網(wǎng)關(guān)節(jié)點發(fā)送連接請求。2.使用 SLB的七層(HTTP)轉(zhuǎn)發(fā)服務(wù)。

當(dāng)客戶端經(jīng)過SLB將連接轉(zhuǎn)發(fā)到網(wǎng)關(guān)時,二次握手驗證成功后向客戶端發(fā)送自己節(jié)點的IP,這樣客戶端下次連接的時候就能直接連接網(wǎng)關(guān)節(jié)點。但是這樣會暴露網(wǎng)關(guān)的IP地址,為安全留下隱患。

如果不希望暴露網(wǎng)關(guān)的IP地址,就需要增加一層代理層,SLB將客戶端請求轉(zhuǎn)發(fā)到代理層,代理層再根據(jù)客戶端帶有的key,轉(zhuǎn)發(fā)到正確的網(wǎng)關(guān)節(jié)點上。增加一層代理層,不僅會增加請求的響應(yīng)時間,還會增加整體框架的復(fù)雜度。

阿里云的七層SLB會話保持服務(wù),主要是基于cookie的會話保持。客戶端在往服務(wù)器發(fā)送HTTP請求后,服務(wù)器會返回客戶端一個Response,SLB會在這時候,將經(jīng)過的Response插入或者重寫cookie。客戶端獲取到這個cookie,下次請求時會帶上cookie,SLB判斷Request的Headers里面有cookie,就將連接轉(zhuǎn)發(fā)到之前的網(wǎng)關(guān)節(jié)點。

HTTP是短鏈接,我們游戲是長連接,所以用HTTP肯定不合適。但是可以考慮基于HTTP的WebSocket。

什么是WebSocket?

WSS(Web Socket Secure)是WebSocket的加密版本。

SLB對WebSocket的支持

查看阿里云SLB文檔對WS的支持,說明SLB是支持WS協(xié)議的,并且SLB對于WS無需配置,只需要選用HTTP監(jiān)聽時,就能夠轉(zhuǎn)發(fā)WS協(xié)議。說明WS協(xié)議在SLB這邊看來就是一個HTTP,這樣WS走的也是七層的轉(zhuǎn)發(fā)服務(wù)。只要SLB能夠正常識別WS握手協(xié)議里Request的cookie和正常識別服務(wù)器返回的Response并且往里面插入cookie,就可以利用會話保持解決重連問題。

Go語言實現(xiàn)WS服務(wù)器有兩種方法,一種是利用golang.org/x/net下的websocket包,另外一種方法就是自己解讀Websocket協(xié)議來實現(xiàn),由于WS協(xié)議一樣是基于TCP協(xié)議之上,完全可以通過監(jiān)聽TCP端口來實現(xiàn)。

客戶端發(fā)送Request消息

服務(wù)器返回Response消息

其中服務(wù)器返回的Sec-WebSocket-Accept字段,主要是用于客戶端需要驗證服務(wù)器是否支持WS。RFC6455文檔中規(guī)定,在WebSocket通信協(xié)議中服務(wù)端為了證實已經(jīng)接收了握手,它需要把兩部分的數(shù)據(jù)合并成一個響應(yīng)。一部分信息來自客戶端握手的Sec-WebSocket-Keyt頭字段:Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==。對于這個字段,服務(wù)端必須得到這個值(頭字段中經(jīng)過base64編碼的值減去前后的空格)并與GUID"258EAFA5-E914-47DA-95CA-C5AB0DC85B11"組合成一個字符串,這個字符串對于不懂WebSocket協(xié)議的網(wǎng)絡(luò)終端來說是不能使用的。這個組合經(jīng)過SHA-1掩碼,base64編碼后在服務(wù)端的握手中返回。如果這個Sec-WebSocket-Accept計算錯誤瀏覽器會提示:Sec-WebSocket-Accept dismatch

如果返回成功,Websocket就會回調(diào)onopen事件

游戲服務(wù)器的使用的TCP協(xié)議,是在協(xié)議的包頭使用4Byte來聲明本協(xié)議長度,然后將協(xié)議一次性發(fā)送。但是在WS協(xié)議是通過Frame形式發(fā)送的,會將一條消息分為幾個frame,按照先后順序傳輸出去。這樣做會有幾個好處:

websocket的協(xié)議格式:

參數(shù)說明如下:

阿里云的SLB開啟HTTP監(jiān)聽后,會檢查過往的Request和Response請求,收到服務(wù)器返回的Response后,會往Response插入一個Cookie

客戶端收到服務(wù)器的Response后,可以在Header中查到有個“Set-Cookie”字段,里面是SLB插入的Cookie值

客戶端斷開連接后,下次發(fā)送請求需要往Headers插入Cookie字段

分別在阿里云的兩臺ECS實例上部署WS服務(wù)器,打開8000端口,開啟一個SLB服務(wù),SLB服務(wù)選擇HTTP方式監(jiān)聽,并且打開會話保持功能,Cookie處理方式選擇植入Cookie。Demo服務(wù)器沒有做HTTP健康監(jiān)聽的處理,健康檢查這塊可以先關(guān)掉。

在兩臺ECS上啟動WS服務(wù)器,然后本地運行客戶端,分別測試兩臺服務(wù)器是否能正常連接,測試完畢后,測試SLB能否正常工作。服務(wù)器和SLB都正常的情況下,運行客戶端,客戶端會得到以下結(jié)果

收到的三次Cookie都相同,說明Cookie是有正常植入工作的,并且三次都被SLB正確抓取了。

收到的三次serverId也都是同樣的值,說明三次都是同一個ECS上的服務(wù)器響應(yīng)。

至此,驗證成功。

Websocket+SLB會話保持能夠解決超時重連和切換網(wǎng)絡(luò)時重連的問題。

參考:

阿里云會話保持

解答Wi-Fi與4G網(wǎng)絡(luò)切換的困惑

WebSocket的實現(xiàn)原理

阿里云SLB對WebSocket的支持

HTTP Headers和Cookie

go語言聊天室實現(xiàn)(二)gorilla/websocket中的聊天室示例

我們可以看到 gorilla/websocket中的examples中有一個聊天室的demo。

我們進入該項目可以看到里面有這樣的一些內(nèi)容

按照官方的運行方式來運行這個項目

在瀏覽器中打開8080端口,可以看到該項目可以被成功運行了。

就是這樣一個簡單的demo。

然后我們?nèi)タ匆幌滤木唧w實現(xiàn)。

在這個項目中首先定義了一個hub的結(jié)構(gòu)體:

這個結(jié)構(gòu)體中,clients代表所有已經(jīng)注冊的用戶,broadcast管道會存儲客戶端發(fā)送來的信息。 register是一個*Client類型的管道,用于存儲新注冊的用戶,unregister管道反之。

我們打開main.go,main函數(shù)的源碼為:

在這里首先會新開一個goroutine,去跑hub的run方法,run方法中一個死循環(huán),不停地去輪詢hub中的內(nèi)容

如果取到了新用戶,就加入到clients中,如果取到了信息,就循環(huán)所有的client,將信息寫到client.send中。

我們看到在請求路徑為根的時候,它會請求一個函數(shù),而這個函數(shù)就是將home.html發(fā)送到客戶端。

而在請求路徑為“/ws”的時候,他會執(zhí)行一個serveWS的函數(shù)。

每當(dāng)一個新的用戶進來之后,首先將連接升級為長連接,然后將當(dāng)前的client寫到register中,由hub.run函數(shù)去做處理。然后開啟兩個goroutine,一個去讀client中發(fā)送來的數(shù)據(jù),一個將數(shù)據(jù)寫入到所有的client中,去發(fā)送給用戶。

這就是整個聊天室的實現(xiàn)原理。

go語言聊天室實現(xiàn)(六)創(chuàng)建HTTP連接,并升級為長連接

我們在mian函數(shù)中,首先初始化配置文件,然后新建http連接。

這個連接創(chuàng)建之后,監(jiān)聽服務(wù)器的9999端口。如果url的路徑后綴為 "/ws",就轉(zhuǎn)發(fā)到ws/ws.go中的IndexHandler方法中。

這個方法中首先我們創(chuàng)建一個websocket的Upgrader實例,然后我們使用Upgrader的upgrade方法來升級一下我們的連接為長連接。

升級完成之后會返回一個*websocket.Conn的連接,我們之后所有的關(guān)于連接的操作,都是基于該conn的。

在該連接完成之后,我們將連接存放到一個名為Client的map中,以便之后管理更為方便。

之后,我們啟動一個goroutine來讀取連接中發(fā)送的信息內(nèi)容,再根據(jù)內(nèi)容進行相應(yīng)的操作。

Go: WebSockets單元測試

WebSockets通過TCP連接提供客戶端與服務(wù)器之間的雙向即時通信。這意味著,我們可以維護一個TCP連接,然后發(fā)送和監(jiān)聽該連接上的消息,而不是不斷地通過新建TCP連接去輪詢web服務(wù)器的更新。

在Go的生態(tài)中,WebSocket協(xié)議有幾個不同的實現(xiàn)。有些庫是協(xié)議的純實現(xiàn)。另外一些人則選擇在WebSocket協(xié)議的基礎(chǔ)上構(gòu)建,為他們特定的用例創(chuàng)建更好的抽象。

下面是一個不全面的Go WebSocket協(xié)議實現(xiàn)列表:

在線拍賣是以實時通信為核心的行業(yè)之一。在一場拍賣中,幾秒鐘的時間就決定了你是贏了還是失去了一件你一直想要的收藏品。

讓我們以gorilla/websocket庫實現(xiàn)的簡單拍賣應(yīng)用程序作為本文的示例。

首先,我們將定義兩個非常簡單的結(jié)構(gòu)體Bid和Auction,我們將在WebSocket處理程序中使用它們。 Auction 有一個Bid方法,我們將使用該方法接收客戶端發(fā)送來的競價請求。

這兩種類型都相當(dāng)簡單,包含的字段非常少。NewAuction構(gòu)造函數(shù)構(gòu)建一個帶有持續(xù)時間、itemID和*Bids的Aution實例。

我們將通過 Bid 方法來實現(xiàn)拍賣的競標(biāo)動作:

Auction的Bid方法就是物品競拍發(fā)生的地方。它接收一個 amount 和 userID 作為參數(shù),并向 Auction 對象中添加Bid實例。而且它會檢查競拍是否結(jié)束以及的競拍價格是否大于已有的最大競價。如果這些條件中的任何一個不滿足,它將向調(diào)用者返回適當(dāng)?shù)腻e誤。

有了結(jié)構(gòu)體定義和Bid方法,讓我們深入到WebSockets機制。

想象一下,一個可以在拍賣中實時出價的網(wǎng)站。它通過WebSockets發(fā)送的每一條JSON消息都會包含用戶的標(biāo)識符( UserID )和出價的金額( amount )。一旦服務(wù)器接受了消息,它將參與競價并向客戶端返回一個競拍結(jié)果。

在服務(wù)器端,此通信將由 net/http 處理程序完成。它將處理所有WebSocket的業(yè)務(wù)邏輯,有幾個值得注意的步驟:

1、將接收到的HTTP連接升級為WebSocket連接。

2、接收來自客戶端的消息。

3、從消息中解碼出bid對象。

4、參與競價。

5、 向客戶端發(fā)送競拍結(jié)果。

下面我們來實現(xiàn)這個處理程序。首先定義 inbound 和 outbound 消息類型,用于接收和發(fā)送客戶端消息。

它們都分別表示入站/出站消息,這就是在客戶端和服務(wù)器之間的交互數(shù)據(jù)。 inbound 入站消息將表示一個出價,而 outbound 類型表示一個簡單的返回消息,其Body中包含一些文本。

接下來定義 bidsHandler ,包含ServeHTTP方法實現(xiàn)HTTP連接的升級:

首先定義 websocket.Upgrader ,接收處理程序的 http.ResponseWriter 和 *http.Resquest 并升級連接。 因為這只是一個應(yīng)用程序示例 upgrader.CheckOrigin 方法將只返回true,而不檢查傳入請求的來源。一旦 upgrader 完成連接的升級,將返回 *websocket.Conn 對象保存在 ws 變量中。 *websocket.Conn 將接收所有客戶端發(fā)送來的消息,也是處理程序讀取請求內(nèi)容的地方。同樣,處理程序?qū)?*websocket.Conn 寫入消息,它將向客戶端發(fā)送響應(yīng)消息。

for 循環(huán)做了幾件事:首先,使用 ws.ReadMessage() 讀取websocket消息,改函數(shù)返回消息類型(二進制或文本)和消息內(nèi)容( m )以及可能發(fā)生的錯誤( err )。然后,檢查客戶端是否意外地關(guān)閉了連接。

錯誤處理完成并讀取到消息,我們將使用 json.Unmarshal 對其進行解碼。接著調(diào)Bid方法參與競拍。然后使用 json.Marshal 對返回內(nèi)容進行序列化,使用 ws.WriteMessage 方法發(fā)送給客戶端。

盡管編寫WebSocket處理程序比普通HTTP處理程序要復(fù)雜得多,但測試它們很簡單。事實上,測試WebSockets處理程序就像測試HTTP處理程序一樣簡單。這是因為WebSockets是在HTTP上構(gòu)建的,所以測試WebSockets使用的工具與測試HTTP服務(wù)器相同。

首先添加測試用例:

首先,我們從定義測試用例開始。每個用例有一個 name ,這是測試用例的可讀名稱。此外,每個測試用例都有一個 bids 切片和一個duration持續(xù)時間,用于創(chuàng)建一個測試拍賣對象 Auction 。測試用例還有一個入站消息 inbound 和一個出站回復(fù) outbound —這是測試用例將發(fā)送給處理程序并期望從處理程序返回的消息。

在TestBidsHandler中我們添加三種不同的測試用例——一個是客戶端發(fā)起了錯誤的報價,低于目前最大報價,另一個測試用例,客戶端添加了一個正常的報價,第三個客戶端參與的拍賣已結(jié)束。

下面完成測試函數(shù):

我們在subtest函數(shù)體中添加了一些新函數(shù)。 newWSServe r將創(chuàng)建一個測試服務(wù)器并將其升級為WebSocket連接,同時返回服務(wù)器和WebSocket連接。然后, sendMessage 函數(shù)將通過WebSocket連接將消息從測試用例發(fā)送到測試服務(wù)器。之后,通過 receiveWSMessage ,我們將從服務(wù)器讀取響應(yīng),并通過將其與測試用例的進行比較來斷言其正確性。

那么,這些新的函數(shù)的作用是什么呢?讓我們逐一分析。

newWSServer 函數(shù)使用 httptest.NewServer 函數(shù)將處理程序掛載到測試HTTP服務(wù)器上。通過 httpToWS ,實現(xiàn)了將服務(wù)器的 URL 轉(zhuǎn)為websocket URL (它只是將URL中的 http 協(xié)議替換為 ws ,或?qū)?https 替換為 wss 協(xié)議)。

為了建立WebSocket連接,我們使用 WebSocket.DefaultDialer ,它是一個所有字段都設(shè)置為默認(rèn)值的dialer。調(diào)用 Dial 方法通過WebSocket服務(wù)器URL (wsURL)返回WebSocket連接。

sendMessage 函數(shù)接收一個WebSocket連接和 inbound 消息作為參數(shù)。將消息序列化成json以二進制格式在websocket連接中發(fā)送。

receiveWSMessage 函數(shù)以 ws WebSocket連接為參數(shù),通過 ws.ReadMessage() 讀取請求消息,然后反序列化成 outbound 類型返回。

如果我們運行測試,我們將看到它們通過:


網(wǎng)站題目:go語言ws協(xié)議,go語言tcp
本文鏈接:http://www.xueling.net.cn/article/hocjih.html

其他資訊

在線咨詢
服務(wù)熱線
服務(wù)熱線:028-86922220
TOP
主站蜘蛛池模板: 欧美aⅴ一区二区 | 欧美激情国产精品视频一区二区 | av片在线看免费高清网站 | 国产后入又长又硬 | 成人av18| 九色综合九色综合色鬼 | 亚洲精品乱码久久久v开放时间 | 亚洲一区二区三区在线网址 | 日本少妇人妻xxxxx18 | 大人在线免费视频 | 亚洲欧美日韩国产成人精品影院 | 国产精品人妻99一区二区三区 | 国产精品 | 欧美成人性a片免费观看办公室 | 91爱国产 | 放荡开放的人妻穿丁字裤凹 | 一级片黄 | 东京热T0KY0综合久久 | 第一次破處在线国语视频播放 | 国产精品美女久久久久 | 缅甸午夜性猛交xxxx | 亚洲高清视频一区 | 日韩av永久免费网站 | 在线精品亚洲一区二区不卡 | 国产一区二区在线免费播放 | 少妇把腿扒开让我舔18 | 成全免费高清观看 | 国产在线榴莲视频导航 | 国产精品一级无遮挡毛片 | 亚洲日韩国产精品第一页一区 | 91精品国产综合久久久久久久 | 国产精品香蕉在线观看首页 | 成人永久视频 | 国产麻豆乱子伦午夜视频观看 | 天海翼精品一区二区三区 | 搡女人真爽免费视频大全 | 久色成人 | 国产猛男GAYB0Y1069麻豆 | 成人涩涩 | 国产精品福利视频一区 | 精品国产福利久久久 |