欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

golang微服務框架kratos實現(xiàn)Socket.IO服務的方法

 更新時間:2023年06月28日 10:39:22   作者:喵個咪  
本文主要介紹了golang微服務框架kratos實現(xiàn)Socket.IO服務的方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

Socket.IO 是一個面向?qū)崟r web 應用的 實時通訊庫。它使得服務器和客戶端之間實時雙向的通信成為可能。底層使用EngineIO。SocketIO的的客戶端使用Engine.IO-Client,服務端使用Engine.IO實現(xiàn)。

Socket.IO 主要使用WebSocket協(xié)議。但是如果需要的話,Socket.IO 可以回退到幾種其它方法,例如Adobe Flash Sockets,JSONP拉取,或是傳統(tǒng)的AJAX拉取,并且在同時提供完全相同的接口。盡管它可以被用作WebSocket的包裝庫,它還是提供了許多其它功能,比如廣播至多個套接字,存儲與不同客戶有關的數(shù)據(jù),和異步IO操作。

Socket.IO如何工作

客戶端

EIO Socket 通過一個 XHR (XMLHttpRequest) 握手。前端發(fā)送一個 XHR,告訴服務端我要開始 XHR 長輪詢了。后端返回的數(shù)據(jù)里面包括一個 open 標志(數(shù)字 0 表示), 以及sid 和 upgrades 字段,ping時間間隔,ping超時時間。

{
"sid": "8b7ab1ae-fbcf-4d23-8192-3c14a2a90721",
"upgrades": [
"websocket"
],
"pingInterval": 10000,
"pingTimeout": 60000
}

sid 是本次 EIO Socket 的會話 ID,因為一次 EIO Socket 包含了多個請求,而后端又會同時連接多個 EIO Socket,sid 的作用就相當于 SESSION ID。
另一個字段 upgrades,正常情況下是 ['websocket'],表示可以把連接方式從長輪詢升級到 WebSocket。

前端在發(fā)送第一個 XHR 的時候就開始了 XHR 長輪詢,這個時候如果有收發(fā)數(shù)據(jù)的需求,是通過長輪詢實現(xiàn)的。所謂長輪詢,是指前端發(fā)送一個 request,服務端會等到有數(shù)據(jù)需要返回時再 response. 前端收到 response 后馬上發(fā)送下一次 request。這樣就可以實現(xiàn)雙向通信。

前端收到握手的 upgrades 后,EIO 會檢測瀏覽器是否支持 WebSocket,如果支持,就會啟動一個 WebSocket 連接,然后通過這個 WebSocket 往服務器發(fā)一條內(nèi)容為 probe, 類型為 ping 的數(shù)據(jù)。如果這時服務器返回了內(nèi)容為 probe, 類型為 pong 的數(shù)據(jù),前端就會把前面建立的 HTTP 長輪詢停掉,后面只使用 WebSocket 通道進行收發(fā)數(shù)據(jù)
EIO Socket 生命周期內(nèi),會間隔一段時間 ping - pong 一次,用來測試網(wǎng)絡是否正常。

這是 WebSocket 幀的結構,綠色是發(fā)送,白色是接收。前面的數(shù)字是數(shù)據(jù)包類型,2 是 ping, 3 是 pong, 42是 message

服務端

服務端使用 ws 庫實現(xiàn) WebSocket 協(xié)議。http://socket.io 服務啟動時,會先啟動一個 ws 服務。http://socket.io 會監(jiān)聽 HTTP 服務器的 upgrade 和 request 事件。當 upgrade 事件觸發(fā)時,說明可能是 WebSocket 握手,先簡單校驗下,然后把請求交給 ws 服務進行處理,拿到 WebSocket 對象。當 request 事件觸發(fā)時,根據(jù) url 路徑判斷是不是 http://socket.io 的 XHR 請求,拿到 res 和 res 對象。這樣就可以正確接收和返回客戶端數(shù)據(jù)了,具體處理過程和前端部分是對應的。

Socket.IO的限制

與所有技術一樣,選擇正確的一種意味著明確您對產(chǎn)品未來的期望。與您自己創(chuàng)建Socket鏈接相比,SocketIO確實使許多事情變得更容易,但是除了上面提到的擴展問題之外,還有局限性和缺點。
首先是初始連接比WebSockets更長。這是因為它首先使用長輪詢和XHRPolling建立連接,然后升級到WebSocket(如果可用)。如果您不需要支持較舊的瀏覽器并且不擔心不支持WebSockets的客戶端環(huán)境,則可能不需要SocketIO的額外開銷。您可以通過指定僅與WebSockets連接來最大程度地減少這種影響。這將更改與WebSocket的初始連接,但是會關閉備選方案。

在代碼最小化的情況下,客戶端仍將需要下載61.2 KB的數(shù)據(jù)。

對于其他繁重的數(shù)據(jù)傳輸(例如,視頻流傳輸),Socket不是好的解決方案。如果要在此級別上支持數(shù)據(jù)交換,則更好的解決方案是webRTC或流數(shù)據(jù)傳輸服務商,Ably是其中之一。

Kratos服務端

首先安裝庫:

go get -u github.com/tx7do/kratos-transport/transport/socketio

然后實現(xiàn)一個簡單的服務端:

package main
import (
?? ?"context"
?? ?"os"
?? ?"os/signal"
?? ?"syscall"
?? ?"github.com/go-kratos/kratos/v2/log"
? ? transportSocketIO "github.com/tx7do/kratos-transport/transport/socketio"
?? ?socketio "github.com/googollee/go-socket.io"
)
func main() {
?? ?interrupt := make(chan os.Signal, 1)
?? ?signal.Notify(interrupt, syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT)
?? ?ctx := context.Background()
?? ?srv := transportSocketIO.NewServer(
?? ??? ?transportSocketIO.WithAddress(":8000"),
?? ??? ?transportSocketIO.WithCodec("json"),
?? ??? ?transportSocketIO.WithPath("/socket.io/"),
?? ?)
?? ?srv.RegisterConnectHandler("/", func(s socketio.Conn) error {
?? ??? ?s.SetContext("")
?? ??? ?log.Info("connected:", s.ID())
?? ??? ?return nil
?? ?})
?? ?srv.RegisterEventHandler("/", "notice", func(s socketio.Conn, msg string) {
?? ??? ?log.Info("notice:", msg)
?? ??? ?s.Emit("reply", "have "+msg)
?? ?})
?? ?srv.RegisterEventHandler("/chat", "msg", func(s socketio.Conn, msg string) string {
?? ??? ?s.SetContext(msg)
?? ??? ?return "recv " + msg
?? ?})
?? ?srv.RegisterEventHandler("/", "bye", func(s socketio.Conn) string {
?? ??? ?last := s.Context().(string)
?? ??? ?s.Emit("bye", last)
?? ??? ?_ = s.Close()
?? ??? ?return last
?? ?})
?? ?srv.RegisterErrorHandler("/", func(s socketio.Conn, e error) {
?? ??? ?log.Info("meet error:", e)
?? ?})
?? ?srv.RegisterDisconnectHandler("/", func(s socketio.Conn, reason string) {
?? ??? ?log.Info("closed", reason)
?? ?})
?? ?if err := srv.Start(ctx); err != nil {
?? ??? ?panic(err)
?? ?}
?? ?defer func() {
?? ??? ?if err := srv.Stop(ctx); err != nil {
?? ??? ??? ?t.Errorf("expected nil got %v", err)
?? ??? ?}
?? ?}()
?? ?<-interrupt
}

JS客戶端

<!DOCTYPE html>
<html lang="en">
<head>
? ? <title>Socket.IO chat</title>
? ? <meta charset='utf-8'>
? ? <meta http-equiv='X-UA-Compatible' content='IE=edge'>
? ? <meta name='viewport' content='width=device-width, initial-scale=1'>
? ? <style>
? ? ? ? * {
? ? ? ? ? ? margin: 0;
? ? ? ? ? ? padding: 0;
? ? ? ? ? ? box-sizing: border-box;
? ? ? ? }
? ? ? ? body {
? ? ? ? ? ? font: 13px Helvetica, Arial;
? ? ? ? }
? ? ? ? form {
? ? ? ? ? ? background: #000;
? ? ? ? ? ? padding: 3px;
? ? ? ? ? ? position: fixed;
? ? ? ? ? ? bottom: 0;
? ? ? ? ? ? width: 100%;
? ? ? ? }
? ? ? ? form input {
? ? ? ? ? ? border: 0;
? ? ? ? ? ? padding: 10px;
? ? ? ? ? ? width: 90%;
? ? ? ? ? ? margin-right: .5%;
? ? ? ? }
? ? ? ? form button {
? ? ? ? ? ? width: 9%;
? ? ? ? ? ? background: rgb(130, 224, 255);
? ? ? ? ? ? border: none;
? ? ? ? ? ? padding: 10px;
? ? ? ? }
? ? ? ? #messages {
? ? ? ? ? ? list-style-type: none;
? ? ? ? ? ? margin: 0;
? ? ? ? ? ? padding: 0;
? ? ? ? }
? ? ? ? #messages li {
? ? ? ? ? ? padding: 5px 10px;
? ? ? ? }
? ? ? ? #messages li:nth-child(odd) {
? ? ? ? ? ? background: #eee;
? ? ? ? }
? ? </style>
</head>
<body>
<ul id="messages"></ul>
<form action="">
? ? <input id="m" autocomplete="off"/>
? ? <button>Send</button>
</form>
<!--<script src="https://cdn.socket.io/4.6.0/socket.io.min.js" integrity="sha384-c79GN5VsunZvi+Q/WObgk2in0CbZsHnjEqvFxC5DxHn9lTfNce2WW6h2pH6u/kF+" crossorigin="anonymous"></script>-->
<script src="https://cdn.socket.io/socket.io-1.2.0.js"></script>
<script src="https://code.jquery.com/jquery-1.11.1.js"></script>
<script>
? ? var socket = io("ws://localhost:8000");
? ? // var socket2 = io("http://localhost:8000/chat/");
? ? socket.on('reply', function (msg) {
? ? ? ? $('#messages').append($('<li>').text(msg));
? ? });
? ? $('form').submit(function () {
? ? ? ? // socket2.emit('msg', $('#m').val(), function (data) {
? ? ? ? // ? ? $('#messages').append($('<li>').text('ACK CALLBACK: ' + data));
? ? ? ? // });
? ? ? ? socket.emit('notice', $('#m').val());
? ? ? ? $('#m').val('');
? ? ? ? return false;
? ? });
</script>
</body>
</html>

參考資料 (Reference)

go-socket.io
Socket.IO
什么是socketIO?

到此這篇關于golang微服務框架kratos實現(xiàn)Socket.IO服務的方法的文章就介紹到這了,更多相關golang Socket.IO內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • golang連接MongoDB數(shù)據(jù)庫及數(shù)據(jù)庫操作指南

    golang連接MongoDB數(shù)據(jù)庫及數(shù)據(jù)庫操作指南

    MongoDB是Nosql中常用的一種數(shù)據(jù)庫,下面這篇文章主要給大家介紹了關于golang連接MongoDB數(shù)據(jù)庫及數(shù)據(jù)庫操作的相關資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2022-09-09
  • golang gorm中格式化時間問題詳解

    golang gorm中格式化時間問題詳解

    這篇文章主要給大家介紹了關于golang gorm中格式化時間問題的相關資料,文中通過示例代碼介紹的非常詳細,對大家學習或者使用golang具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧
    2019-07-07
  • Go語言中你不知道的Interface詳解

    Go語言中你不知道的Interface詳解

    對于go語言來說,設計最精妙的應該是interface了,直白點說interface是一組method的組合。下面這篇文章主要給大家介紹了關于Go語言中你不知道的Interface的相關資料,需要的朋友可以參考借鑒,下面來一起看看吧。
    2018-02-02
  • Golang中的信號(Signal)機制詳解

    Golang中的信號(Signal)機制詳解

    Signal 是一種操作系統(tǒng)級別的事件通知機制,進程可以響應特定的系統(tǒng)信號,這些信號用于指示進程執(zhí)行特定的操作,如程序終止、掛起、恢復等,Golang 的標準庫 os/signal 提供了對信號處理的支持,本文將詳細講解 Golang 是如何處理和響應系統(tǒng)信號的,需要的朋友可以參考下
    2024-01-01
  • 淺析Go語言中Channel的各種用法

    淺析Go語言中Channel的各種用法

    這篇文章主要帶大家一起來學習一下Go語言中的if語句,也就是大家口中的判斷語句。文中的示例代碼講解詳細,對我們學習Go語言有一定幫助,需要的可以參考一下
    2022-11-11
  • golang內(nèi)存對齊的項目實踐

    golang內(nèi)存對齊的項目實踐

    本文主要介紹了golang內(nèi)存對齊的項目實踐,內(nèi)存對齊不僅有助于提高內(nèi)存訪問效率,還確保了與硬件接口的兼容性,是Go語言編程中不可忽視的重要優(yōu)化手段,下面就來介紹一下
    2025-02-02
  • Go?Gin框架優(yōu)雅重啟和停止實現(xiàn)方法示例

    Go?Gin框架優(yōu)雅重啟和停止實現(xiàn)方法示例

    Web應用程序中,有時需要重啟或停止服務器,無論是因為更新代碼還是進行例行維護,這時需要保證應用程序的可用性和數(shù)據(jù)的一致性,就需要優(yōu)雅地關閉和重啟應用程序,即不丟失正在處理的請求和不拒絕新的請求,本文將詳解如何在Go語言中使用Gin這個框架實現(xiàn)優(yōu)雅的重啟停止
    2024-01-01
  • Go語言基于viper的conf庫進行配置文件解析

    Go語言基于viper的conf庫進行配置文件解析

    在現(xiàn)代軟件開發(fā)中,配置文件是不可或缺的一部分,如何高效地將這些格式解析到 Go 結構體中,一直是開發(fā)者的痛點,下面我們來看看如何使用conf進行配置文件解析吧
    2025-03-03
  • 解決go在函數(shù)退出后子協(xié)程的退出問題

    解決go在函數(shù)退出后子協(xié)程的退出問題

    這篇文章主要介紹了解決go在函數(shù)退出后子協(xié)程的退出問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-04-04
  • VS Code配置Go語言開發(fā)環(huán)境的詳細教程

    VS Code配置Go語言開發(fā)環(huán)境的詳細教程

    這篇文章主要介紹了VS Code配置Go語言開發(fā)環(huán)境的詳細教程,本文通過實例代碼圖文相結合的形式給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-05-05

最新評論