0x01。Package

Http 框架:gin-gonic/gin

Websocket 框架:olahol/melody (在 gorilla/websocket 上封裝的一個庫,更易使用)

0x02。Getting Start

Melody example: chatting

Chat

package

main

import

“github。com/gin-gonic/gin”

“gopkg。in/olahol/melody。v1”

“fmt”

“sync”

//連線數

var

counter

int

=

0

//讀寫鎖

var

mutex

sync

RWMutex

//房間和連線的對應關係

var

sm

map

*

melody

Session

string

=

make

map

*

melody

Session

string

//發生錯誤時的channel

var

CloseChan

chan

*

melody

Session

=

make

chan

*

melody

Session

100

func

main

()

{

//建立gin例項和melody例項

r

:=

gin

Default

()

m

:=

melody

New

()

//返回客戶端頁面

r

GET

“/”

func

c

*

gin

Context

{

c

File

“index。html”

})

//ws握手鍊接

r

GET

“/ws”

func

c

*

gin

Context

{

//這裡進行協議升級升級

m

HandleRequest

c

Writer

c

Request

})

//訪問這個網頁傳入一個room的query 就會向room房間的所有連結傳送訊息

//這裡可以理解為一個rpc呼叫之類的,這裡簡單實用http進行觸發

r

GET

“/call”

func

c

*

gin

Context

{

room

:=

c

Query

“room”

// 這個房間所有的連結切片

targets

:=

make

([]

*

melody

Session

0

//讀取資料使用讀鎖

mutex

RLock

()

for

s

m

:=

range

sm

{

if

m

==

room

{

targets

=

append

targets

s

}

}

mutex

RUnlock

()

for

_

s

:=

range

targets

{

go

func

s

*

melody

Session

{

//

if

err

:=

s

Write

([]

byte

“123”

));

err

!=

nil

{

//發生錯誤就往CloseChan扔資料

CloseChan

<-

s

}

}(

s

}

c

JSON

200

gin

H

{

“ret”

0

“msg”

“success”

})

})

//websocket連線狀態的路由

r

GET

“/health”

func

c

*

gin

Context

{

list

:=

make

([]

string

0

mutex

Lock

()

for

_

room

:=

range

sm

{

list

=

append

list

room

}

mutex

Unlock

()

c

JSON

200

gin

H

{

“list”

list

“counter”

counter

//自己記錄的連結數

“len”

m

Len

(),

//melody記錄的連線數

})

})

//處理websocket連線進入時的操作

//s *melody。Session s就是服務端和客戶端的連線物件

m

HandleConnect

func

s

*

melody

Session

{

fmt

Print

“Connect”

//在index。html的握手地址傳入的query,用來區分房間資訊,這樣就可以將session透過room進行分組

//s。Request就是握手是傳入的Request

var

room

string

=

s

Request

FormValue

“room”

// 因為這個是併發的操作所以需要讀寫鎖

mutex

Lock

()

counter

++

sm

s

=

room

mutex

Unlock

()

})

//收到訊息回撥的事件

m

HandleMessage

func

s

*

melody

Session

msg

[]

byte

{

fmt

Println

“Message”

//將收到的資料廣播給所有連結

//m有很多廣播相關的方法,如廣播給出了自己的其他人

m

Broadcast

msg

})

m

HandleDisconnect

func

s

*

melody

Session

{

fmt

Println

“Disconnect”

CloseChan

<-

s

})

//這裡啟動一個協程 進行房間和連結對應關心的維護

go

func

()

{

for

{

select

{

case

s

:=

<-

CloseChan

go

func

()

{

if

s

IsClosed

()

{

s

Close

()

}

mutex

Lock

()

counter

——

delete

sm

s

mutex

Unlock

()

}()

}

}

}()

r

Run

“:5000”

}

可以透過訪問health得到連線資訊

Go搭建Websocket訊息推送服務

0x03。Summary

透過上述例子可以,可以簡單的瞭解 websocket 的使用。透過維護連線 session 和 room的對印關係就實現了一個組聊的功能,這裡是維護的是一個map。當然也可以封裝成Struct維護房間和連線的關係,來實現組聊,私聊的功能。

curl

http://

localhost:5000/call?

room=CATCH_100024

來實現想房間中的人傳送訊息,這裡就可以理解為一個http的rpc呼叫,當然也可以透過其他的方式觸發這個事件。