#pragma once // ── İş Takip ağ sürücüleri — TasimaArayuz'ün Winsock implementasyonları ────── // İş Takip Orchestrator'dan AYRI kanalda çalışır (istakip.port, docs/ // istakip_tasarim.md): kral kendi dinleyicisini açar, istemciler IP:port ile // bağlanır (LAN keşfi ŞART DEĞİL — uzaktan doğrudan IP girilir). Soket // primitifleri orkestra'nınkiyle ORTAK (TcpDinleyiciWin/TcpBaglantiWin + // AkisCozucu — kopya değil). tik() ana-iplik drain'inden çağrılır (kule deseni); // bayraklar kapalıyken bu sınıflar hiç kurulmaz → sıcak yola sıfır yük. #include #include #include #include #include #include "fiko/orkestra/akis.hpp" #include "fiko/orkestra/tasima.hpp" #include "orkestra_tcp_win.hpp" namespace fiko { // "ip:port" ayrıştır (istakip.kral_adres). Port yoksa varsayilanPort kullanılır. // false = boş/bozuk adres. bool istakipAdresCoz(const std::string& adres, std::string& ip, uint16_t& port, uint16_t varsayilanPort); // ── Kral tarafı: dinleyici + bağlantı başına kanal. NodeAdres.nodeId = geçici // bağlantı kimliği (artan sayaç; kalıcı kimlik ÇERÇEVE GÖVDESİNDEN gelir — // IsSnapshotIste/IsYaz istemciNo taşır, sürücü içerik bilmez). ──────────────── class IstakipTasimaKral : public orkestra::TasimaArayuz { public: using KopmaCb = std::function; bool ac(uint16_t port, size_t maksGovde, size_t maksBaglanti); void kapat(); bool acikMi() const { return dinleyici_.acikMi(); } // Ana-iplik nabzı: yeni bağlantıları kabul et + gelen baytları çerçevelere çöz // (alıcı callback'i BURADA çalışır) + kopan/bozuk kanalları düşür. void tik(); const char* ad() const override { return "istakip-kral-tcp"; } bool gonder(const orkestra::NodeAdres& hedef, const SurecCerceve& c) override; void kopmaAyarla(KopmaCb cb) { kopma_ = std::move(cb); } size_t baglantiSayisi() const { return kanallar_.size(); } uint64_t alinanCerceve() const { return alinanCerceve_; } uint64_t reddedilenBaglanti() const { return reddedilen_; } private: struct Kanal { uint64_t kimlik = 0; TcpBaglantiWin baglanti; orkestra::AkisCozucu cozucu; Kanal(uint64_t id, uintptr_t soket, size_t maksGovde) : kimlik(id), baglanti(soket), cozucu(maksGovde) {} }; TcpDinleyiciWin dinleyici_; std::vector> kanallar_; size_t maksGovde_ = 4u * 1024 * 1024; size_t maksBaglanti_ = 32; uint64_t sonKimlik_ = 0; uint64_t alinanCerceve_ = 0, reddedilen_ = 0; KopmaCb kopma_; }; // ── İstemci tarafı: krala tek bağlantı + otomatik yeniden bağlanma (backoff). // baglandiCb her (yeniden) bağlantıda çağrılır → IsIstemciKanal::baglan() // (snapshot iste + bekleyenleri it). koptuCb → IsIstemciKanal::koptu(). ─────── class IstakipTasimaIstemci : public orkestra::TasimaArayuz { public: using DurumCb = std::function; void hedefAyarla(const std::string& ip, uint16_t port, size_t maksGovde); void kapat(); bool bagliMi() const { return baglanti_.acikMi(); } // Ana-iplik nabzı: kopuksa denemeAralikMs arayla yeniden bağlan; bağlıysa // gelen baytları çöz (alıcı callback'i BURADA çalışır). void tik(uint64_t simdiMs, uint64_t denemeAralikMs = 5000); const char* ad() const override { return "istakip-istemci-tcp"; } bool gonder(const orkestra::NodeAdres& hedef, const SurecCerceve& c) override; void baglandiAyarla(DurumCb cb) { baglandi_ = std::move(cb); } void koptuAyarla(DurumCb cb) { koptu_ = std::move(cb); } uint64_t alinanCerceve() const { return alinanCerceve_; } private: void dus(); // bağlantıyı kapat + koptuCb std::string ip_; uint16_t port_ = 0; size_t maksGovde_ = 4u * 1024 * 1024; TcpBaglantiWin baglanti_; orkestra::AkisCozucu cozucu_; uint64_t sonDenemeMs_ = 0; uint64_t alinanCerceve_ = 0; DurumCb baglandi_, koptu_; }; } // namespace fiko