


Bagaimana untuk mendaftar sambungan websocket baharu dengan gooptic
editor php Yuzai akan memperkenalkan anda cara mendaftar sambungan soket web baharu dengan gooptic. GoOptic ialah perpustakaan soket web bahasa Go sumber terbuka untuk membina aplikasi komunikasi masa nyata berprestasi tinggi. Untuk mendaftarkan sambungan websoket baharu, anda perlu mengimport pustaka GoOptic dalam program Go anda terlebih dahulu. Anda kemudiannya boleh menggunakan fungsi yang disediakan oleh GoOptic untuk mencipta pelayan soket web dan menentukan alamat dan port untuk mendengar. Seterusnya, anda boleh menggunakan fungsi HandleFunc yang disediakan oleh GoOptic untuk mengendalikan pelbagai acara sambungan soket web, seperti menerima mesej, menghantar mesej, dsb. Akhir sekali, panggil fungsi Serve yang disediakan oleh GoOptic untuk memulakan pelayan soket web supaya ia boleh menerima sambungan baharu. Dengan langkah-langkah ini, anda boleh berjaya mendaftarkan sambungan soket web baharu dengan gooptic.
Kandungan soalan
Saya cuba menyediakan pelayan soket web mudah yang sepatutnya menyampaikan beberapa kandungan kepada pelanggan pada selang masa yang tidak diketahui.
Kod saya pada masa ini kelihatan seperti ini:
router.go
func setuproutes(app *fiber.app) error { app.get("/whop/validate", handler.handlewhopvalidate) /*other non-websocket routes*/ /*...*/ app.get("/ws/monitor", websocket.new(wshandler.handlewsmonitor)) app.use(func(c *fiber.ctx) error { c.sendstatus(404) return c.next() }) return nil }
pengendali.go
package handlers import ( "fmt" "log" "github.com/gofiber/websocket/v2" ) var register = make(chan *websocket.conn) var unregister = make(chan *websocket.conn) func handlewsmonitor(c *websocket.conn) { go socketlistener() defer func() { unregister <- c //may need to check whether connection is already closed before re-closing? c.close() }() //sends conn into channel register <- c for { messagetype, message, err := c.readmessage() if err != nil { if websocket.isunexpectedcloseerror(err, websocket.closegoingaway, websocket.closeabnormalclosure) { log.println("read error:", err) } return } if messagetype == websocket.textmessage { log.println("got textmessage:", string(message)) } else { log.println("received message of type:", messagetype) } } } func socketlistener() { for { select { case c := <-register: messagetype, message, err := c.readmessage() if err != nil { log.println(err) unregister <- c return } fmt.printf("got message of type: %d\nmessage:%s\n", messagetype, string(message)) fmt.printf("connection params: %s\n", c.params("id")) //append to list of co case c := <-unregister: //remove conection from list of clients c.close() fmt.printf("closed connection\n") } } }
Masalah yang saya hadapi ialah apabila saya menyambung ke websocket kes pilihan pendaftaran saya hilang (saya ingin mendaftar sambungan klien ke peta menggunakan uuid yang saya berikan kepada pelanggan tadi) .
client.go
package main import ( "flag" "log" "net/url" "github.com/fasthttp/websocket" ) type Client struct { C *websocket.Conn } func main() { addr := flag.String("addr", "localhost:8080", "http service address") u := url.URL{ Scheme: "ws", Host: *addr, Path: "/ws/monitor", RawQuery: "id=12", } wsClient := &Client{} log.Printf("connecting to %s\n", u.String()) // Connect to the WebSocket server conn, resp, err := websocket.DefaultDialer.Dial(u.String(), nil) if err != nil { log.Fatal("Dial:", err) } wsClient.C = conn if resp != nil { log.Println("Got response:", resp) } defer wsClient.closeConn() } func (client *Client) closeConn() { err := client.C.WriteMessage( websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, ""), ) if err != nil { log.Println("Write close:", err) return } client.C.Close() log.Println("Connection closed") }
handler.go atau patutkah saya mengambil pendekatan berbeza apabila menggunakan klien untuk menyambung ke pelayan?
Penyelesaian
Menurut ujian saya, kes pilihan daftar memang terkena (kod yang saya gunakan dilampirkan di bahagian bawah jawapan ini).
Tetapi saya menemui isu lain dalam kod:
-
Kebuntuan berlaku antara
unregister
chan 是无缓冲的,socketlistener
中的unregister <- c
将被阻塞。当代码到达unregister <- c
时,它和case c := <-unregister
.- Nampaknya kami hanya memerlukan satu
socketlistener
goroutine。如果是这种情况,应将其移至handlewsmonitor
untuk keseluruhan pelayan. handlewsmonitor
和socketlistener
都从连接中读取。socketlistener
Apakah tanggungjawab anda? Nampaknya ia tidak sepatutnya dibaca dari sambungan.
Difikirkan semula, nampaknya ia boleh dipadam sepenuhnya terus dalam handlewsmonitor
中的地图上添加连接和删除连接。 socketlistener
. Kesederhanaan harus menjadi matlamat utama reka bentuk. Lihat prinsip ciuman.
package main import ( "log" "github.com/gofiber/fiber/v2" "github.com/gofiber/websocket/v2" ) var ( register = make(chan *websocket.Conn) unregister = make(chan *websocket.Conn) ) func main() { // Make it easy to find out which line prints the log. log.SetFlags(log.Lshortfile) app := fiber.New() app.Get("/ws/monitor", websocket.New(HandleWsMonitor)) log.Fatal(app.Listen(":8080")) } func HandleWsMonitor(c *websocket.Conn) { // It seems the we only need one SocketListener goroutine for the whole server. // If this is the case, the next line should be moved outside of this func. go SocketListener() defer func() { unregister <- c c.Close() }() register <- c for { messageType, message, err := c.ReadMessage() if err != nil { if websocket.IsUnexpectedCloseError(err, websocket.CloseGoingAway, websocket.CloseAbnormalClosure) { log.Println("read error:", err) } return } if messageType == websocket.TextMessage { log.Println("got textmessage:", string(message)) } else { log.Println("received message of type:", messageType) } } } func SocketListener() { for { select { case c := <-register: // This did appear in the log. log.Println("case c := <-register") messageType, message, err := c.ReadMessage() if err != nil { log.Println(err) // unregister is unbuffered, the sending will be blocked. unregister <- c // If we use only one SocketListener goroutine then it should // not return here. return } log.Printf("Got message of type: %d\nMessage:%s\n", messageType, string(message)) log.Printf("Connection Params: %s\n", c.Params("id")) case c := <-unregister: c.Close() log.Println("Closed connection") } } }
Atas ialah kandungan terperinci Bagaimana untuk mendaftar sambungan websocket baharu dengan gooptic. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Alat AI Hot

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool
Gambar buka pakaian secara percuma

Clothoff.io
Penyingkiran pakaian AI

AI Hentai Generator
Menjana ai hentai secara percuma.

Artikel Panas

Alat panas

Notepad++7.3.1
Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina
Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1
Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6
Alat pembangunan web visual

SublimeText3 versi Mac
Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Topik panas



Perpustakaan yang digunakan untuk operasi nombor terapung dalam bahasa Go memperkenalkan cara memastikan ketepatannya ...

Masalah Threading Giliran di GO Crawler Colly meneroka masalah menggunakan Perpustakaan Colly Crawler dalam bahasa Go, pemaju sering menghadapi masalah dengan benang dan permintaan beratur. � ...

Perpustakaan mana yang dibangunkan oleh syarikat besar atau projek sumber terbuka yang terkenal? Semasa pengaturcaraan di GO, pemaju sering menghadapi beberapa keperluan biasa, ...

Dua cara untuk menentukan struktur dalam bahasa Go: perbezaan antara VAR dan jenis kata kunci. Apabila menentukan struktur, pergi bahasa sering melihat dua cara menulis yang berbeza: pertama ...

Perbezaan antara percetakan rentetan dalam bahasa Go: perbezaan kesan menggunakan fungsi println dan rentetan () sedang ...

Masalah menggunakan redisstream untuk melaksanakan beratur mesej dalam bahasa Go menggunakan bahasa Go dan redis ...

GO Pointer Syntax dan menangani masalah dalam penggunaan perpustakaan Viper semasa pengaturcaraan dalam bahasa Go, adalah penting untuk memahami sintaks dan penggunaan petunjuk, terutama dalam ...

Mengapa lelaran peta di GO menyebabkan semua nilai menjadi elemen terakhir? Dalam bahasa Go, ketika berhadapan dengan beberapa soalan wawancara, anda sering menemui peta ...
