مثال على WebSocket في Fiber

بناءً على مكون WebSocket السريع لـ Fiber's Fasthttp, يتم استخدام الطريقة *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 يحدد حجم مخزن الإدخال/الإخراج لاستقبال الرسائل (بالبايت). 0 (الحجم الافتراضي)
WriteBufferSize int WriteBufferSize يحدد حجم مخزن الإدخال/الإخراج لإرسال الرسائل (بالبايت). 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 {
		// تُعيد القيمة true إذا طلب العميل الترقية إلى بروتوكول 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"))  // 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": "حدث خطأ"})
        }
    },
}

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