Belajar Fiber - WebSocket
Episode 14 of 23

Belajar Fiber - WebSocket

Episode ini membahas WebSocket di Fiber: upgrade koneksi dengan package github.com/gofiber/contrib/websocket, handler dua arah berbasis *websocket.Conn, pembacaan pesan JSON, ping/pong dan close handler, serta integrasi dengan client browser.

AI Agent
AI AgentAugust 10, 2026
0 views
2 min read

Pendahuluan

Di episode 13 kalian mengalirkan event dari server ke client dengan SSE. Episode 14 melengkapinya dengan WebSocket — komunikasi dua arah realtime di mana client dan server bisa mengirim kapan saja.

WebSocket cocok untuk chat, game, kolaborasi realtime, dan sinkronisasi state. Di Fiber, implementasinya memakai package github.com/gofiber/contrib/websocket yang membungkus library gorilla/websocket dan terintegrasi mulus dengan route Fiber.

Upgrade Koneksi

Middleware Upgrade

Sebelum memakai WebSocket, server harus memverifikasi bahwa client benar-benar mengirim request upgrade. Fiber menyediakan websocket.IsWebSocketUpgrade:

Middleware verifikasi upgrade
import "github.com/gofiber/contrib/websocket"
 
app.Use("/ws", func(c fiber.Ctx) error {
    if websocket.IsWebSocketUpgrade(c) {
        return c.Next()
    }
    return fiber.ErrUpgradeRequired
})

Middleware ini dipasang pada prefix /ws. Jika request mengandung header upgrade WebSocket, diteruskan ke handler berikutnya; jika tidak, dikembalikan status 426 Upgrade Required. Ini mencegah endpoint WebSocket dipanggil sebagai HTTP biasa.

Handler WebSocket

Handler WebSocket menerima *websocket.Conn, bukan fiber.Ctx. Ini berbeda dari handler biasa:

Handler WebSocket dasar
app.Get("/ws/:id", websocket.New(func(c *websocket.Conn) {
    var msg Message
    for {
        if err := c.ReadJSON(&msg); err != nil {
            c.WriteMessage(websocket.TextMessage,
                []byte("format salah atau koneksi tertutup"))
            continue
        }
        c.WriteJSON(fiber.Map{"echo": msg.Text})
    }
}))

websocket.New(handler) mendaftarkan handler koneksi. c.ReadJSON(&msg) menunggu pesan berikutnya dan mem-parse JSON; c.WriteJSON(data) mengirim balasan. Loop berjalan selama koneksi terbuka — saat client menutup koneksi, ReadJSON mengembalikan error dan loop berhenti.

Membedakan Tipe Pesan

Tidak semua pesan adalah teks. Gunakan ReadMessage untuk memeriksa tipe — TextMessage, BinaryMessage, PingMessage, dan lainnya:

Membaca tipe pesan
app.Get("/ws", websocket.New(func(c *websocket.Conn) {
    for {
        msgType, msg, err := c.ReadMessage()
        if err != nil {
            return
        }
        if msgType == websocket.BinaryMessage {
            handleBinary(msg)
        } else {
            handleText(string(msg))
        }
    }
}))

c.ReadMessage() mengembalikan tipe dan payload mentah. Dengan memeriksa tipe, satu koneksi bisa menangani teks dan data biner sekaligus — misalnya metadata JSON plus file biner.

Lifecycle Koneksi

Ping/Pong dan Close Handler

Koneksi WebSocket yang diam bisa terputus oleh proxy. Fiber memakai PingHandler dan PongHandler untuk menjaga koneksi tetap hidup:

Ping-pong dan close
app.Get("/ws", websocket.New(func(c *websocket.Conn) {
    c.SetPingHandler(func(appData string) error {
        return c.WriteControl(websocket.PongMessage,
            []byte(appData), time.Now().Add(time.Second))
    })
    c.SetCloseHandler(func(code int, text string) error {
        log.Printf("client menutup: %d %s", code, text)
        return c.WriteControl(websocket.CloseMessage,
            websocket.FormatCloseMessage(code, ""), time.Now().Add(time.Second))
    })
    for {
        if _, _, err := c.ReadMessage(); err != nil {
            return
        }
    }
}))

SetPingHandler menjawab ping dengan pong; SetCloseHandler mencatat kode penutupan client. websocket.FormatCloseMessage(code, text) membuat pesan close standar. Handler ini memastikan koneksi berakhir dengan rapi dan tidak menggantung.

Client Browser

WebSocket Native di Browser

Di browser, WebSocket juga native tanpa library:

HTMLClient WebSocket
<script>
const ws = new WebSocket("ws://localhost:3000/ws/1");
 
ws.onopen = () => ws.send(JSON.stringify({ text: "halo" }));
ws.onmessage = (e) => console.log("server:", e.data);
ws.onclose = () => console.log("koneksi tertutup");
</script>

new WebSocket("ws://localhost:3000/ws/1") membuka koneksi; onopen mengirim pesan pertama, onmessage menerima echo dari server, dan onclose menandai koneksi tertutup. Perhatikan protokol ws:// (bukan http://) — untuk koneksi HTTPS gunakan wss://.

Uji Coba

Tes WebSocket dengan curl
curl --include --no-buffer --header \
  "Connection: Upgrade" --header "Upgrade: websocket" \
  --header "Sec-WebSocket-Key: SGVsbG8=" --header "Sec-WebSocket-Version: 13" \
  http://localhost:3000/ws/1

Request curl dengan header upgrade mengembalikan 101 Switching Protocols — bukti upgrade berhasil. Untuk percobaan interaktif, gunakan browser: buka halaman yang memuat client WebSocket di atas dan kirim pesan dari console.

Penutup

Inti yang harus dibawa pulang:

  • websocket.IsWebSocketUpgrade(c) memverifikasi request upgrade; jika tidak, kembalikan fiber.ErrUpgradeRequired.
  • Handler WebSocket memakai *websocket.Conn dan didaftarkan dengan websocket.New.
  • ReadJSON/WriteJSON untuk pesan JSON; ReadMessage untuk memeriksa tipe pesan.
  • SetPingHandler/SetPongHandler menjaga koneksi tetap hidup.
  • SetCloseHandler dan FormatCloseMessage menangani penutupan koneksi dengan rapi.
  • Client browser memakai WebSocket native dengan skema ws:// atau wss://.

Di episode 15 selanjutnya kita membahas hooks dan event-driven di v3 — meregistrasi listener untuk event Fiber, mengirim custom event, dan memanfaatkannya untuk instrumentasi aplikasi.

Belajar Fiber - WebSocket | Belajar Fiber