Golangはwebsocket通信、gorilla/websocketを使用
4316 ワード
ケース:gorilla/websocketを使用してチャットルーム機能を実現
目次:
1、構想分析
2、コアコード
3、すべてのコード
4、テストコード
5、連絡して
一、構想分析
Websocketはhttpのアップグレードバージョンと理解すればよい
すべてのユーザをオブジェクトUserとして抽象化し、Userには1つの接続と1つのメッセージチャネルを含むべきである.
データプロセッサHub:あるユーザに送信されたデータを取得して各ユーザにプッシュする
二、実現&コアコード
Userの定義:
データ・プロセッサの定義:
データプロセッサの処理方法:
Websocketプロモーターを定義するには、次の手順に従います.
ユーザーがサービスに接続するコールバック関数:ユーザーの読み書き操作を処理する
イニシエータ:
三、完全なコード、1つのserver.goファイル、情況によって自分で分割することができます
四、テストコード、goで作成した1つのクライアントを使用して、複数のユーザーをシミュレートする
五、作者接続方式:QQ 535495438
目次:
1、構想分析
2、コアコード
3、すべてのコード
4、テストコード
5、連絡して
一、構想分析
Websocketはhttpのアップグレードバージョンと理解すればよい
すべてのユーザをオブジェクトUserとして抽象化し、Userには1つの接続と1つのメッセージチャネルを含むべきである.
データプロセッサHub:あるユーザに送信されたデータを取得して各ユーザにプッシュする
二、実現&コアコード
Userの定義:
type User struct {
conn *websocket.Conn
msg chan []byte
}
データ・プロセッサの定義:
type Hub struct {
// ,
userList map[*User]bool
// chan, chan
register chan *User
// chan, chan , map
unregister chan *User
// ,
broadcast chan []byte
}
データプロセッサの処理方法:
//
func (h *Hub) run() {
for {
select {
// chan
case user :=
Websocketプロモーターを定義するには、次の手順に従います.
// , http websocket
var up = &websocket.Upgrader{
//
WriteBufferSize: 1024,
ReadBufferSize: 1024,
//
CheckOrigin: func(r *http.Request) bool {
// get ,
if r.Method != "GET" {
fmt.Println(" ")
return false
}
// chat,
if r.URL.Path != "/chat" {
fmt.Println(" ")
return false
}
//
return true
},
}
ユーザーがサービスに接続するコールバック関数:ユーザーの読み書き操作を処理する
func wsHandle(w http.ResponseWriter, r *http.Request) {
//
conn, err := up.Upgrade(w, r, nil)
if err != nil {
fmt.Println(" :", err)
return
}
//
user := &User{
conn: conn,
msg: make(chan []byte),
}
hub.register
イニシエータ:
func main() {
//
go hub.run()
http.HandleFunc("/chat", wsHandle) // chat wshandle
http.ListenAndServe("127.0.0.1:8888", nil) //
}
三、完全なコード、1つのserver.goファイル、情況によって自分で分割することができます
package main
import (
"fmt"
"github.com/gorilla/websocket"
"net/http"
)
func main() {
//
go hub.run()
http.HandleFunc("/chat", wsHandle) // chat wshandle
http.ListenAndServe("127.0.0.1:8888", nil) //
}
// websocket ,
type Hub struct {
// ,
userList map[*User]bool
// chan, chan
register chan *User
// chan, chan , map
unregister chan *User
// ,
broadcast chan []byte
}
// websocket ,
type User struct {
conn *websocket.Conn
msg chan []byte
}
// , http websocket
var up = &websocket.Upgrader{
//
WriteBufferSize: 1024,
ReadBufferSize: 1024,
//
CheckOrigin: func(r *http.Request) bool {
// get ,
if r.Method != "GET" {
fmt.Println(" ")
return false
}
// chat,
if r.URL.Path != "/chat" {
fmt.Println(" ")
return false
}
//
return true
},
}
// ,
var hub = &Hub{
userList: make(map[*User]bool),
register: make(chan *User),
unregister: make(chan *User),
broadcast: make(chan []byte),
}
func wsHandle(w http.ResponseWriter, r *http.Request) {
//
conn, err := up.Upgrade(w, r, nil)
if err != nil {
fmt.Println(" :", err)
return
}
//
user := &User{
conn: conn,
msg: make(chan []byte),
}
hub.register
四、テストコード、goで作成した1つのクライアントを使用して、複数のユーザーをシミュレートする
package main
import (
"bufio"
"fmt"
"github.com/gorilla/websocket"
"io"
"os"
"sync"
)
var wg sync.WaitGroup
func main() {
conn, _, err := websocket.DefaultDialer.Dial("ws://127.0.0.1:8888/chat", nil)
if err != nil {
fmt.Println(" :", err)
}
wg.Add(2)
go read(conn)
go writeM(conn)
wg.Wait()
}
func read(conn *websocket.Conn) {
defer wg.Done()
for {
_, msg, err := conn.ReadMessage()
if err != nil {
fmt.Println(" :", err)
break
}
if err == io.EOF {
continue
}
fmt.Println(" :", string(msg))
}
}
func writeM(conn *websocket.Conn) {
defer wg.Done()
for {
fmt.Print(" :")
reader := bufio.NewReader(os.Stdin)
data, _ := reader.ReadString('
')
conn.WriteMessage(1, []byte(data))
}
}
五、作者接続方式:QQ 535495438