25 Desember 2024

Sebagian besar pengembang mengetahui tentang WebSockets, tetapi Server-Sent Events (SSE) menawarkan alternatif yang lebih sederhana dan sering diabaikan sehingga perlu mendapat perhatian lebih. Mari kita telusuri mengapa teknologi ini diremehkan dan apa manfaatnya bagi aplikasi Anda.

Apa itu Acara yang Dikirim Server?

SSE menetapkan saluran komunikasi satu arah dari server ke klien melalui HTTP. Tidak seperti koneksi dua arah WebSockets, SSE mempertahankan koneksi HTTP terbuka untuk pembaruan server-ke-klien. Anggap saja sebagai siaran radio: server (stasiun) memancarkan, dan klien (penerima) mendengarkan.

Mengapa Mereka Diremehkan?

Dua faktor utama yang menyebabkan rendahnya apresiasi SSE:

  1. Popularitas WebSocket: Kemampuan komunikasi dupleks penuh WebSockets sering kali menutupi pendekatan SSE yang lebih sederhana
  2. Keterbatasan yang Dirasakan: Sifat searah mungkin tampak membatasi, meskipun seringkali cukup untuk banyak kasus penggunaan

Kekuatan Utama SSE

1. Kesederhanaan Implementasi

SSE memanfaatkan protokol HTTP standar, menghilangkan kerumitan manajemen koneksi WebSocket.

2. Kompatibilitas Infrastruktur

SSE bekerja secara lancar dengan infrastruktur HTTP yang ada:

  • Penyeimbang beban
  • Proksi
  • Firewall
  • Server HTTP standar

3. Efisiensi Sumber Daya

Konsumsi sumber daya yang lebih rendah dibandingkan dengan WebSockets karena:

  • Sifatnya searah
  • Penggunaan koneksi HTTP standar
  • Tidak ada pemeliharaan soket yang terus-menerus

4. Sambungan Ulang Otomatis

Dukungan browser bawaan untuk:

  • Penanganan gangguan koneksi
  • Upaya penyambungan ulang otomatis
  • Pengalaman real-time yang tangguh

5. Hapus Semantik

Pola komunikasi satu arah menerapkan:

  • Pemisahan kekhawatiran yang jelas
  • Aliran data yang mudah
  • Logika aplikasi yang disederhanakan

Aplikasi Praktis

SSE unggul dalam skenario berikut:

  1. Umpan Berita dan Pembaruan Sosial Waktu Nyata
  2. Ticker Saham dan Data Keuangan
  3. Bilah Kemajuan dan Pemantauan Tugas
  4. Streaming Log Server
  5. Pengeditan Kolaboratif (untuk pembaruan)
  6. Papan Peringkat Permainan
  7. Sistem Pelacakan Lokasi

Contoh Implementasi

Sisi Server (Labu)

from flask import Flask, Response, stream_with_context
import time
import random

app = Flask(__name__)

def generate_random_data():
    while True:
        data = f"data: Random value: {random.randint(1, 100)}nn"
        yield data
        time.sleep(1)

@app.route('/stream')
def stream():
    return Response(
        stream_with_context(generate_random_data()),
        mimetype='text/event-stream'
    )

if __name__ == '__main__':
    app.run(debug=True)

Sisi Klien (JavaScript)

const eventSource = new EventSource("/stream");

eventSource.onmessage = function(event) {
    const dataDiv = document.getElementById("data");
    dataDiv.innerHTML += `${event.data}`;
};

eventSource.onerror = function(error) {
    console.error("SSE error:", error);
};

Penjelasan Kode

Komponen Sisi Server:

  • /stream rute menangani koneksi SSE
  • generate_random_data() terus menerus menghasilkan acara yang diformat
  • text/event-stream mimetype memberi sinyal protokol SSE
  • stream_with_context mempertahankan konteks aplikasi Flask

Komponen Sisi Klien:

  • EventSource objek mengelola koneksi SSE
  • onmessage handler memproses kejadian yang masuk
  • onerror menangani masalah koneksi
  • Koneksi ulang otomatis ditangani oleh browser

Keterbatasan dan Pertimbangan

Saat menerapkan SSE, waspadai kendala berikut:

1. Komunikasi Searah

  • Hanya server-ke-klien
  • Memerlukan permintaan HTTP terpisah untuk komunikasi klien-ke-server

2. Dukungan Peramban

3.Format Data

  • Dukungan utama untuk data berbasis teks
  • Data biner memerlukan pengkodean (misalnya, Base64)

Praktik Terbaik

  1. Penanganan Kesalahan
eventSource.onerror = function(error) {
    if (eventSource.readyState === EventSource.CLOSED) {
        console.log("Connection was closed");
    }
};
  1. Manajemen Koneksi
// Clean up when done
function closeConnection() {
    eventSource.close();
}
  1. Strategi Penyambungan Kembali
let retryAttempts = 0;
const maxRetries = 5;

eventSource.onclose = function() {
    if (retryAttempts < maxRetries) {
        setTimeout(() => {
            // Reconnect logic
            retryAttempts++;
        }, 1000 * retryAttempts);
    }
};

Contoh Dunia Nyata: Implementasi ChatGPT

Model Pembelajaran Bahasa Modern (LLM) menggunakan Server-Sent Events (SSE) untuk respons streaming. Mari kita jelajahi cara kerja penerapan ini dan apa yang membuatnya unik.

Pola Umum

Semua penyedia LLM besar menerapkan streaming menggunakan pola umum:

  • Kembali content-type: text/event-stream tajuk
  • Blok data aliran dipisahkan oleh rnrn
  • Setiap blok berisi a data: JSON garis

Catatan Penting

Meskipun SSE biasanya bekerja dengan API EventSource browser, implementasi LLM tidak dapat menggunakan ini secara langsung karena:

  • EventSource hanya mendukung permintaan GET
  • LLM API memerlukan permintaan POST

Implementasi OpenAI

Struktur Permintaan Dasar

curl  
  -H "Content-Type: application/json" 
  -H "Authorization: Bearer $OPENAI_API_KEY" 
  -d '{
    "model": "gpt-4o-mini",
    "messages": ({"role": "user", "content": "Hello, world?"}),
    "stream": true,
    "stream_options": {
      "include_usage": true
    }
  }'

Format Respons

Setiap potongan mengikuti struktur ini:

"data":{
   "id":"chatcmpl-AiT7GQk8zzYSC0Q8UT1pzyRzwxBCN",
   "object":"chat.completion.chunk",
   "created":1735161718,
   "model":"gpt-4o-mini-2024-07-18",
   "system_fingerprint":"fp_0aa8d3e20b",
   "choices":(
      {
         "index":0,
         "delta":{
            "content":"!"
         },
         "logprobs":null,
         "finish_reason":null
      }
   ),
   "usage":null
}

"data":{
   "id":"chatcmpl-AiT7GQk8zzYSC0Q8UT1pzyRzwxBCN",
   "object":"chat.completion.chunk",
   "created":1735161718,
   "model":"gpt-4o-mini-2024-07-18",
   "system_fingerprint":"fp_0aa8d3e20b",
   "choices":(
      {
         "index":0,
         "delta":{
            
         },
         "logprobs":null,
         "finish_reason":"stop"
      }
   ),
   "usage":null
}

Header kunci dikembalikan oleh OpenAI:

HTTP/2 200
date: Wed, 25 Dec 2024 21:21:59 GMT
content-type: text/event-stream; charset=utf-8
access-control-expose-headers: X-Request-ID
openai-organization: user-esvzealexvl5nbzmxrismbwf
openai-processing-ms: 100
openai-version: 2020-10-01
x-ratelimit-limit-requests: 10000
x-ratelimit-limit-tokens: 200000
x-ratelimit-remaining-requests: 9999
x-ratelimit-remaining-tokens: 199978
x-ratelimit-reset-requests: 8.64s
x-ratelimit-reset-tokens: 6ms

Detail Implementasi

Penyelesaian Aliran

Aliran diakhiri dengan:

Informasi Penggunaan

Pesan terakhir mencakup penggunaan token:

"data":{
   "id":"chatcmpl-AiT7GQk8zzYSC0Q8UT1pzyRzwxBCN",
   "object":"chat.completion.chunk",
   "created":1735161718,
   "model":"gpt-4o-mini-2024-07-18",
   "system_fingerprint":"fp_0aa8d3e20b",
   "choices":(
      
   ),
   "usage":{
      "prompt_tokens":11,
      "completion_tokens":18,
      "total_tokens":29,
      "prompt_tokens_details":{
         "cached_tokens":0,
         "audio_tokens":0
      },
      "completion_tokens_details":{
         "reasoning_tokens":0,
         "audio_tokens":0,
         "accepted_prediction_tokens":0,
         "rejected_prediction_tokens":0
      }
   }
}

Kesimpulan

SSE memberikan solusi elegan untuk komunikasi server-ke-klien secara real-time. Kesederhanaan, efisiensi, dan integrasinya dengan infrastruktur yang ada menjadikannya pilihan yang sangat baik untuk banyak aplikasi. Meskipun WebSockets tetap berharga untuk komunikasi dua arah, SSE menawarkan solusi yang lebih fokus dan seringkali lebih tepat untuk skenario streaming data satu arah.

Ingin lebih banyak konten seperti ini? Daftar ke blog saya!

Sumber

Krystian Wiśniewski
Krystian Wiśniewski is a dedicated Sports Reporter and Editor with a degree in Sports Journalism from He graduated with a degree in Journalism from the University of Warsaw. Bringing over 14 years of international reporting experience, Krystian has covered major sports events across Europe, Asia, and the United States of America. Known for his dynamic storytelling and in-depth analysis, he is passionate about capturing the excitement of sports for global audiences and currently leads sports coverage and editorial projects at Agen BRILink dan BRI.