Contoh WebSocket Fiber

Berdasarkan komponen WebSocket Fasthttp dari Fiber, metode *fiber.Ctx digunakan, seperti Locals, Params, Query, dan Cookies. Berikut adalah contoh penggunaan WebSocket di Fiber.

Catatan: Diperlukan Go versi 1.18 ke atas.

Instalasi

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

Tanda Tangan Fungsi

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

Konfigurasi

Properti Tipe Deskripsi Nilai Default
Filter func(*fiber.Ctx) bool Mendefinisikan fungsi untuk melewati middleware. nil
HandshakeTimeout time.Duration HandshakeTimeout menentukan durasi penyelesaian handshake. 0 (tanpa batas waktu)
Subprotocols []string Subprotocols menentukan subprotocol yang diminta oleh klien. nil
Origins []string Origins yang diizinkan berdasarkan header Origin. Jika kosong, akan mengizinkan asal mana pun. nil
ReadBufferSize int ReadBufferSize menentukan ukuran buffer I/O untuk menerima pesan (dalam byte). 0 (ukuran default)
WriteBufferSize int WriteBufferSize menentukan ukuran buffer I/O untuk mengirim pesan (dalam byte). 0 (ukuran default)
WriteBufferPool websocket.BufferPool WriteBufferPool adalah pool buffer yang digunakan untuk operasi tulis. nil
EnableCompression bool EnableCompression menentukan apakah klien harus bernegosiasi kompresi untuk setiap pesan (RFC 7692). false
RecoverHandler func(*websocket.Conn) void RecoverHandler adalah fungsi penanganan untuk pemulihan dari panic. defaultRecover

Contoh

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 {
		// Mengembalikan true jika klien meminta upgrade ke protokol 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 ditambahkan ke *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"))
	// Akses server WebSocket: ws://localhost:3000/ws/123?v=1.0
	// https://www.websocket.org/echo.html
}

Catatan Penggunaan Middleware Cache

Jika Anda mengalami kesalahan websocket: bad handshake saat menggunakan middleware cache, gunakan config.Next untuk melewati jalur 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) {}))

Pertimbangan Penggunaan Middleware Pemulihan

Karena alasan implementasi internal, saat ini middleware pemulihan tidak kompatibel dengan middleware WebSocket. Harap gunakan config.RecoverHandler untuk menambahkan handler pemulihan untuk endpoint WebSocket. Secara default, konfigurasi RecoverHandler akan pulih dari panic, menulis jejak stack ke stderr, dan juga mengembalikan respons yang berisi pesan panic di dalam bidang 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))