Mikro WebSocket Engine
Go to file
abdussamedulutas 5ebd111af0 endPair/disconnect: WebRTC tamamen kapatılıyor + tiles temizleniyor
sdk/Peer.js — endPair():
  - this.rtc?.destroy() eklendi
  - Yerel akışlar durur, RTCPeerConnection kapanır

sdk/index.js — sinyal handler'ları:
  - end/pair: peer.rtc?.destroy() (alan taraf da kapatır)
  - peer/disconnect: peer.rtc?.destroy() (WebSocket kopunca RTC da kapanır)

public/studio/Studio.js:
  _clearPeerTiles(peerId):
    - data-peer-id dataset'i ile local + remote grid'den tile'ları kaldırır
    - Gizli <audio> elemanını srcObject=null + remove() ile temizler
    - CSS.escape ile güvenli selector
  tile.dataset.peerId: _addLocalTile ve _addRemoteTile her ikisinde eklendi
  tile._audioEl: ses tile'larında referans saklanır (clearPeerTiles için)
  _watchIncoming: peer.rtc.on('disconnected') → clearPeerTiles + rebuildPeerItems
  end/pair handler: clearPeerTiles(from) çağrısı eklendi
  peer/disconnect handler: clearPeerTiles(peer.socketId) çağrısı eklendi
  _addLocalTile/_addRemoteTile: peerLabel yerine peer objesi alır

go test -race ./... — yeşil

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-17 14:59:47 +03:00
internal Studio ürünü sdk/'dan public/studio/'a taşındı + /studio route 2026-06-17 13:13:56 +03:00
loadtest Go engine portu (0.1.0 çekirdek) — Node.js engine'i race-free Go'ya taşı 2026-06-17 07:09:36 +03:00
public endPair/disconnect: WebRTC tamamen kapatılıyor + tiles temizleniyor 2026-06-17 14:59:47 +03:00
sdk endPair/disconnect: WebRTC tamamen kapatılıyor + tiles temizleniyor 2026-06-17 14:59:47 +03:00
tools Ajan çalışma sözleşmesi + gitea CLI + yol haritası dosyaları 2026-06-17 08:08:05 +03:00
.agent-prompt-port.txt Ajan çalışma sözleşmesi + gitea CLI + yol haritası dosyaları 2026-06-17 08:08:05 +03:00
.agent-prompt.txt Ajan çalışma sözleşmesi + gitea CLI + yol haritası dosyaları 2026-06-17 08:08:05 +03:00
.gitea-auth.example.json Ajan çalışma sözleşmesi + gitea CLI + yol haritası dosyaları 2026-06-17 08:08:05 +03:00
.gitignore Eski Node.js / TypeScript yapı dosyaları temizlendi 2026-06-17 12:28:37 +03:00
CLAUDE.md Ajan çalışma sözleşmesi + gitea CLI + yol haritası dosyaları 2026-06-17 08:08:05 +03:00
LICENSE Initial commit 2022-11-16 20:31:27 +01:00
PORT-PROGRESS.md Go engine portu (0.1.0 çekirdek) — Node.js engine'i race-free Go'ya taşı 2026-06-17 07:09:36 +03:00
README.md #35: README — Go engine + yeni SDK yapısı 2026-06-17 13:05:38 +03:00
REVIEW.md #33: EventPool WOM — askıda kalan promise düzeltmesi 2026-06-17 08:11:29 +03:00
decisions.md #43/#44/#45: Notify (store-and-forward + suit) ve data-sync alt sistemleri 2026-06-17 08:30:20 +03:00
go.mod Go engine portu (0.1.0 çekirdek) — Node.js engine'i race-free Go'ya taşı 2026-06-17 07:09:36 +03:00
go.sum Go engine portu (0.1.0 çekirdek) — Node.js engine'i race-free Go'ya taşı 2026-06-17 07:09:36 +03:00
main.go #46: 3. parti sunucu köprüsü (bridge) 2026-06-17 12:05:59 +03:00
todo.md Ajan çalışma sözleşmesi + gitea CLI + yol haritası dosyaları 2026-06-17 08:08:05 +03:00

README.md

MWSE — Micro Web Socket Engine

MWSE, kendisine bağlanan eşleri birbirleriyle eşleştirerek eşler arası veri tünelleri oluşturan geniş ölçekli bir WebSocket mikroservis altyapısıdır.

Servis; cihazları senkronize etmek, odalar oluşturmak, sohbet ve görüntülü görüşme yazılımları için gerçek zamanlı altyapı sağlamak amacıyla kullanılır. Sunucu cihazları sanallaştırdığı için eşler birbirlerinin gerçek IP adresini veya cihaz bilgisini bilmeden düşük gecikmeli, çift yönlü iletişim kurabilir.

Durum (Go engine, v1.0.0)

Motor Node.js'ten Go ile yeniden yazıldı. Concurrency modeli goroutine + sync.RWMutex + bağlantı başına tek-yazıcı (actor) deseni üzerine kuruludur; Node.js'teki "leave-while-send" race condition ve EventPool promise takılması (#33) giderildi. Yük testi: 150 bağlantı, ~210 k msg/s relay, RSS ~43 MB.

Özellik Durum
WebSocket bağlantı yaşam döngüsü
Oda oluşturma / katılma / çıkma
Eşleme (pair) sistemi
Paket tünelleme (pack/to, pack/room)
Veri senkronizasyonu (data/sync, sync/pool)
Bildirim + suit yanıtı (notify/send, notify/reply)
3. parti sunucu köprüsü (bridge)
Sanal IP / numara / kısa kod + alt ağ
WebRTC kütüphanesi (perfect negotiation, çoklu track)
Studio UI (Miller kolonlar)
İkili çerçeveleme (binary framing) 2.5.0
SRS entegrasyonu (binlerce izleyici) 2.0.0

Kurulum ve çalıştırma

Gereksinimler

  • Go 1.22+

Sunucuyu başlat

go mod tidy
go run .
# Varsayılan: 0.0.0.0:7707

Ortam değişkenleri

Değişken Varsayılan ıklama
MWSE_HOST 0.0.0.0 Bind adresi
MWSE_PORT 7707 Dinleme portu
MWSE_PUBLIC_DIR ./public Statik dosyalar (/status.xml vb.)
MWSE_SDK_DIR ./sdk ES modül SDK (/sdk/)
MWSE_OUTBOUND_BUFFER 1024 Bağlantı başına gönderim kuyruğu
MWSE_MAX_MESSAGE_SIZE 16777216 Maksimum gelen frame boyutu (bayt)
MWSE_PING_INTERVAL 10s Heartbeat ping aralığı
MWSE_SHUTDOWN_TIMEOUT 10s Graceful shutdown bekleme süresi
BRIDGE_APPROVE_URL Bağlantı onay URL'i (3. parti köprü)
BRIDGE_TRIGGER_URL Suit yanıtı push URL'i
BRIDGE_INBOX 1 ile inbox'ı etkinleştir

Testler

go test -race ./...

Frontend SDK entegrasyonu

SDK saf vanilla ES modülü olarak /sdk/ endpoint'inden sunulur. Bundler gerekmez; native import ile çalışır.

<script type="module">
import MWSE from 'http://localhost:7707/sdk/index.js';

const mwse = new MWSE();  // endpoint: otomatik aynı sunucudan

mwse.on('scope', async () => {
    console.log('Bağlandı:', mwse.me.socketId);
    const room = mwse.room({ name: 'genel', joinType: 'free', ifexistsJoin: true });
    await room.createRoom();
    room.on('message', (pack, peer) => console.log(peer.socketId, ':', pack));
    room.send({ text: 'merhaba!' });
});
</script>

WebRTC (P2P ses/video/dosya)

import MWSE from '/sdk/index.js';
import { MediaSources } from '/sdk/webrtc/index.js';

const mwse = new MWSE();

mwse.me.on('accepted/pair', async peer => {
    const polite = mwse.me.socketId < peer.socketId;
    peer.rtc.connect({ polite });

    // Kamera + mikrofon
    const stream = await MediaSources.cameraAndMic();
    peer.rtc.addStream('cam', stream);

    // Gelen video/ses
    peer.rtc.on('track', (track, streams) => {
        const video = document.createElement('video');
        video.srcObject = streams[0];
        video.autoplay = true;
        document.body.appendChild(video);
    });

    // Dosya gönderme
    await peer.rtc.sendFile(file);
});

Studio UI

import MWSE   from '/sdk/index.js';
import Studio from '/sdk/studio/index.js';

const mwse   = new MWSE();
const studio = new Studio(mwse, '#app');
mwse.on('scope', () => studio.mount());

Demo dosyaları

Sunucu çalışırken http://localhost:7707/demos/ altında:

Demo Dosya ıklama
Chat chat.html ~20 satır JS ile odalı gerçek zamanlı sohbet
Sesli görüşme audio.html P2P WebRTC mikrofon (çift yönlü)
Video görüşme video.html P2P WebRTC kamera ızgara görünümü

API kontrolü (/api)

# API anahtarı al
KEY=$(curl -s -X POST localhost:7707/api/auth/key \
  -H 'Content-Type: application/json' \
  -d '{"domain":"myapp"}' | jq -r .key)

# Tüm odaları listele
curl -s localhost:7707/api/rooms | jq .

# Belirli bir istemciye mesaj gönder
curl -s -X POST localhost:7707/api/client/<id>/send \
  -H "x-api-key: $KEY" \
  -H 'Content-Type: application/json' \
  -d '{"pack": {"hello": "world"}}'

# 3. parti köprü — inbox boşalt
curl -s -X POST localhost:7707/api/bridge/inbox \
  -H "x-api-key: $KEY"

Mimari

Tarayıcı (WebSocket)
  │
  ▼
ws.Hub — router + client registry
  ├─ services/yourid.go       Bağlantıılınca wsts/hello + id sinyalleri
  ├─ services/auth.go         Pairing, erişilebilirlik
  ├─ services/room.go         Oda oluşturma / yönetimi
  ├─ services/datatransfer.go pack/to, request/to, response/to tünelleri
  ├─ services/notify.go       Store-and-forward bildirim + suit yanıtı
  ├─ services/datastore.go    Aktif & pasif veri senkronizasyonu
  ├─ services/bridge.go       3. parti sunucu inbox
  ├─ services/ippressure.go   Sanal IP / numara / kısa kod + alt ağ (/24)
  └─ services/session.go      Oturum bayrakları (readable/writable/pairinfo)

httpserver
  ├─ GET /sdk.js              → /sdk/index.js (301 yönlendirme)
  ├─ GET /sdk/*               ES modül SDK dosyaları
  ├─ GET /demos/*             Demo HTML dosyaları
  ├─ GET|POST /api/*          Kontrol düzlemi
  └─ GET /*                   Statik public/ dosyaları

sdk/
  ├─ index.js                 MWSE ana sınıf (bağlantı + sinyal yönlendirme)
  ├─ webrtc/                  WebRTC kütüphanesi
  │   ├─ index.js             RTCEngine (PeerConnection yönetimi, ICE restart)
  │   ├─ PeerConnection.js    RTCPeerConnection wrapper + full event izleme
  │   ├─ Negotiator.js        Perfect negotiation (RFC 8829)
  │   ├─ StreamManager.js     addStream/replaceTrack/setEncodings
  │   ├─ DataChannel.js       Birincil veri kanalı + oto-yeniden bağlanma
  │   ├─ MediaSources.js      getUserMedia/getDisplayMedia/AudioContext fabrikaları
  │   ├─ FileSender.js        Paralel DataChannel dosya transferi
  │   └─ CanvasCompositor.js  Çoklu video track birleştirme (grid/pip/focus)
  └─ studio/
      ├─ index.js             Studio UI giriş noktası
      ├─ ColumnView.js        Miller kolon yöneticisi
      ├─ Column.js            Tek kolon (başlık + arama + liste)
      └─ style.css            Koyu masaüstü teması

Güvenlik

  • İstemci mesajları uygulama katmanında doğrulanmaz. Hassas veriler için imzalama/şifreleme ekleyin.
    1. parti köprü (BRIDGE_APPROVE_URL) kullanılıyorsa bağlantı onayı uygulama sunucusuna delege edilir (fail-closed).
  • .gitea-auth.json dosyası commit'e asla girmez (.gitignore'da).

Geliştirici dökümanı

Wiki: https://git.saqut.com/saqut/MWSE/wiki