Dalam beberapa tahun kebelakangan ini, komunikasi masa nyata telah menjadi keperluan asas. WebSocket ialah peneraju dalam komunikasi masa nyata Ia boleh merealisasikan komunikasi masa nyata antara pelanggan dan pelayan dengan lebih cepat dan berkesan. Bahasa Go juga telah menjadi bahasa yang popular sejak beberapa tahun kebelakangan ini dan digunakan secara meluas dalam komunikasi masa nyata. Mengambil kesempatan daripada kelebihan bahasa Go dan ciri pemprosesan berbilang benang, fungsi komunikasi Websocket dapat direalisasikan dengan lebih cekap dan stabil.
Artikel ini akan memfokuskan pada bahasa Go dan memperkenalkan cara menggunakannya untuk melaksanakan komunikasi Websocket berbilang benang, termasuk beberapa pelaksanaan fungsi penting, dan akan memberikan contoh kod terperinci.
Sebelum menggunakan bahasa Go untuk melaksanakan komunikasi Websocket, anda perlu memahami beberapa pengetahuan asas komunikasi Websocket. Websocket, seperti HTTP, ialah protokol rangkaian berdasarkan TCP. Tetapi perbezaannya ialah ia bukan mod permintaan dan tindak balas, tetapi sambungan berterusan antara pelanggan dan pelayan, membolehkan komunikasi masa nyata antara kedua-dua pihak.
Dalam bahasa Go, langkah pertama untuk melaksanakan komunikasi Websocket ialah mengimport pakej "net/http" dan "github.com/gorilla/websocket". Antaranya, "net/http" digunakan untuk mencipta pelayan HTTP, dan "github.com/gorilla/websocket" ialah pakej pihak ketiga untuk Websocket. Jika pakej ini tidak tersedia, anda boleh menggunakan arahan "go get" untuk memasangnya.
import ( "fmt" "net/http" "github.com/gorilla/websocket" )
Gunakan kaedah "http.HandleFunc()" untuk mewujudkan sambungan Websocket dalam bahasa Go, seperti yang ditunjukkan di bawah:
func main() { http.HandleFunc("/", handleConnections) http.ListenAndServe(":4000", nil) }
Kod di atas menggunakan kaedah "http.HandleFunc()" untuk mencipta sambungan bernama fungsi pemprosesan " handleConnections", yang bertanggungjawab untuk mewujudkan sambungan Websocket. Seperti yang anda lihat, laluan permintaan untuk mewujudkan sambungan Websocket ialah "/", yang merupakan direktori akar.
Selepas mewujudkan sambungan Websocket, anda perlu mengkonfigurasi beberapa parameter asas untuk permintaan sambungan, seperti peningkatan protokol, saiz penimbal baca dan tulis, tamat masa degupan jantung, dsb.
var upgrader = websocket.Upgrader{ ReadBufferSize: 1024, WriteBufferSize: 1024, CheckOrigin: func(r *http.Request) bool { return true }, }
Kod di atas dikonfigurasikan menggunakan "websocket.Upgrader", di mana "ReadBufferSize" dan "WriteBufferSize" menentukan saiz penimbal baca dan tulis, dan "CheckOrigin" ditetapkan kepada "true", menunjukkan bahawa semua permintaan akses sumber diterima. Jika sumber tertentu diperlukan, ia boleh ditetapkan mengikut keperluan khusus.
Selepas permintaan sambungan Websocket diproses, jabat tangan protokol Websocket standard perlu diikuti untuk naik taraf protokol. Dalam bahasa Go, naik taraf protokol boleh menggunakan Penaik taraf untuk melakukan jabat tangan protokol dan pemegang sambungan kembali (sambungan) Pemegang sambungan boleh digunakan untuk menghantar dan menerima mesej semasa kitaran hayat sambungan Websocket.
func handleConnections(w http.ResponseWriter, r *http.Request) { // 通过Upgrader进行协议升级 ws, err := upgrader.Upgrade(w, r, nil) if err != nil { fmt.Println(err) } // 若协议升级成功,则跳转到另一个处理函数处理消息 go handleMessages(ws) }
Dalam fungsi handleConnections, protokol pertama kali dinaik taraf melalui Penaik taraf. Jika peningkatan berjaya, panggil "go handleMessages(ws)" untuk memulakan goroutine untuk mula memproses mesej Websocket.
Langkah seterusnya ialah memproses mesej Websocket. Dalam bahasa Go, anda boleh menggunakan gelung tak terhingga untuk memantau ketibaan mesej Websocket, dan kemudian memproses setiap mesej dengan sewajarnya.
func handleMessages(ws *websocket.Conn) { for { messageType, p, err := ws.ReadMessage() if err != nil { fmt.Println(err) return } // 根据消息类型进行处理 switch messageType { case websocket.TextMessage: // 处理text类型消息 fmt.Println(string(p)) case websocket.BinaryMessage: // 处理binary类型消息 fmt.Println(p) } } }
Dalam fungsi handleMessages, mula-mula gunakan kaedah "ws.ReadMessage()" untuk membaca mesej Websocket dan memprosesnya mengikut jenis mesej.
Bahagian terakhir ialah bahagian penghantaran mesej Websocket. Dalam bahasa Go, anda boleh menggunakan pemegang sambungan Websocket "ws" untuk menghantar data kepada klien.
func sendMessage(ws *websocket.Conn, messageType int, message []byte) error { if err := ws.WriteMessage(messageType, message); err != nil { return err } return nil }
Dalam fungsi sendMessage, mula-mula hantar mesej kepada klien melalui kaedah "ws.WriteMessage()".
Untuk meningkatkan kecekapan komunikasi Websocket, pelbagai benang perlu digunakan untuk memproses mesej Websocket. Dalam bahasa Go, anda boleh menggunakan goroutine untuk melaksanakan pemprosesan serentak.
Dalam bahasa Go, memulakan goroutine adalah sangat mudah, cuma tambah "go" sebelum fungsi.
go handleMessages(ws)
Dalam pembangunan sebenar, Websocket biasanya perlu melaksanakan mesej siaran, iaitu menghantar mesej kepada semua pelanggan yang bersambung. Dalam bahasa Go, anda boleh menggunakan peta untuk menyimpan semua pelanggan yang disambungkan, kemudian melintasi dan menghantar mesej kepada setiap pelanggan secara bergilir-gilir.
var clients = make(map[*websocket.Conn]bool) // 所有连接的客户端 var broadcast = make(chan []byte) // 广播通道 func main() { http.HandleFunc("/", handleConnections) go handleMessages() http.ListenAndServe(":4000", nil) } func handleConnections(w http.ResponseWriter, r *http.Request) { // 通过Upgrader进行协议升级 ws, err := upgrader.Upgrade(w, r, nil) if err != nil { fmt.Println(err) } // 若协议升级成功,则将客户端存入map clients[ws] = true } func handleMessages() { for { // 从广播通道中获取消息 message := <- broadcast // 对所有连接的客户端发送消息 for client := range clients { if err := client.WriteMessage(websocket.TextMessage, message); err != nil { fmt.Println(err) delete(clients, client) return } } } }
Dalam kod di atas, saluran siaran (siaran) dilaksanakan untuk memproses mesej siaran. Pada masa yang sama, peta (pelanggan) dicipta untuk menyimpan semua pelanggan yang bersambung. Dalam fungsi handleConnections, apabila pelanggan baharu menyambung, ia akan disimpan dalam klien. Dalam fungsi handleMessages, saluran siaran mendapat mesej baharu daripadanya dan menghantarnya kepada semua pelanggan yang disambungkan.
Semasa multi-threading memproses mesej Websocket, adalah perlu untuk memastikan keselamatan serentak data. Dalam bahasa Go, anda boleh menggunakan kunci untuk kawalan keselamatan serentak. Dalam kod sampel artikel ini, "sync.RWMutex" digunakan untuk melaksanakan kunci baca-tulis untuk memastikan keselamatan serentak.
var mutex = &sync.RWMutex{} func handleConnections(w http.ResponseWriter, r *http.Request) { // 通过Upgrader进行协议升级 ws, err := upgrader.Upgrade(w, r, nil) if err != nil { fmt.Println(err) } // 若协议升级成功,则将客户端存入map,并进行锁定 mutex.Lock() clients[ws] = true mutex.Unlock() } func handleMessages() { for { // 从广播通道中获取消息,并加锁 message := <- broadcast mutex.Lock() for client := range clients { if err := client.WriteMessage(websocket.TextMessage, message); err != nil { fmt.Println(err) client.Close() delete(clients, client) } } mutex.Unlock() } }
Dalam fungsi handleConnections, selepas sambungan berjaya, pelanggan ditambahkan pada peta dan dikunci. Dalam fungsi handleMessages, kunci sebelum memproses mesej baharu untuk memastikan keselamatan data.
Ringkasnya, menggunakan bahasa Go untuk melaksanakan komunikasi Websocket berbilang benang boleh meningkatkan kecekapan dan kestabilan komunikasi Websocket, dan boleh melaksanakan mesej siaran dengan mudah. Dalam amalan, fungsi yang lebih kompleks boleh dilaksanakan mengikut keperluan khusus.
Atas ialah kandungan terperinci Cara melaksanakan komunikasi Websocket berbilang benang menggunakan bahasa Go. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!