ตัวอย่าง Fiber WebSocket

ขึ้นอยู่กับคอมโพเนนต์ของ WebSocket ใน Fasthttp ของ Fiber ใช้วิธี *fiber.Ctx เช่น Locals, Params, Query, และ Cookies นี่คือตัวอย่างการใช้ WebSocket ใน Fiber

หมายเหตุ: จำเป็นต้องใช้ Go เวอร์ชัน 1.18 ขึ้นไป

การติดตั้ง

go get -u github.com/gofiber/fiber/v2
go get -u github.com/gofiber/contrib/websocket

ลายเซ็นต์ของฟังก์ชัน

func New(handler func(*websocket.Conn), config ...websocket.Config) fiber.Handler {

การกำหนดค่า

Property Type รายละเอียด ค่าเริ่มต้น
Filter func(*fiber.Ctx) bool กำหนดฟังก์ชันในการข้าม middleware nil
HandshakeTimeout time.Duration HandshakeTimeout ระบุระยะเวลาในการทำการ Handshake 0 (ไม่มีการจำกัดเวลา)
Subprotocols []string Subprotocols ระบุ subprotocols ที่ลูกค้าร้องขอ nil
Origins []string Origins ที่อนุญาตโดยขึ้นอยู่กับหัวข้อลูกค้า nil
ReadBufferSize int ReadBufferSize ระบุขนาดของบัฟเฟอร์ I/O สำหรับการรับข้อความ (ในไบต์) 0 (ขนาดเริ่มต้น)
WriteBufferSize int WriteBufferSize ระบุขนาดของบัฟเฟอร์ I/O สำหรับการส่งข้อความ (ในไบต์) 0 (ขนาดเริ่มต้น)
WriteBufferPool websocket.BufferPool WriteBufferPool คือพูลบัฟเฟอร์ที่ใช้สำหรับการดำเนินการเขียน nil
EnableCompression bool EnableCompression ระบุว่าลูกค้าควรเจรจะการบีบอัดสำหรับแต่ละข้อความหรือไม่ (RFC 7692) false
RecoverHandler func(*websocket.Conn) void RecoverHandler เป็นฟังก์ชันในการดำเนินการสำหรับการกู้คืนจากการขาด defaultRecover

ตัวอย่าง

package main

import (
	"log"
	"github.com/gofiber/fiber/v2"
	"github.com/gofiber/contrib/websocket"
)

func main() {
	app := fiber.New()

	app.Use("/ws", func(c *fiber.Ctx) error {
		// คืนค่าเป็นจริงถ้าลูกค้าร้องขอการอัพเกรดไปยังโปรโตคอล WebSocket
		if websocket.IsWebSocketUpgrade(c) {
			c.Locals("allowed", true)
			return c.Next()
		}
		return fiber.ErrUpgradeRequired
	})

	app.Get("/ws/:id", websocket.New(func(c *websocket.Conn) {
		// c.Locals เพิ่มใน *websocket.Conn
		log.Println(c.Locals("allowed"))  // จริง
		log.Println(c.Params("id"))       // 123
		log.Println(c.Query("v"))         // 1.0
		log.Println(c.Cookies("session")) // ""

		var (
			mt  int
			msg []byte
			err error
		)
		for {
			if mt, msg, err = c.ReadMessage(); err != nil {
				log.Println("read:", err)
				break
			}
			log.Printf("recv: %s", msg)

			if err = c.WriteMessage(mt, msg); err != nil {
				log.Println("write:", err)
				break
			}
		}
	}))

	log.Fatal(app.Listen(":3000"))
	// เข้าถึงเซิร์ฟเวอร์ WebSocket: ws://localhost:3000/ws/123?v=1.0
	// https://www.websocket.org/echo.html
}

ข้อความเพื่อการใช้งาน Cache Middleware

หากคุณพบข้อผิดพลาด websocket: bad handshake ในขณะที่ใช้ cache middleware ใช้ config.Next เพื่อข้ามเส้นทาง WebSocket

app := fiber.New()
app.Use(cache.New(cache.Config{
	Next: func(c *fiber.Ctx) bool {
		return strings.Contains(c.Route().Path, "/ws")
	},
}))

app.Get("/ws/:id", websocket.New(func(c *websocket.Conn) {}))

ข้อคิดพิจารณาในการใช้ middleware สำหรับการกู้คืน

เนื่องจากเหตุผลในการดำเนินการภายใน ในปัจจุบัน middleware สำหรับการกู้คืน (recovery) ไม่สามารถทำงานร่วมกับ middleware สำหรับ WebSocket ได้ กรุณาใช้ config.RecoverHandler เพื่อเพิ่มตัวจัดการการกู้คืนสำหรับ endpoint ของ WebSocket โดยค่าเริ่มต้นของค่าการกำหนด RecoverHandler จะทำการกู้คืนจาก panic, เขียน stack trace ไปยัง stderr, และส่งคำตอบที่ประกอบด้วยข้อความ panic ในฟิลด์ error ด้วย

app := fiber.New()

app.Use(cache.New(cache.Config{
    Next: func(c *fiber.Ctx) bool {
        return strings.Contains(c.Route().Path, "/ws")
    },
}))

cfg := Config{
    RecoverHandler: func(conn *Conn) {
        if err := recover(); err != nil {
            conn.WriteJSON(fiber.Map{"customError": "error occurred"})
        }
    },
}

app.Get("/ws/:id", websocket.New(func(c *websocket.Conn) {}, cfg))