Teknik Detaylar

Go ile WebSockets: Upgrader Nedir?

← Teknik Detaylar
2021-08-02 ~ 2026-06-21 · 4 dk okuma
Go ile WebSockets: Upgrader Nedir?
Bu yazıyı yapay zekâ ile tartış
Sayfayı kopyala

💡 Özet (TL;DR):

  • Nedir: websocket.Upgrader, standart bir HTTP bağlantısını (TCP el sıkışması ile) çift yönlü, düşük gecikmeli bir WebSocket bağlantısına dönüştüren (Upgrade) Gorilla WebSocket metodudur.
  • Kritik Hata Düzeltmesi: Orijinal yazıdaki Upgrader struct yorum satırlarında yer alan, yorum işareti (//) unutulduğu için derleme hatasına yol açan satır düzeltilmiştir.
  • Temel Yapılandırma: Geliştirme ortamında CheckOrigin fonksiyonunun true dönmesi sağlanarak tarayıcı kökenli CORS engellemelerinin önüne geçilmesi yaygın bir pratiktir.

Bir süredir Go ile haşır neşir oluyorum ve son 1-2 gündür de WebSocket üzerinde çalışıyorum. Go ile WebSocket destekli bir uygulama yazmak için ek paketler kullanmanız şart olmasa da, hem Amerika'yi yeniden keşfetmemek hem de Go dünyasında yeniyseniz kendinize fazla yüklenmemek için kullanabileceğiniz çeşitli kütüphaneler mevcut.

Bu kütüphaneler arasında Go topluluğu tarafından en yaygın kabul gören ve popüler olanı gorilla/websocket kütüphanesidir. Ben kendi adıma örnekleri ve dokümantasyonu geniş olduğu için önce bu kütüphaneyle bir şeyler yapmayı, ardından nhooyr/websocket kütüphanesine geçiş yapmayı düşünüyorum.


HTTP vs. WebSocket Karşılaştırması

ÖzellikHTTP (Standart)WebSocket
İletişim TürüTek yönlü (İstemci ister, sunucu cevap verir).Çift yönlü (Bi-directional) - İki taraf da aynı anda veri gönderebilir.
Bağlantı TipiStateless (Her istekte bağlantı açılır/kapanır).Persistent (Bağlantı sürekli açık kalır).
Gecikme (Latency)Yüksek (Her istekte HTTP başlıkları taşınır).Çok Düşük (Handshake sonrası başlık yükü yoktur).
Kullanım SenaryosuKlasik web sayfaları, REST API'ler.Canlı sohbet, anlık borsa grafikleri, çok oyunculu oyunlar.

1. websocket.Upgrader Nedir?

Gorilla WebSocket kütüphanesinde daha başlarken websocket.Upgrader kullanıldığını görürüz. Upgrader, standart bir HTTP bağlantısını güvenli bir el sıkışması (handshake) ile WebSocket bağlantısına "yükselten" (upgrade) Gorilla kütüphanesi metodudur.

Temel mantık şu şekilde çalışır: İstemci, belirlenen HTTP adresine istek yaparak bağlantının WebSocket'e yükseltilmesini ister; sunucu da istek gereken şartları (belirlenen güvenlik kurallarını) karşılıyorsa bağlantıyı onaylayıp TCP hattını sürekli açık tutacak şekilde WebSocket moduna geçirir.

Upgrader tanımlanırken genelde sadece ReadBufferSize ve WriteBufferSize tampon (buffer) değerleri belirtilir:

var upgrader = websocket.Upgrader{
    ReadBufferSize:  4096,
    WriteBufferSize: 4096,
}

2. Upgrader Yapısının Detaylı Parametreleri

Upgrader yapısının (struct) alabileceği tüm parametreler ve açıklamaları aşağıda belirtilmiştir:

type Upgrader struct {
    // HandshakeTimeout el sıkışması (handshake) süresi için bir azami limit belirler.
    HandshakeTimeout time.Duration

    // ReadBufferSize ve WriteBufferSize I/O tampon büyüklüklerini bayt olarak
    // belirlemek içindir. Tampon (buffer) boyutu sıfırsa HTTP sunucusu tarafından
    // belirlenen tampon kullanılır. I/O tampon boyutları gönderilecek veya alınacak
    // mesajların boyutunu sınırlandırmaz.
    ReadBufferSize, WriteBufferSize int

    // WriteBufferPool yazma işlemleri için bir tampon havuzudur. Değer belirtilmezse
    // yazma tamponları bağlantı yaşam süresi boyunca tahsis edilir.
    WriteBufferPool BufferPool

    // Subprotocols sunucunun desteklediği alt protokolleri tercih sırasına göre belirtir.
    // Bu alan nil değilse Upgrade metodu bu listenin başından başlayarak istemcinin
    // istediği protokole göre bir tercih yapar.
    Subprotocols []string

    // Error HTTP hata yanıtlarını oluşturacak fonksiyonu belirler. Error nil ise
    // HTTP yanıtını oluşturmak için http.Error kullanılır.
    Error func(w http.ResponseWriter, r *http.Request, status int, reason error)

    // CheckOrigin isteğin köken (Origin) başlığının kabul edilme kriterlerini denetler.
    // Eğer CheckOrigin nil ise varsayılan olarak origin header'ı varsa ve origin
    // host değeri request host başlık değerinden farklıysa false döndürür.
    // Cross-site istek saldırılarından (CSRF) korunmak için bu fonksiyon kullanılmalıdır.
    CheckOrigin func(r *http.Request) bool

    // EnableCompression sunucunun mesaj sıkıştırmayı (RFC 7692) etkinleştirmeyi
    // denemesini sağlar. True olarak ayarlamak sıkıştırmayı garanti etmez.
    // Mevcut desteklenen modlar "no context" ve "takeover" modlarıdır.
    EnableCompression bool
}

3. Çalışan WebSocket Sunucu Örneği (Go)

Aşağıdaki örnekte, tarayıcı isteklerine açık (CheckOrigin devrede) ve gelen mesajları geri döndüren (Echo Server) çalışan bir Go WebSocket uygulamasını inceleyebilirsiniz:

package main

import (
    "fmt"
    "net/http"
    "github.com/gorilla/websocket"
)

var myUpgrader = websocket.Upgrader{
    ReadBufferSize:  1024,
    WriteBufferSize: 1024,
    CheckOrigin: func(r *http.Request) bool {
        // Tarayıcı kökenli CORS engellemelerini aşmak için geliştirme ortamında true dönüyoruz
        return true 
    },
}

func handleWebSocket(w http.ResponseWriter, r *http.Request) {
    // HTTP bağlantısını WebSocket bağlantısına yükseltiyoruz
    conn, err := myUpgrader.Upgrade(w, r, nil)
    if err != nil {
        fmt.Println("WebSocket bağlantısı kurulamadı:", err)
        return
    }
    defer conn.Close()

    fmt.Println("WebSocket istemcisi başarıyla bağlandı!")

    for {
        // İstemciden gelen mesajı oku
        messageType, p, err := conn.ReadMessage()
        if err != nil {
            fmt.Println("Mesaj okuma hatası:", err)
            return
        }

        fmt.Printf("Gelen Mesaj: %s\n", string(p))

        // Gelen mesajı aynı şekilde istemciye geri gönder (Echo)
        if err := conn.WriteMessage(messageType, p); err != nil {
            fmt.Println("Mesaj yazma hatası:", err)
            return
        }
    }
}

func main() {
    http.HandleFunc("/ws", handleWebSocket)
    fmt.Println("WebSocket sunucusu :8080 portunda çalışıyor...")
    http.ListenAndServe(":8080", nil)
}

Kapak görseli: Hamish Kale (Unsplash)


Bu Yazıda Yapılan Değişiklikler
  • 11.05.2022: Yazı özeti düzenlendi.
  • 21.06.2026: EnableCompression yorum satırındaki derleme hatasına yol açan eksik yorum işaretleri düzeltildi. Türkçe imla hataları (Amerika'yı, bir şeyler, başlayarak, protokol vb.) giderildi. Okuyucuların lokalde çalıştırabileceği güncel bir WebSocket sunucu (Echo Server) örnek kodu eklendi, TL;DR özet ve karşılaştırma tablosu entegre edildi.