Allmine API
Live Stream

Live Stream started entegrasyonu

Yayın başlama akışı ve client bildirimleri

Live Stream Started Event Entegrasyonu

Bu doküman, guest kullanıcı join-as-guest akışıyla yayını gerçekten başlattığında /live-stream namespace'inde yayınlanan streamStarted event'inin entegrasyonunu açıklar.

Amaç

  • Yayının başladığı anı stream odasındaki client'lara gerçek zamanlı bildirmek.
  • startedAt set edildiği ilk geçişte tek sefer bildirim üretmek.
  • Client tarafında yayın başlangıç zamanını anlık UI güncellemelerinde kullanmak.

Tetiklenme Koşulları

streamStarted event'i yalnızca aşağıdaki durumda yayınlanır:

  1. Guest kullanıcı POST /live-stream/join-as-guest ile katılır.
  2. Yayın statüsü başlatılabilir bir durumda olur (preparing, bazı duo senaryolarında scheduled).
  3. startedAt alanı veritabanında null iken atomik olarak set edilir.

startedAt zaten doluysa event tekrar gönderilmez.

Namespace ve Oda

  • Namespace: /live-stream
  • Room: stream:{streamId}

streamStarted event'i sadece ilgili stream room'a yayınlanır.

Socket Bağlantı Adımları

  1. /live-stream namespace'ine bağlan.
  2. joinStream event'i ile ilgili odaya katıl.
  3. streamStarted event'ini dinle.
import { io } from 'socket.io-client';

const socket = io(`${SOCKET_BASE_URL}/live-stream`, {
  transports: ['websocket'],
});

socket.emit('joinStream', { streamId });

socket.on('streamStarted', (payload) => {
  console.log('Yayın başladı:', payload);
});

Event Payload

{
  streamId: string;
  startedAt: string;  // ISO 8601
  plannedEndDate: string | null; // ISO 8601 veya null
  timestamp: string;  // ISO 8601
}

React Native Örneği

import { useEffect } from 'react';
import { io } from 'socket.io-client';

export function useStreamStarted(streamId: string, onStarted: (startedAt: string) => void) {
  useEffect(() => {
    const socket = io(`${process.env.EXPO_PUBLIC_SOCKET_URL}/live-stream`, {
      transports: ['websocket'],
    });

    socket.emit('joinStream', { streamId });

    const handleStarted = (data: { streamId: string; startedAt: string; plannedEndDate: string | null; timestamp: string }) => {
      if (data.streamId !== streamId) return;
      onStarted(data.startedAt);
    };

    socket.on('streamStarted', handleStarted);

    return () => {
      socket.emit('leaveStream', { streamId });
      socket.off('streamStarted', handleStarted);
      socket.disconnect();
    };
  }, [streamId, onStarted]);
}

Web / Next.js Örneği

'use client';

import { useEffect } from 'react';
import { io } from 'socket.io-client';

export function StreamStartedListener({ streamId }: { streamId: string }) {
  useEffect(() => {
    const socket = io(`${process.env.NEXT_PUBLIC_SOCKET_URL}/live-stream`, {
      transports: ['websocket'],
    });

    socket.emit('joinStream', { streamId });

    const onStarted = (data: { streamId: string; startedAt: string; plannedEndDate: string | null; timestamp: string }) => {
      if (data.streamId !== streamId) return;
      console.log('startedAt:', data.startedAt);
      console.log('plannedEndDate:', data.plannedEndDate);
    };

    socket.on('streamStarted', onStarted);

    return () => {
      socket.emit('leaveStream', { streamId });
      socket.off('streamStarted', onStarted);
      socket.disconnect();
    };
  }, [streamId]);

  return null;
}

Client Tarafında Idempotent İşleme Notu

Network tekrar bağlantıları veya farklı ekran akışlarında aynı event birden fazla işlenmek istenmiyorsa:

  • streamId bazında son işlenen startedAt değerini local state/store'da tutun.
  • Yeni event'in startedAt değeri aynıysa UI güncellemesini tekrar çalıştırmayın.

Hata ve Fallback Davranışı

  • Sunucu socket katmanı hazır değilse event yayınlanmaz, log kaydı bırakılır.
  • Event kaçırma riskine karşı client açılışında ilgili stream detay endpoint'inden startedAt alanını da kontrol edin.
  • Event geldiği anda state güncellemesi yapılır, REST verisi geldiğinde çakışma varsa startedAt açısından en güncel değeri koruyun.

On this page