mego

package module
v0.0.0-...-6ed046f Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 7, 2018 License: MIT Imports: 21 Imported by: 0

README

 

Meet Go.

 

// WIP - 尚未完成 //

// WIP - 尚未完成 //

// WIP - 尚未完成 //

// WIP - 尚未完成 //

// WIP - 尚未完成 //

// WIP - 尚未完成 //

Mego

類似 Gin 用法,用以取代傳統 RESTful 溝通結構,並且以類 RPC 的方式以 MessagePack 將資料進行壓縮並透過 WebSocket 傳遞使資料更加輕量。同時亦支援分塊檔案上傳。

這是什麼?

煤果是一個由 Golang 所撰寫的前後端雙向溝通方式,這很適合用於聊天室、即時連線、單頁應用程式。目前僅支援前端 JavaScript 與後端 Golang 的溝通。

  • 可取代傳統 RESTful API。
  • 以 MessagePack 編碼資料與達到更輕量的傳遞。
  • 可雙向溝通與廣播以解決傳統僅單向溝通的障礙。
  • 檔案分塊上傳方式。
  • 支援中介軟體(Middleware)。
  • 可使用 ES7 Async/Await 處理前端的呼叫。
  • 友善的錯誤處理環境。

為什麼?

在部份時候傳統 RESTful API 確實能派上用場,但久而久之就會為了如何命名、遵循 REST 風格而產生困擾,例如網址必須是名詞而非動詞,登入必須是 GET /token 而非 POST /login,但使用 GET 傳遞機密資料極為不安全,因此只好更改為 POST /session 等,陷入如此地窘境。

且多個時候 RESTful API 都是單向,而非雙向。這造成了在即時連線、雙向互動上的溝通困擾,不得不使用 Comet、Long Polling 達到相關的要求,令 API 更加分散難以管理。

Mego 試圖以 WebSocket 解決雙向溝通和多數重複無用的 HTTP 標頭導致浪費頻寬的問題。Mego 同時亦支援透過 WebSocket 上傳檔案的功能。

檔案上傳與廣播

因為 Mego 是透過 WebSocket 進行溝通,這令你可以主動式廣播訊息至客戶端(讓你更友善地達成通知系統)。Mego 亦支援檔案上傳,同時也能夠透過最簡單的方式妥善地以分塊方式上傳大型檔案。

效能如何?

Mego 是基於 net/httpolahol/melody 的 WebSocket 框架作為基礎,並由 vmihailenco/msgpack 作為傳遞訊息的基本格式。

這裡有份簡略化的效能測試報表。

測試規格:
1.7 GHz Intel Core i7 (4650U)
8 GB 1600 MHz DDR3

索引

安裝方式

打開終端機並且透過 go get 安裝此套件即可。

$ go get github.com/TeaMeow/Mego

使用方式

Mego 的使用方式參考令人容易上手的 Gin 網站框架,令你撰寫 WebSocket 就像在撰寫普通的網站框架ㄧ樣容易。

Golang
import "github.com/TeaMeow/Mego"

func main() {
	// 初始化一個基本的 Mego 引擎。
	e := mego.Default()
	// 定義一個 GetUser 方法供客戶端呼叫。
	e.Register("GetUser", func(c *mego.Context) {
		// 回應 `{"username": "YamiOdymel"}` 資料。
		c.Respond(mego.H{
			"username": "YamiOdymel",
		})
	})
	// 執行引擎在埠口 5000 上。
	e.Run()
}
JavaScript
ws = new MegoClient('ws://localhost/')

ws.on('open', () => {
    ws.call('getUser').end().then(({result}) => {
        console.log(result.username) // 輸出:YamiOdymel
    })
})

初始化引擎

初始化一個 Mego 引擎才能夠開始新增可供客戶端呼叫的方法,建立一個引擎有兩種方法。

// 初始化一個帶有自動回復、紀錄中介軟體的基本引擎。
e := mego.Default()

// 初始化一個無預設中介軟體的引擎。
e := mego.New()

廣播與事件

由於 Mego 和傳統 HTTP 網站框架不同之處在於:Mego 透過 WebSocket 連線。這使你可以主動發送事件到客戶端,而不需要等待客戶端主動來發送請求。

一個事件可以有很多個頻道,類似一個「新訊息」事件可以發送到很多個「聊天室」。透過不同的頻道你可以避免不相關的事件廣播到其他人手中。

func main() {
	e := mego.Default()

	// 廣播一個 `UpdateApp` 事件給所有監聽 `Channel1` 頻道的客戶端,觸發其事件監聽函式。
	e.Emit("UpdateApp", "Channel1", nil)

	// 廣播一個 `UpdateApp` 事件給 `Channel1` 頻道並帶有指定的資料供客戶端讀取。
	e.Emit("UpdateApp", "Channel1", mego.H{
		"version": "1.0.0",
	})

	e.Run()
}
預設訂閱處理函式

在 Mego 中,預設允許客戶端訂閱任何事件與其頻道,透過 HandleSubscribe 能夠更改訂閱處理函式。此函式會接收所有來自客戶端的訂閱請求與事件和頻道名稱。當處理函式回傳 false 的時候即表示客戶端不被允許訂閱此事件與頻道。

如果你希望使用者訂閱事件的時候需要傳入認證資料,例如:聊天室密碼⋯等。那麼你就該回傳 false 否決所有的訂閱事件,並見下方說明採用「手動訂閱」方式。

func main() {
	e := mego.Default()

	// 更改預設的事件訂閱處理函式。
	e.HandleSubscribe(func(evt string, ch string, ctx *mego.Context) bool {
		fmt.Printf("客戶端訂閱了 %s 事件的 %s 頻道!", evt, ch)
		return true
	})

	e.Run()
}
手動訂閱

客戶端能夠自行訂閱指定的事件與頻道,但如果這不太安全,請透過 HandleSubscribe 將所有訂閱事件回傳 false 拒絕。

接著以 Register 建立新的方法供客戶端傳遞認證資料至此,並在此方法內以 Subscribe 手動將經過認證的客戶端加入至訂閱清單中。

func main() {
	e := mego.Default()

	// 建立一個會協助客戶端訂閱事件的方法。
	e.Register("SubscribeMyEvent", func(c *mego.Context) {
		// ... 認證邏輯 ...

		// 手動讓這個客戶端訂閱 `MyEvent` 事件中的 `MyChannel` 頻道。
		c.Subscribe("MyEvent", "MyChannel")
	})

	e.Run()
}
手動取消訂閱

透過 Unsubscribe 在伺服端將一個訂閱指定事件的客戶端從監聽清單上移除,此客戶將不再接收到指定事件。

func main() {
	e := mego.Default()

	e.Register("UnsubscribeMyEvent", func(c *mego.Context) {
		// 這個客戶端將會取消訂閱 `MyEvent` 事件中的 `MyChannel` 頻道。
		c.Unsubscribe("MyEvent", "MyChannel")
	})

	e.Run()
}
多數廣播

透過 Emit 會廣播指定事件給指定頻道的所有連線的客戶端,如果你希望廣播事件給指定頻道中的某個客戶端時,你可以透過 EmitMultiple 並傳入欲接收指定事件的客戶端階段達成。

func main() {
	e := mego.Default()

	// 對頻道 `Channel1` 內的 [0] 與 [1] 客戶端廣播 `UpdateApp` 事件,
	// 位於此頻道的其他客戶端不會接收到此事件。
	e.EmitMultiple("UpdateApp", "Channel1", nil, []*mego.Session{
		e.Sessions[0],
		e.Sessions[1],
	})

	e.Run()
}
過濾廣播

同時,透過 EmitFilter 可以遍歷所有連線的客戶端,找出他們的相關資料並以此為依據決定是否要廣播指定事件給他們。

func main() {
	e := mego.Default()

	// 過濾所有客戶端,僅有 ID 為 `0k3LbEjL` 且在 `Channel1` 內才能夠接收到 UpdateApp 事件。
	e.EmitFilter("UpdateApp", "Channel1", nil, func(s *mego.Session) bool {
		// 此函式會過濾、遍歷每個客戶端,如果此函式回傳 `true`,此客戶端則會接收到此事件。
		return s.ID == "0k3LbEjL"
	})

	e.Run()
}

映射資料與參數

欲要接收客戶端傳來的資料,透過 Bind 可以將資料映射到本地的建構體。如果資料是重要且必須的,可以透過 MustBind 來映射資料,並在錯誤發生時自動呼叫 panic 終止此請求。

// User 是一個使用者資料建構體。
type User struct {
	Username string
}

func main() {
	e := mego.Default()

	e.Register("CreateUser", func(c *mego.Context) {
		var u User

		// 將接收到的資料映射到本地的使用者資料建構體,這樣才能讀取其資料。
		if c.Bind(&u) == nil {
			fmt.Println(u.Username)
		}

		// 透過 `MustBind` 在映射錯誤時直接呼叫 `panic` 終止此請求繼續。
		c.MustBind(&u)
		fmt.Println(u.Username)
	})

	e.Run()
}
取得參數

當客戶端傳送來的不是資料,而是普通陣列時會被當作參數看待。參數可以讓你更快進行處理而不需映射。

透過 Param(index).Get() 取得指定索引的參數內容,亦有 GetIntGetString 等方便的資料型態快捷函式。

func main() {
	e := mego.Default()

	e.Register("Sum", func(c *mego.Context) {
		// 以正整數資料型態取得傳入的兩個參數。
		a := c.Param(0).GetInt()
		b := c.Param(1).GetInt()

		// 將兩個轉換成正整數的參數進行相加取得結果。
		fmt.Printf("A + B = %d", a+b)
	})

	e.Run()
}
存取階段資料

你可以透過將資料存放至階段中,在下次相同客戶端呼叫時進行存取。

同時,你也不需要在每次傳送請求時夾帶一長串的 Token 或使用者身份驗證字串。

因為當 Mego 在初始化連線時就會將客戶端傳入的資料保存於階段中供你存取。

func main() {
	e := mego.Default()

	e.Register("Sum", func(c *mego.Context) {
		// 取得客戶端初始化連線時所傳入的 `Token` 資料。
		c.Session.GetString("Token")

		// 在階段中保存名為 `Foo` 且值為 `Bar` 的內容,下次相同客戶端呼叫時可以進行存取。
		c.Session.Set("Foo", "Bar")
	})

	e.Run()
}

處理請求與回應

透過 Respond 正常回應一個客戶端的請求。而 RespondWithError 可以回傳一個錯誤發生的詳細資料用已告知客戶端發生了錯誤。

func main() {
	e := mego.Default()

	e.Register("CreateUser", func(c *mego.Context) {
		// 針對此請求,回傳一個指定的狀態碼與資料。
		c.Respond(mego.H{
			"message": "成功建立使用者!",
		})

		// 針對此請求,回傳一個錯誤相關資料與狀態碼,還有錯誤本身。
		c.RespondWithError(mego.StatusError, mego.H{
			"empty": "username",
		}, errors.New("使用者名稱不可為空。"))
	})

	e.Run()
}
指定客戶端廣播事件

在處理函式中使用上下文建構體的 Emit 可以僅對發送請求的客戶端進行指定的事件廣播。同時也可以透過上下文建構體內的 EmitOthers 來對此客戶端以外的所有其他人進行指定事件的廣播。

func main() {
	e := mego.Default()

	e.Register("CreateUser", func(c *mego.Context) {
		// 廣播 `UpdateApp` 事件到此請求客戶端所監聽的 `Channel1` 中。
		c.Emit("UpdateApp", "Channel1", nil)

		// 廣播 `UpdateApp` 事件到此請求客戶端以外「其他所有人」所監聽的 `Channel1` 中。
		c.EmitOthers("UpdateApp", "Channel1", nil)
	})

	e.Run()
}

中介軟體

透過中介軟體你可以很容易地集中管理一些函式,例如:請求驗證、連線紀錄、效能測量。簡單來說,中介軟體就是能夠在每個連線之前所執行的函式。

要謹記:在中介軟體中必須呼叫 Next 呼叫下一個中介軟體或函式,否則會無法進行下個動作。

func main() {
	e := mego.Default()

	// logMw 是一個會紀錄請求編號的紀錄中介軟體。
	logMw := func(c *mego.Context) {
		fmt.Printf("%s 已連線。", c.ID)
		// ... 紀錄邏輯 ...
		c.Next()
	}

	// authMw 是一個驗證請求者是否有權限的身份檢查中介軟體。
	authMw := func(c *mego.Context) {
		if c.Session.ID != "jn3Dl74eX" {
			// ... 驗證邏輯 ...
		}
		c.Next()
	}

	// 在 Mego 引擎中使用上述兩個全域中介軟體。
	e.Use(logMw, authMw)

	e.Run()
}
推遲執行與接續

Next 之後的程式會在其他中介軟體或處理函式執行完畢後反序執行,因此你可以透過這個特性測量一個請求到結束總共耗費了多少時間。

func main() {
	e := mego.Default()

	mw := func(c *mego.Context) {
		// 從連線開始的時間。
		start := time.Now()
		// 呼叫下一個中介軟體或執行處理函式。
		c.Next()
		// 取得執行完畢後的時間。
		end := time.Now()

		// 將開始與結束的時間相減,取得此請求所耗費的時間。
		fmt.Printf("此請求共花費了 %v 時間", end.Sub(start))
	}

	// 在 Mego 引擎中使用上述全域中介軟體。
	e.Use(mw)

	e.Run()
}
終止請求

如果連線有異常不希望繼續呼叫下一個中介軟體或處理函式,則需要透過 Abort 終止此請求。以 AbortWithRespond 可以回傳正常的資料與狀態碼。

AbortWithError 則會在終止的時候回傳狀態碼與錯誤的詳細資料。

func main() {
	e := mego.Default()

	mw := func(c *mego.Context) {
		if c.Session.ID != "jn3Dl74eX" {
			// 直接終止此請求的繼續,並停止呼叫接下來的中介軟體與處理函式。
			c.Abort()

			// 終止此請求並且回傳資料。客戶端並不會知道是錯誤發生,仍會依一般回應處理。
			c.AbortWithRespond(mego.H{
				"message": "嗨!雖然你不是 jn3Dl74eX 但我們還是很歡迎你!",
			})

			// 終止此請求並且回傳一個錯誤的資料與狀態碼和錯誤本體。
			c.AbortWithError(mego.StatusNoPermission, nil, errors.New("沒有相關權限可訪問。"))
		}
	}

	// 在 Mego 引擎中使用上述全域中介軟體。
	e.Use(mw)

	e.Run()
}
存放鍵值組

為了讓開發者更方便在不同中介軟體或處理函式中交換訊息,上下文建構體內建了可存放自訂值的鍵值組。透過 Set 存放指定的鍵值,而 Get 來取得指定的值。

如果有一個值是非常重要且必須的,透過 MustGet 來取得可以在找不到該值時自動呼叫 panic 終止此請求的繼續。

func main() {
	e := mego.Default()

	mw := func(c *mego.Context) {
		// 在上下文建構體中存入名為 `Foo` 的 `Bar` 值。
		c.Set("Foo", "Bar")
		// 呼叫下一個中介軟體或處理函式。
		c.Next()
	}

	mw2 := func(c *mego.Context) {
		// 檢查是否有 `Foo` 這個鍵名,若沒有則終止此請求繼續。
		if v, ok := c.Get("Foo"); !ok {
			c.Abort()
		}
		fmt.Println(v) // 輸出:Bar
	}

	// 在 Mego 引擎中使用上述兩個全域中介軟體。
	e.Use(mw, mw2)

	e.Run()
}

和參數ㄧ樣,鍵值組也有相關的資料型態輔助函式,如:GetStringGetInt

func main() {
	e := mego.Default()

	mw := func(c *mego.Context) {
		fmt.Println(c.GetString("Foo")) // 輸出:Bar

		// c.GetInt()
		// c.GetBool()
		// c.GetStringMap()
		// ...
	}

	e.Run()
}
內建中介軟體

Mego 有內建數個方便的中介軟體能夠讓你限制同時連線數,或使用內建的簡易記錄系統⋯等。

如果你使用 Default 建立了一個 Mego 引擎,該引擎則包含自動回復與請求紀錄中介軟體。

自動回復

單個方法發生 panic 時,Recovery 可以自動回復並在終端機顯示相關錯誤訊息供除錯。

此中介軟體能避免整個 Mego 引擎被強制關閉。

func main() {
	e := mego.New()
	e.Use(mego.Recovery())
}
請求紀錄

Logger 會在終端機即時顯示任何請求,方便開發者進行監控。

func main() {
	e := mego.New()
	e.Use(mego.Logger())
}
配額限制

如果你希望限制客戶端在單個方法的某個時間內僅能呼叫數次,透過 RateLimit 就能達成。

選項中的 Period 表示週期秒數,Limit 表示客戶端可在週期內呼叫幾次相同方法。

func main() {
	e := mego.Default()

	e.Register("CreateUser", mego.RateLimit(mego.RateLimitOption{
		Period: 1 * time.Hour,
		Limit: 100
	}), func(c *mego.Context) {
		// ...
	})

	e.Run()
}
同時請求數

為了避免某個方法特別繁忙,透過 RequestLimit 可以限制單個方法的最大同時連線數。

選項中的 Limit 表示單個方法最大僅能有幾個客戶端同時呼叫。

func main() {
	e := mego.Default()

	e.Register("CreateUser", mego.RequestLimit(mego.RequestLimitConfig{
		Limit: 1000
	}), func(c *mego.Context) {
		// ...
	})

	e.Run()
}

檔案上傳處理

Mego 能夠自動幫你處理透過 WebSocket 所上傳的檔案。

單一檔案

客戶端可以上傳多個且獨立的檔案。透過 GetFile 取得單一個檔案,需要傳遞一個檔案欄位的名稱至此函式。當沒有指定名稱時以第一個檔案為主,如果方法永遠只接收一個檔案,那麼就可以省略名稱。

如果檔案是必要的,那麼透過 MustGetFile 可以在沒有接收到檔案的情況下自動呼叫 panic 終止此請求。

func main() {
	e := mego.Default()

	e.Register("UploadPhoto", func(c *mego.Context) {
		// 透過 `GetFile` 取得客戶端上傳的 `Photo` 檔案。
		if file, err := c.GetFile("Photo"); err == nil {
			c.Respond(mego.H{
				"filename":  file.Name,      // 檔案原始名稱。
				"size":      file.Size,      // 檔案大小(位元組)。
				"extension": file.Extension, // 檔案副檔名(無符號)。
				"path":      file.Path,      // 檔案本地路徑。
			})
		}
	})

	e.Run()
}
多個檔案

一個檔案欄位可以擺放多個檔案,這會使其成為檔案陣列。透過 GetFiles 以切片的方式取得指定檔案欄位的多個檔案。同樣地,當這個函式沒有傳入指定檔案欄位名稱時,以第一個檔案欄位為主。

這個函式會回傳一個切片方便進行遍歷。如果有個檔案欄位是必須的,透過 MustGetFiles 來在沒有接收到檔案的情況下自動呼叫 panic 中止請求。

func main() {
	e := mego.Default()

	e.Register("UploadPhoto", func(c *mego.Context) {
		// 透過 `GetFiles` 取得客戶端上傳的多個檔案。
		if files, err := c.GetFiles("Photos"); err == nil {
			for _, file := range files {
				fmt.Println(file.Name) // 檔案原始名稱。
			}
		}
	})

	e.Run()
}
區塊上傳

如果客戶端中的檔案過大,區塊上傳便是最好的方法。你不需要在 Mego 特別設置,Mego 即會自動組合區塊。使用這個區塊上傳時方法只會接收到一個完整檔案與起初傳遞的資料。透過 GetFile 直接取得完整的檔案。

如果你希望能夠手動處理區塊,例如搭配 Amazon S3 的 Multi-part 將接收到的每個區塊都各自上傳至雲端時,請更改方法中的 ChunkHandler

一個自訂的區塊處理函式內部結構看起來應該要像這樣。

// 建立一個自訂的區塊處理函式。
myChunkHandler := func(c *mego.Context, raw *mego.RawFile, dest *mego.File) mego.ChunkStatus {
	// ... 區塊處理邏輯 ...
	// fmt.Println(raw.Binary)

	// 如果這個區塊是最後一塊的話。
	if raw.Last {
		// 將完成的資料保存到檔案建構體。
		dest.Name = "MyFile"
		dest.Size = 128691

		// 表示區塊處理完畢。
		return mego.ChunkDone
	}

	// 如果尚未完成則要求客戶端傳送下一塊。
	return mego.ChunkNext
}

照理來說 Mego 就能協助你處理區塊組合了,不過如果你像上述ㄧ樣建立了自訂的區塊組合函式,透過 HandleChunk 能夠覆蓋全域的預設區塊處理函式。透過修改方法中的 ChunkHandler 能夠獨立修改各個方法的區塊處理函式。

func main() {
	e := mego.Default()

	// 更改全域的區塊處理函式。
	e.HandleChunk(myChunkHandler)

	// 註冊一個接受檔案的方法供客戶端上傳檔案至此。
	e.Register("UploadVideo", func(c *mego.Context) {
		var u User

		// 取得已從區塊組成的完整檔案。
		file := c.MustGetFile()
		fmt.Println(file.Name)

		// 你仍可以將檔案夾帶的資料映射到本地建構體。
		c.MustBind(&u)
		fmt.Println(u.Username)
	})

	// 你也能獨立更改 `UploadVideo` 方法的區塊處理函式。
	e.Method["UploadVideo"].ChunkHandler = myChunkHandler

	e.Run()
}

斷開客戶端

欲要從伺服器斷開與指定客戶端的連線,請透過客戶端階段裡的 Disconnect 函式。

func main() {
	e := mego.Default()

	// 斷開客戶端 `HkBE9lebt` 與伺服器的連線。
	e.Sessions["HkBE9lebt"].Disconnect()

	// 或者你也不需要指名道姓⋯⋯。
	e.Register("CreateUser", func(c *mego.Context) {
		// 直接斷開發送此請求的客戶端連線。
		c.Session.Disconnect()
	})

	e.Run()
}

複製並使用於 Goroutine

當你要將上下文建構體(Context)傳入 Goroutine 使用時,你必須透過 Copy 複製一份上下文建構體,這個建構體不會指向原本的上下文建構體,如此一來能夠避免資料競爭、衝突問題。

func main() {
	e := mego.Default()

	e.Register("CreateUser", func(c *mego.Context) {
		// 複製一份目前的上下文建構體。
		copied := c.Copy()
		// 然後在 Goroutine 中使用這個複製體。
		go func() {
			time.Sleep(5 * time.Second)
			// ... 在這裡使用 copied 而非 c ...
		}()
	})

	e.Run()
}

錯誤處理

在中介軟體或函式中處理錯誤是非常簡單的一件事。透過 Error 存放或堆疊此請求所發生的所有錯誤,並能在最終一次讀取。

func main() {
	e := mego.Default()

	// 這是一個錯誤中介軟體,會不斷地在上下文建構體中塞入一堆錯誤。
	errMw := func(c *mego.Context) {
		// 透過 `Error` 能將錯誤訊息堆放置上下文建構體中,
		// 並在最終一次獲得所有錯誤資訊。
		c.Error(errors.New("這是超重要的錯誤訊息啊!"))
		c.Error(errors.New("世界要毀滅啦!"))

		c.Next()
	}

	// 在 Mego 引擎中使用上述全域中介軟體。
	e.Use(errMw)

	e.Register("CreateUser", func(c *mego.Context) {
		// 檢查上下文建構體裡是否有任何錯誤。若有則回傳錯誤訊息給客戶端。
		if len(c.Errors) != 0 {
			c.AbortWithError(mego.StatusError, nil, c.Errors[0].Err)
		}
	})

	e.Run()
}

結束

欲要結束整個 Mego 引擎,請使用 Close 函式。

e.Close()

客戶端

Mego 有附帶數個官方客戶端。

狀態碼

在 Mego 中有內建這些狀態碼,但令 Mego 優於傳統 RESTful API 之處在於你可以自訂你自己的狀態碼。狀態碼是由數字奠定,如果你想要自訂自己的狀態碼,請從 0 開始。

狀態碼 說明
StatusError 內部錯誤發生,可能是非預期的錯誤。
StatusFull 請求因為已滿而被拒絕,例如:好友清單已滿無法新增、聊天室人數已滿無法加入。
StatusExists 已經有相同的事物存在而被拒絕。
StatusInvalid 格式無效而被拒絕,通常是不符合表單驗證要求。
StatusNotFound 找不到指定資源。
StatusNotAuthorized 請求被拒。沒有驗證的身份,需要登入以進行驗證。
StatusNoPermission 已驗證身份,但沒有權限提出此請求因而被拒。
StatusUnimplemented 此功能尚未實作完成,如果呼叫了一個不存在的函式即會回傳此狀態。
StatusTooManyRequests 使用者在短時間內發送太多的請求,請稍後重試。
StatusResourceExhausted 預定給使用者的配額已經被消耗殆盡,例如可用次數、分配容量。
StatusBusy 伺服器正處於忙碌狀態,請稍候重試。

API 文件撰寫風格

由於不受傳統 RESTful 風格的拘束,你可以很輕易地就透過 Markdown 格式規劃出 Mego 的 API 文件。我們有現成的使用者 API 範例可供參考。

# 會員系統

與會員、使用者有關的 API。

## 建立會員 [createUser]

建立一個新的使用者並在之後可透過註冊時所使用的帳號與密碼進行登入。

+ 請求

    + 欄位
        + username (string!) - 帳號。
        + password (string!) - 密碼。
        + email (string!) - 電子郵件地址。
        + gender (int!)

            使用者的性別採用編號以節省資料空間並在未來有更大的彈性進行變動。0 為男性、1 為女性。

    + 內容

            {
                "username": "YamiOdymel",
                "password": "yami123456",
                "email": "yamiodymel@yami.io",
                "gender": 1
            }

Documentation

Index

Constants

View Source
const (
	// B 為 Byte。
	B = 1
	// KB 為 Kilobyte。
	KB = 1024 * B
	// MB 為 Megabyte。
	MB = 1024 * KB
	// GB 為 Gigabyte。
	GB = 1024 * MB
	// TB 為 Terabyte。
	TB = 1024 * GB
)
View Source
const (
	// StatusError 表示有內部錯誤發生。
	StatusError = -1000
	// StatusFull 表示此請求無法被接受,因為額度已滿。例如:使用者加入了一個已滿的聊天室、好友清單已滿。
	StatusFull = -1001
	// StatusExists 表示請求的事物已經存在,例如:重複的使用者名稱、電子郵件地址。
	StatusExists = -1002
	// StatusInvalid 表示此請求格式不正確。
	StatusInvalid = -1003
	// StatusNotFound 表示找不到請求的資源。
	StatusNotFound = -1004
	// StatusNotAuthorized 表示使用者需要登入才能進行此請求。
	StatusNotAuthorized = -1005
	// StatusNoPermission 表示使用者已登入但沒有相關權限執行此請求。
	StatusNoPermission = -1006
	// StatusUnimplemented 表示此功能尚未實作完成。
	StatusUnimplemented = -1007
	// StatusTooManyRequests 表示使用者近期發送太多請求,需稍後再試。
	StatusTooManyRequests = -1008
	// StatusResourceExhausted 表示使用者可用的額度已耗盡。
	StatusResourceExhausted = -1009
	// StatusBusy 表示伺服器正繁忙無法進行執行請求。
	StatusBusy = -1010
	// StatusFileRetry 表示檔案區塊發生錯誤,需要重新上傳相同區塊。
	StatusFileRetry = -1011
	// StatusFileEmpty 表示上傳的檔案、區塊是空的。
	StatusFileEmpty = -1012
	// StatusFileTooLarge 表示檔案過大無法上傳。
	StatusFileTooLarge = -1013
	// StatusTimeout 表示這個請求費時過久導致逾期而被終止。
	StatusTimeout = -1014
)

Variables

View Source
var (
	// ErrEventNotFound 表示欲發送的事件沒有被初始化或任何客戶端監聽而無法找到因此發送失敗。
	ErrEventNotFound = errors.New("mego: the event doesn't exist")
	// ErrChannelNotFound 表示欲發送的事件存在,但目標頻道沒有被初始化或任何客戶端監聽而無法找到因此發送失敗。
	ErrChannelNotFound = errors.New("mego: the channel doesn't exist")
	// ErrFileNotFound 表示欲取得的檔案並不存在,可能是客戶端上傳不完整。
	ErrFileNotFound = errors.New("mego: the file was not found")
	// ErrKeyNotFound 表示欲從鍵值組中取得的鍵名並不存在。
	ErrKeyNotFound = errors.New("mego: the key was not found")
	// ErrPanicRecovered 表示 Panic 發生了但已回復正常。
	ErrPanicRecovered = errors.New("mego: panic recovered")
)
View Source
var (
	// DefaultPort 是 Mego 引擎的預設埠口。
	DefaultPort = ":5000"
	// DefaultWriter 是預設的紀錄、資料寫入者。
	DefaultWriter io.Writer = os.Stdout
	// DefaultErrorWriter 是預設的錯誤資料寫入者。
	DefaultErrorWriter io.Writer = os.Stderr
)

Functions

This section is empty.

Types

type Channel

type Channel struct {
	// Name 是這個頻道的名稱。
	Name string
	// Sessions 是監聽此頻道的階段 ID 切片。
	Sessions []*Session
	// Event 是這個頻道的父事件。
	Event *Event
}

Channel 呈現了事件中的一個頻道與其監聽者。

func (*Channel) Destroy

func (c *Channel) Destroy()

Destroy 會摧毀一個頻道避免其階段接收到相關事件。

func (*Channel) Kick

func (c *Channel) Kick(id string)

Kick 會移除有註冊此頻道指定階段,避免繼續接收到相關事件。

type ChunkHandler

type ChunkHandler func(ctx *Context, raw *RawFile, dest *File) ChunkStatus

ChunkHandler 是區塊處理函式。

type ChunkStatus

type ChunkStatus int

ChunkStatus 是區塊處理結果狀態碼,用以讓 Mego 得知下一步該如何執行。

const (
	// ChunkNext 表示本次處理成功,請求下一個檔案區塊。
	ChunkNext ChunkStatus = iota
	// ChunkDone 表示所有區塊皆處理完畢,結束檔案處理。
	ChunkDone
	// ChunkAbort 表示不打算處理本檔案了,結束此檔案的處理手續並停止上傳。
	ChunkAbort
)

type Context

type Context struct {
	// Keys 存放透過 `Set` 儲存的鍵值組,僅限於單次請求。
	Keys map[string]interface{}
	// Errors 存放開發者自訂的錯誤,可用在中介軟體或處理函式中。
	Errors errorMsgs
	// Session 是產生此連線的客戶端階段建構體。
	Session *Session

	// ID 是本次請求的工作編號,用以讓客戶端呼叫相對應的處理函式。
	ID int
	// Request 是這個 WebSocket 的 HTTP 請求建構體。
	Request *http.Request
	// Method 是目前正執行的方法建構體。
	Method *Method
	// contains filtered or unexported fields
}

Context 是單次請求中的上下文建構體。

func (*Context) Abort

func (c *Context) Abort()

Abort 終止此次請求,避免繼續執行。

func (*Context) AbortWithError

func (c *Context) AbortWithError(code int, data interface{}, err error)

AbortWithError 結束此次請求,避免繼續執行。並以指定的狀態碼、錯誤資料與訊息回應特定的客戶端並表示錯誤發生。

func (*Context) AbortWithRespond

func (c *Context) AbortWithRespond(result interface{})

AbortWithRespond 終止此次請求,避免繼續執行。並以資料回應特定的客戶端。

func (*Context) Bind

func (c *Context) Bind(dest interface{}) error

Bind 能夠將接收到的資料映射到本地建構體。

func (*Context) ClientIP

func (c *Context) ClientIP() string

ClientIP 會盡所能地取得到最真實的客戶端 IP 位置。

func (*Context) Copy

func (c *Context) Copy() *Context

Copy 會複製一份 `Context` 供你在 Goroutine 中操作不會遇上資料競爭與衝突問題。

func (*Context) Emit

func (c *Context) Emit(event string, result interface{})

Emit 會向此客戶端廣播一個事件。

func (*Context) EmitOthers

func (c *Context) EmitOthers(event string, result interface{})

EmitOthers 會將帶有指定資料的事件向自己以外的所有人廣播。

func (*Context) Error

func (c *Context) Error(err error) *Context

Error 能夠將發生的錯誤保存到單次 Session 中。

func (*Context) Get

func (c *Context) Get(key string) (v interface{}, ok bool)

Get 會取得先前以 `Set` 存放在本次 Session 中的指定鍵值組。

func (*Context) GetBool

func (c *Context) GetBool(key string) (v bool)

GetBool 能夠以布林值取得指定的參數。

func (*Context) GetDuration

func (c *Context) GetDuration(key string) (v time.Duration)

GetDuration 能夠以時間長度取得指定的參數。

func (*Context) GetFile

func (c *Context) GetFile(name ...string) (*File, error)

GetFile 會回傳一個指定檔案欄位中的檔案。

func (*Context) GetFiles

func (c *Context) GetFiles(name ...string) ([]*File, error)

GetFiles 會取得指定檔案欄位中的全部檔案,並回傳一個檔案切片供開發者遍歷。

func (*Context) GetFloat64

func (c *Context) GetFloat64(key string) (v float64)

GetFloat64 能夠以浮點數取得指定的參數。

func (*Context) GetInt

func (c *Context) GetInt(key string) (v int)

GetInt 能夠以正整數取得指定的參數。

func (*Context) GetMapString

func (c *Context) GetMapString(key string) (v map[string]string)

GetMapString 能夠以 `map[string]string` 取得指定的參數。

func (*Context) GetString

func (c *Context) GetString(key string) (v string)

GetString 能夠以字串取得指定的參數。

func (*Context) GetStringMap

func (c *Context) GetStringMap(key string) (v map[string]interface{})

GetStringMap 能夠以 `map[string]interface{}` 取得指定的參數。

func (*Context) GetStringSlice

func (c *Context) GetStringSlice(key string) (v []string)

GetStringSlice 能夠以字串切片取得指定的參數。

func (*Context) GetTime

func (c *Context) GetTime(key string) (v time.Time)

GetTime 能夠以時間取得指定的參數。

func (*Context) IsAborted

func (c *Context) IsAborted() bool

IsAborted 會回傳一個此請求是否已被終止的布林值。

func (*Context) MustBind

func (c *Context) MustBind(dest interface{}) error

MustBind 和 `Bind` 相同,差異在於若映射失敗會呼叫 `panic` 並阻止此次請求繼續執行。

func (*Context) MustGet

func (c *Context) MustGet(key string) interface{}

MustGet 和 `Get` 相同,但沒有該鍵值組時會呼叫 `panic`。

func (*Context) MustGetFile

func (c *Context) MustGetFile(name ...string) *File

MustGetFile 會回傳一個指定檔案欄位中的檔案,並且在沒有該檔案的時候呼叫 `panic` 終止此請求。

func (*Context) MustGetFiles

func (c *Context) MustGetFiles(name ...string) []*File

MustGetFiles 會取得指定檔案欄位中的全部檔案,並回傳一個檔案切片供開發者遍歷。沒有該檔案欄位的時候會呼叫 `panic` 終止此請求。

func (*Context) Next

func (c *Context) Next()

Next 來呼叫下一個方法處理函式,常用於中介軟體中。

func (*Context) Param

func (c *Context) Param(indexes ...int) *Param

Param 能夠從參數陣列中透過指定索引取得特定的參數。

func (*Context) Respond

func (c *Context) Respond(result interface{})

Respond 會以指定的狀態碼、資料回應特定的客戶端。

func (*Context) RespondWithError

func (c *Context) RespondWithError(code int, data interface{}, err error)

RespondWithError 會以指定的狀態碼、錯誤資料與訊息回應特定的客戶端並表示錯誤發生。

func (*Context) Set

func (c *Context) Set(key string, value interface{})

Set 會在本次上下文建構體中存放指定的鍵值組內容,可供其他處理函式存取。

func (*Context) Subscribe

func (c *Context) Subscribe(event string, channel string) *Context

Subscribe 能將此客戶納入指定事件、頻道的監聽清單中,方能接收其事件。

func (*Context) Unsubscribe

func (c *Context) Unsubscribe(event string, channel string) *Context

Unsubscribe 會將此客戶端從指定的事件、頻道監聽清單中移除。

type Engine

type Engine struct {
	// Sessions 儲存了正在連線的所有階段。
	Sessions map[string]*Session
	// Events 儲存了所有可用的事件與其監聽的客戶端資料。
	Events map[string]*Event
	// Methods 是所有可用的方法切片。
	Methods map[string]*Method
	// Option 是這個引擎的設置。
	Option *EngineOption
	// contains filtered or unexported fields
}

Engine 是 Mego 最主要的引擎結構體。

func Default

func Default() *Engine

Default 會建立一個帶有 `Recovery` 和 `Logger` 中介軟體的 Mego 引擎。

func New

func New() *Engine

New 會建立一個新的 Mego 空白引擎。

func (*Engine) Close

func (e *Engine) Close() error

Close 會結束此引擎的服務。

func (*Engine) Emit

func (e *Engine) Emit(event string, channel string, result interface{}) error

Emit 會帶有指定資料並廣播指定事件與頻道,當頻道為空字串時則廣播到所有頻道。

func (*Engine) EmitFilter

func (e *Engine) EmitFilter(event string, channel string, payload interface{}, filter func(*Session) bool) error

EmitFilter 會以過濾函式來決定要將帶有指定資料的事件廣播給誰。 如果過濾函式回傳 `true` 則表示該客戶端會接收到該事件。

func (*Engine) EmitMultiple

func (e *Engine) EmitMultiple(event string, channel string, result interface{}, sessions []*Session) error

EmitMultiple 會將指定事件與資料向指定的客戶端切片進行廣播。

func (*Engine) Event

func (e *Engine) Event(name string)

Event 會建立一個新的事件,如此一來客戶端方能監聽。

func (*Engine) HandleChunk

func (e *Engine) HandleChunk(handler ChunkHandler) *Engine

HandleChunk 會更改預設的區塊處理函式,開發者可以傳入一個回呼函式並接收區塊內容。 回傳 `ChunkStatus` 來告訴 Mego 區塊的處理狀態如何。

func (*Engine) HandleSubscribe

func (e *Engine) HandleSubscribe(handler SubscribeHandler) *Engine

HandleSubscribe 會更改預設的事件訂閱檢查函式,開發者可傳入一個回呼函式並接收客戶端欲訂閱的事件與頻道和相關資料。 回傳一個 `false` 即表示客戶端的資格不符,將不納入訂閱清單中。該客戶端將無法接收到指定的事件。

func (*Engine) Len

func (e *Engine) Len() int

Len 會回傳目前有多少個連線數。

func (*Engine) NoMethod

func (e *Engine) NoMethod(handler ...HandlerFunc) *Engine

NoMethod 會在客戶端呼叫不存在方法時被執行。

func (*Engine) Register

func (e *Engine) Register(method string, handler ...HandlerFunc) *Method

Register 會註冊一個指定的方法,並且允許客戶端呼叫此方法觸發指定韓式。

func (*Engine) Run

func (e *Engine) Run(port ...string)

Run 會在指定的埠口執行 Mego 引擎。

func (*Engine) Use

func (e *Engine) Use(handlers ...HandlerFunc) *Engine

Use 會使用傳入的中介軟體作為全域使用。

type EngineOption

type EngineOption struct {
	// MaxSize 是這個方法允許接收的最大位元組(Bytes)。
	MaxSize int
	// MaxChunkSize 是這個方法允許的區塊最大位元組(Bytes)。
	MaxChunkSize int
	// MaxFileSize 是這個方法允許的檔案最大位元組(Bytes),會在每次接收區塊時結算總計大小,
	// 如果超過此大小則停止接收檔案。
	MaxFileSize int
	// MaxSessions 是引擎能容忍的最大階段連線數量。
	MaxSessions int
	// CheckInterval 是每隔幾秒進行一次階段是否仍存在的連線檢查,
	// 此為輕量檢查而非發送回應至客戶端。
	CheckInterval int
}

EngineOption 是引擎的選項設置。

type Error

type Error struct {
	// Err 是實際的錯誤資料。
	Err error
	// Meta 是這個錯誤的中繼資料,可傳遞至其他函式讀取運用。
	Meta interface{}
	// Type 是這個錯誤的種類,預設為 `ErrorTypePrivate`。
	Type ErrorType
}

Error 呈現了一個路由中發生的錯誤。

func (*Error) Error

func (e *Error) Error() string

Error 會回傳一個錯誤的代表訊息。

func (*Error) IsType

func (e *Error) IsType(flags ErrorType) bool

IsType 會表示此錯誤是否為指定的種類。

func (*Error) JSON

func (e *Error) JSON() interface{}

func (*Error) MarshalJSON

func (e *Error) MarshalJSON() ([]byte, error)

MarshalJSON implements the json.Marshaller interface.

func (*Error) SetMeta

func (e *Error) SetMeta(data interface{}) *Error

SetMeta 可以將自訂的資料保存至錯誤建構體中傳遞到其他地方進行運用。

type ErrorType

type ErrorType uint64

ErrorType 是錯誤種類。

const (
	// ErrorTypeBind 是 `Bind` 錯誤。
	ErrorTypeBind ErrorType = 1 << 63
	// ErrorTypePrivate 是建議僅供開發內部顯示的錯誤。
	ErrorTypePrivate ErrorType = 1 << 0
	// ErrorTypePublic 是可公開的錯誤。
	ErrorTypePublic ErrorType = 1 << 1
	// ErrorTypeAny 是任意、不限公開或較私密的錯誤。
	ErrorTypeAny ErrorType = 1<<64 - 1
)

type Event

type Event struct {
	// Name 是這個事件的名稱。
	Name string
	// Channels 是這個事件的所有頻道。
	Channels map[string]*Channel
	// contains filtered or unexported fields
}

Event 呈現了單一個事件。

func (*Event) Destroy

func (e *Event) Destroy()

Destroy 會摧毀一個事件和所有頻道避免其階段接收到相關事件。

type File

type File struct {
	// Name 為此檔案的原生名稱。
	Name string
	// Size 是這個檔案的總位元組大小。
	Size int
	// Extension 是這個檔案的副檔名。
	Extension string
	// Path 為此檔案上傳後的本地路徑。
	Path string
	// Keys 為此檔案的鍵值組,可供開發者存放自訂資料。
	Keys map[string]interface{}
}

File 呈現了一個接收的檔案資料。

func (*File) Move

func (f *File) Move(dest string) error

Move 會移動接收到的檔案到指定路徑。

func (*File) Remove

func (f *File) Remove() error

Remove 會移除這個檔案。

type H

type H map[string]interface{}

H 是常用的資料格式,簡單說就是 `map[string]interface{}` 的別名。

type HandlerFunc

type HandlerFunc func(*Context)

HandlerFunc 是方法處理函式的型態別名。

func Logger

func Logger() HandlerFunc

Logger 會回傳一個紀錄中介軟體,能夠簡略地紀錄每個請求的 IP 和日期與耗費時間。

func LoggerWithWriter

func LoggerWithWriter(out io.Writer) HandlerFunc

LoggerWithWriter 可以傳入自訂的 `io.Writer` 決定紀錄的輸出位置(如:`Stdout` 或檔案)。

func RateLimit

func RateLimit(conf RateLimitConfig) HandlerFunc

RateLimit 會回傳一個流量限制的中介軟體,可以限制單個階段在限時時間內能夠發出多少個請求。

func Recovery

func Recovery() HandlerFunc

Recovery 會回傳一個回復中介軟體, 這能在請求發生 `panic` 錯誤時自動回復並顯示相關錯誤訊息供除錯,而不會導致整個伺服器強制關閉。

func RecoveryWithWriter

func RecoveryWithWriter(out io.Writer) HandlerFunc

RecoveryWithWriter 可以傳入自訂的 `io.Writer` 決定回復紀錄的輸出位置(如:`Stdout` 或檔案)。

func RequestLimit

func RequestLimit(conf RequestLimitConfig) HandlerFunc

RequestLimit 會回傳一個能夠限制單個方法最大同時請求數的中介軟體。

type Method

type Method struct {
	// Name 是此方法的名稱。
	Name string
	// Handlers 是中介軟體與處理函式。
	Handlers []HandlerFunc
	// Option 是此方法的選項。
	Option *MethodOption
	// ChunkHandler 是本方法的區塊處理回呼函式。
	ChunkHandler ChunkHandler
}

Method 呈現了一個方法。

type MethodOption

type MethodOption struct {
	// MaxSize 是這個方法允許接收的最大位元組(Bytes)。此選項會覆蓋引擎設定。
	MaxSize int
	// MaxChunkSize 是這個方法允許的區塊最大位元組(Bytes)。此選項會覆蓋引擎設定。
	MaxChunkSize int
	// MaxFileSize 是這個方法允許的檔案最大位元組(Bytes),會在每次接收區塊時結算總計大小,
	// 如果超過此大小則停止接收檔案。此選項會覆蓋引擎設定。
	MaxFileSize int
}

MethodOption 是一個方法的選項。

type Param

type Param struct {
	// contains filtered or unexported fields
}

Param 代表著單一個參數。

func (*Param) Get

func (p *Param) Get() (v interface{})

Get 能夠以介面取得指定的參數。

func (*Param) GetBool

func (p *Param) GetBool() (v bool)

GetBool 能夠以布林值取得指定的參數。

func (*Param) GetDuration

func (p *Param) GetDuration() (v time.Duration)

GetDuration 能夠以時間長度取得指定的參數。

func (*Param) GetFloat64

func (p *Param) GetFloat64() (v float64)

GetFloat64 能夠以浮點數取得指定的參數。

func (*Param) GetInt

func (p *Param) GetInt() (v int)

GetInt 能夠以正整數取得指定的參數。

func (*Param) GetMapString

func (p *Param) GetMapString() (v map[string]string)

GetMapString 能夠以 `map[string]string` 取得指定的參數。

func (*Param) GetString

func (p *Param) GetString() (v string)

GetString 能夠以字串取得指定的參數。

func (*Param) GetStringMap

func (p *Param) GetStringMap() (v map[string]interface{})

GetStringMap 能夠以 `map[string]interface{}` 取得指定的參數。

func (*Param) GetStringSlice

func (p *Param) GetStringSlice() (v []string)

GetStringSlice 能夠以字串切片取得指定的參數。

func (*Param) GetTime

func (p *Param) GetTime() (v time.Time)

GetTime 能夠以時間取得指定的參數。

func (*Param) Len

func (p *Param) Len() int

Len 能夠取得參數的數量。

type RateLimitConfig

type RateLimitConfig struct {
	// Period 是計時的週期。
	Period int
	// Limit 表示單個階段在指定週期內僅能發送相同請求的數量。
	Limit int
}

RateLimitConfig 是用在流量限制的選項建構體。

type RawFile

type RawFile struct {
	// Binary 是檔案的二進制。
	Binary []byte `codec:"b" msgpack:"b"`
	// ID 是由客戶端替此檔案所產生的順序編號,用於區塊組合。
	ID int `codec:"i" msgpack:"i"`
	// Parts 呈現區塊的分塊進度。索引 0 表示總共區塊數,索引 1 則是本區塊編號。
	// 如果這個切片是空的表示此為實體檔案而非區塊。
	Parts []int `codec:"p" msgpack:"p"`
	// Name 是檔案的原始名稱。
	Name string `codec:"n" msgpack:"n"`
}

RawFile 是尚未轉化成為可供開發者使用之前的生檔案資料內容。

type Request

type Request struct {
	// Method 是欲呼叫的方法名稱。
	Method string `codec:"m" msgpack:"m"`
	// Files 是此請求所包含的檔案欄位與其內容。
	Files map[string][]*RawFile `codec:"f" msgpack:"f"`
	// Params 是資料或參數。
	Params interface{} `codec:"p" msgpack:"p"`
	// ID 為本次請求編號,若無則為單次通知廣播不需回應。
	ID int `codec:"i" msgpack:"i"`
}

Request 呈現了一個客戶端所傳送過來的請求內容。

type RequestLimitConfig

type RequestLimitConfig struct {
	// Limit 是指定方法最大的同時連線數。
	Limit int
}

RequestLimitConfig 是總請求限制的選項建構體。

type Response

type Response struct {
	// Event 是欲呼叫的客戶端事件名稱。
	Event string `codec:"v" msgpack:"v"`
	// Result 是正常回應時的資料酬載。
	Result interface{} `codec:"r" msgpack:"r"`
	// Error 是錯誤回應時的資料酬載,與 Result 兩者擇其一,不會同時使用。
	Error ResponseError `codec:"e" msgpack:"e"`
	// ID 是當時發送此請求的編號,用以讓客戶端比對是哪個請求所造成的回應。
	ID int `codec:"i" msgpack:"i"`
}

Response 呈現了 Mego 將會回應給客戶端的內容。

type ResponseError

type ResponseError struct {
	// Code 是錯誤代號。
	Code int `codec:"c" msgpack:"c"`
	// Message 是人類可讀的簡略錯誤訊息。
	Message string `codec:"m" msgpack:"m"`
	// Data 是本次錯誤的詳細資料。
	Data interface{} `codec:"d" msgpack:"d"`
}

ResponseError 是回應錯誤資料建構體。

type Session

type Session struct {
	// Keys 包含了發送此請求的客戶端初始連線資料,此資料由客戶端連線時自訂。可用以取得用戶身份和相關資料。
	// 此欄位亦能存放伺服端設置的鍵值組。
	Keys map[string]interface{}
	// ID 是此客戶端初始化時由伺服端所建立的不重複隨機名稱,供辨識匿名身份用。
	ID string
	// contains filtered or unexported fields
}

Session 是接收請求時的關聯內容,其包含了指向到特定客戶端的函式。

func (*Session) Copy

func (s *Session) Copy() *Session

Copy 會複製一份 `Session` 供你在 Goroutine 中操作不會遇上資料競爭與衝突問題。

func (*Session) Disconnect

func (s *Session) Disconnect() error

Disconnect 會結束掉這個階段的連線。

func (*Session) Get

func (s *Session) Get(name string) (v interface{}, ok bool)

Get 會取得客戶端當初建立連線時所傳入的資料特定鍵值組。

func (*Session) GetBool

func (s *Session) GetBool(key string) (v bool)

GetBool 能夠以布林值取得指定的參數。

func (*Session) GetDuration

func (s *Session) GetDuration(key string) (v time.Duration)

GetDuration 能夠以時間長度取得指定的參數。

func (*Session) GetFloat64

func (s *Session) GetFloat64(key string) (v float64)

GetFloat64 能夠以浮點數取得指定的參數。

func (*Session) GetInt

func (s *Session) GetInt(key string) (v int)

GetInt 能夠以正整數取得指定的參數。

func (*Session) GetMapString

func (s *Session) GetMapString(key string) (v map[string]string)

GetMapString 能夠以 `map[string]string` 取得指定的參數。

func (*Session) GetString

func (s *Session) GetString(key string) (v string)

GetString 能夠以字串取得指定的參數。

func (*Session) GetStringMap

func (s *Session) GetStringMap(key string) (v map[string]interface{})

GetStringMap 能夠以 `map[string]interface{}` 取得指定的參數。

func (*Session) GetStringSlice

func (s *Session) GetStringSlice(key string) (v []string)

GetStringSlice 能夠以字串切片取得指定的參數。

func (*Session) GetTime

func (s *Session) GetTime(key string) (v time.Time)

GetTime 能夠以時間取得指定的參數。

func (*Session) Set

func (s *Session) Set(key string, value interface{})

Set 會在本次的 Session 中存放指定的鍵值組內容,可供下次相同客戶端呼叫時存取。

type SubscribeHandler

type SubscribeHandler func(evt string, ch string, ctx *Context) bool

SubscribeHandler 是訂閱事件處理函式。

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL