Ví dụ WebSocket của Fiber

Dựa trên thành phần WebSocket Fasthttp của Fiber, phương thức *fiber.Ctx được sử dụng, chẳng hạn như Locals, Params, Query và Cookies. Dưới đây là một ví dụ về việc sử dụng WebSocket trong Fiber.

Lưu ý: Yêu cầu Go phiên bản 1.18 trở lên.

Cài đặt

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

Chữ ký hàm

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

Cấu hình

Thuộc tính Kiểu Mô tả Giá trị Mặc định
Filter func(*fiber.Ctx) bool Xác định một hàm để bỏ qua middleware. nil
HandshakeTimeout time.Duration HandshakeTimeout xác định thời gian hoàn thành nghi thức bắt tay. 0 (không giới hạn thời gian)
Subprotocols []string Subprotocols chỉ định các subprotocols được yêu cầu từ phía máy khách. nil
Origins []string Các nguồn cho phép dựa trên tiêu đề Origin. Nếu rỗng, sẽ cho phép mọi nguồn. nil
ReadBufferSize int ReadBufferSize chỉ định kích thước bộ đệm I/O để nhận các tin nhắn (theo byte). 0 (kích thước mặc định)
WriteBufferSize int WriteBufferSize chỉ định kích thước bộ đệm I/O để gửi các tin nhắn (theo byte). 0 (kích thước mặc định)
WriteBufferPool websocket.BufferPool WriteBufferPool là bộ đệm được sử dụng cho các hoạt động ghi. nil
EnableCompression bool EnableCompression chỉ định liệu máy khách có nên thương lượng nén cho mỗi tin nhắn (RFC 7692) hay không. false
RecoverHandler func(*websocket.Conn) void RecoverHandler là một hàm xử lý để phục hồi từ trạng thái hoảng loạn. defaultRecover

Ví dụ

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 {
		// Trả về true nếu máy khách yêu cầu nâng cấp lên giao thức 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 được thêm vào *websocket.Conn
		log.Println(c.Locals("allowed"))  // true
		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"))
	// Truy cập máy chủ WebSocket: ws://localhost:3000/ws/123?v=1.0
	// https://www.websocket.org/echo.html
}

Lưu ý khi Sử dụng Middleware Cache

Nếu bạn gặp phải lỗi websocket: bad handshake khi sử dụng middleware bộ nhớ đệm, sử dụng config.Next để bỏ qua đường dẫn 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) {}))

Xem xét khi sử dụng middleware khôi phục

Do lí do triển khai nội bộ, hiện tại middleware khôi phục không tương thích với middleware WebSocket. Vui lòng sử dụng config.RecoverHandler để thêm xử lý khôi phục cho các điểm cuối WebSocket. Theo mặc định, cấu hình RecoverHandler khôi phục từ sự chết người, ghi stack trace ra stderr, và cũng trả về một phản ứng chứa thông điệp chết người trong trường 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))