مثال WebSocket فایبر

بر اساس Fiber's Fasthttp کامپوننت WebSocket، متد *fiber.Ctx بکار می‌رود، مانند Locals، Params، Query و Cookies. در زیر مثالی از استفاده از WebSocket در Fiber آمده است.

توجه: نسخه 1.18 و بالاتر Go مورد نیاز است.

نصب

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 {

پیکربندی

خصوصیت نوع توضیحات مقدار پیش‌فرض
Filter func(*fiber.Ctx) bool تعیین یک تابع برای رد کردن میان‌افزار. nil
HandshakeTimeout time.Duration HandshakeTimeout مدت زمان مشخص می‌شود که برای تکمیل هندشیک اختصاص داده می‌شود. 0 (بدون زمان محدود)
Subprotocols []string 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 داشته باشد، برمی‌گرداند true
		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"))  // 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"))
	// دسترسی به سرور WebSocket: ws://localhost:3000/ws/123?v=1.0
	// https://www.websocket.org/echo.html
}

یادداشت‌ها در استفاده از میان‌افزار حافظه پنهان

اگر هنگام استفاده از میان‌افزار حافظه پنهان با خطای websocket: bad handshake مواجه می‌شوید، از 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) {}))

ملاحظات مربوط به استفاده از میان‌افزار بازیابی

به دلایل پیاده‌سازی داخلی، میان‌افزار بازیابی در حال حاضر با میان‌افزار وب‌سوکت سازگار نیست. لطفاً از config.RecoverHandler برای اضافه کردن یک دستگیرگر بازیابی برای نقاط پایانی وب‌سوکت استفاده کنید. به طور پیش‌فرض، پیکربندی RecoverHandler از خطاهای پدید آمده بازیابی می‌کند، ردیابی پشته را در stderr نوشته و همچنین یک پاسخ حاوی پیام خطا را در فیلد 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))