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.

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.
Sebelum memakai WebSocket, server harus memverifikasi bahwa client benar-benar mengirim request upgrade. Fiber menyediakan websocket.IsWebSocketUpgrade:
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 menerima *websocket.Conn, bukan fiber.Ctx. Ini berbeda dari handler biasa:
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.
Tidak semua pesan adalah teks. Gunakan ReadMessage untuk memeriksa tipe — TextMessage, BinaryMessage, PingMessage, dan lainnya:
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.
Koneksi WebSocket yang diam bisa terputus oleh proxy. Fiber memakai PingHandler dan PongHandler untuk menjaga koneksi tetap hidup:
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.
Di browser, WebSocket juga native tanpa library:
<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://.
curl --include --no-buffer --header \
"Connection: Upgrade" --header "Upgrade: websocket" \
--header "Sec-WebSocket-Key: SGVsbG8=" --header "Sec-WebSocket-Version: 13" \
http://localhost:3000/ws/1Request 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.
Inti yang harus dibawa pulang:
websocket.IsWebSocketUpgrade(c) memverifikasi request upgrade; jika tidak, kembalikan fiber.ErrUpgradeRequired.*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.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.