Taşıma: WebSocket, HTTP yedeği ve yeniden bağlanma
Widget’ın sohbet sunucusuyla iletişimi: adresler, rc.v1 alt protokolü, çerçeve biçimi, hata ve kapanış kodları, sınırlar, seq ile yeniden bağlanma, yineleme önleme, SSE ve uzun yoklamayla HTTP yedeği.
Bu sayfa tarayıcıdaki widget ile sohbet sunucusu arasında olanları açıklar. Sorun giderme (geliştirici araçlarının ağ sekmesi), proxy ve güvenlik duvarı kuralları, Content Security Policy için gereklidir.
Önemli: İletişim protokolü bizim widget’ımızla bizim sunucumuz arasındaki arayüzdür. Protokolü doğrudan kullanan özel istemciler resmen desteklenmez; alanlar protokol sürümü 1 içinde genişletilebilir. Kendi arayüzleriniz için JavaScript API’sini, sunucu bağlantıları için webhook’ları ve sunucu API’sini kullanın.
Adresler
- WebSocket:
wss://ws.reactive.chat/rc_wss/ - HTTP yedeği, çevrimdışı form, yüklemeler: Aynı adres
https://, yanihttps://ws.reactive.chat/rc_wss/h/…,https://ws.reactive.chat/api/offline/<SITE_KEY>vehttps://ws.reactive.chat/rc_wss/upload/… - Widget dosyaları:
https://cdn.reactive.chat/
Widget WebSocket adresini nasıl bulur?
- Yükleyici etiketindeki
data-rc-ws-url,window.ReactiveChatSettings.wsUrlveyaReactiveChat('boot', { wsUrl }); ayarlanmışsa bu değer geçerlidir. - Aksi durumda
loader.jskonumundan türetilir:wss://ws.+ alan adının son iki bölümü +/rc_wss/.cdn.reactive.chat,wss://ws.reactive.chat/rc_wss/olur.
Bundan iki sorun doğar:
loader.jsdosyasını kendi alan adınızdan sunuyorsanız widget sizin alan adınız altında adres türetir. Bu durumdadata-rc-ws-urlayarlayın (Hızlı başlangıç bölümüne bakın)..co.ukgibi iki parçalı uzantılarda türetme yanlış olur.data-rc-ws-urlaçıkça ayarlayın.
WebSocket yolu sorgu parametrelerini değerlendirmez.
Bağlantı kurma
- Zamanlama: Widget sayfa yüklenirken değil, ilk gerçek etkileşimde bağlanır (fare hareketi, tıklama, tuş, fare tekerleği, dokunma, odak). Sohbet penceresi açıksa veya açılıyorsa, ziyaretçinin sohbeti biliniyorsa ya da gönderilmemiş mesajlar bekliyorsa hemen bağlanır. Herhangi bir öğedeki (genellikle yükleyici etiketi)
data-rc-connect="load"veyawindow.ReactiveChatSettings.connect = 'load'ile eskisi gibi yüklemede bağlanır. Sayfa görüntülemesinden belirli süre sonra tetiklenen kurallar ilk etkileşimden itibaren sayar. - Alt protokol: Widget
new WebSocket(url, 'rc.v1')açar; sunucurc.v1yansıtır. Protokol sürümü adreste değil, her çerçevededir (v: 1). - UTF-8 olarak yalnızca metin çerçeveleri; bir çerçeve = bir mesaj. Sıkıştırma yoktur (sunucuda
permessage-deflatekapalı). - El sıkışma:
opensonrasında widget en geç 5 saniyedeinitgönderir; sunucuinit_okyanıtlar.open8 saniyede gelmezse deneme başarısız sayılır;init_ok10 saniyede gelmezse widget yeniden bağlanır. - Kaynak kontrolü: Sunucu
Originbaşlığının ana makine adını proje alan adlarıyla karşılaştırır (hesabınızdaki İzin verilen kaynaklar). Şema ve port sayılmaz; alt alan adları eşleşir (www.your-company.com,your-company.comile eşleşir;notyour-company.comeşleşmez). Başarısızsaorigin_deniedhatası, ardından 1008 kapanışı; yeniden deneme yok. Projeye hiç alan adı girilmemişse kaynak kontrolü yapılmaz; bu nedenle alan adlarınızı her zaman girin.
Çerçeve biçimi
Her iki yöndeki her mesaj şu biçimdedir:
{ "v": 1, "t": "msg", "id": "01JAB3C4D5E6F7G8H9JKMNPQRS", "ts": 1792500000000, "d": { } }
- v (tam sayı, zorunlu) – protokol sürümü; şu anda
1. - t (dize, zorunlu) – mesaj türü,
[a-z0-9_]{1,24}. - id (dize, zorunlu) – ULID: yalnızca büyük harfli 26 Crockford Base32 karakteri. Yineleme önleme anahtarı da budur.
- ts (tam sayı, zorunlu) – 1970’ten bu yana milisaniye; yalnızca tanılama için.
- d (nesne, zorunlu) – veri yükü; asla
nulldeğil, boşken{}.
Bilinmeyen tür ve alanlar sessizce yok sayılır; böylece eski widget’lar yeni sunucularla uyumlu kalır.
Mesaj türlerine genel bakış
Widget’tan sunucuya:
- init – bağlantı kaydı: site anahtarı, oturum, ziyaretçi, sekme ve sohbet kimliği, dil, onay durumu, varsa imzalı kimlik (
user), sayfa bağlamı (ctx), devam noktası (resume). - msg – ziyaretçi mesajı (metin, en fazla 5 ek, hızlı yanıtlara veya formlara yanıt).
- typing – yazma göstergesi (
start/stop). Giriş alanının içeriği asla iletilmez. - read –
seqdeğerine kadar okundu. - ctx – örneğin SPA gezinmesinde veya
identifysonrasında bağlam değişimi. - csat – değerlendirme (beğenme/beğenmeme; yorum en fazla 1.000 karakter).
- upload_req – yükleme onayı isteği (ad, MIME türü, boyut, SHA-256).
- transcript, forget, consent – sohbeti e-postayla gönderme, kendi verilerini silme, onay verme/geri alma.
- ping – bağlantıyı canlı tutma.
Sunucudan widget’a:
- init_ok – doğrulanmış kimlikler, geçmiş, tasarım, özellikler ve sınırlar (aşağıda), kimlik kontrolünün sonucu (
identity.verified). - msg – mesajlar (ziyaretçinin kendi mesajının
client_idile yankısı dâhil). - bot_typing, bot_stream – YZ asistanı düşünüyor veya yazıyor;
bot_streamo ana kadar görünen metnin tamamını, en fazla 150 ms’de bir iletir. - typing, read, handoff, queue_pos, proactive, conv_list, error, pong.
Hata kodları
Hata, d.code, d.message (İngilizce, yalnızca geliştiriciler için), d.retry (no, immediate, backoff, after_reinit) ve gerektiğinde d.retry_after_ms, d.detail içeren t: "error" çerçevesi olarak gelir. Liste kapalıdır; bilinmeyen kod internal gibi ele alınır.
- bad_json – geçerli JSON değil; üç kez olunca 1008 kapanışı.
- bad_envelope – çerçeve biçimi ihlal ediyor (ULID 24 saatten fazla farklıysa da;
detail.reason: stale_or_future). - unsupported_version – sürümde uzlaşılamıyor; 4001 kapanışı.
- unknown_site_key – site anahtarı bilinmiyor, proje duraklatılmış veya arşivlenmiş; 4002 kapanışı.
- origin_denied – kaynak projenin alan adları arasında değil; 1008 kapanışı.
- visitor_blocked – ziyaretçi engelli; 1008 kapanışı.
- auth_failed – kimlik kontrolü başarısız;
detail.reason:no_hash,bad_hash,bad_exp,expired,exp_too_far. Oturum anonim devam eder. - not_initialized / already_initialized –
initöncesi mesaj veya ikinciinit. - init_timeout – 5 sn içinde
inityok; 4004 kapanışı. - conversation_not_found / conversation_closed
- rate_limited –
retry_after_msile hız sınırı. Aynı bağlantıda tekrarlanırsa sunucu 4008 ile kapatır. - payload_too_large – çerçeve 64 KiB’tan büyük.
- msg_too_long – metin plan sınırından uzun;
detail.max. - unsupported_kind, attachment_invalid
- upload_disabled, upload_too_large, upload_mime_denied, upload_expired
- consent_required – eylem onay gerektiriyor.
- dnd_active – “Rahatsız etmeyin” etkin.
- session_conflict – aynı oturumun çok fazla bağlantısı (3’ten fazla); 4003 kapanışı; sekme izleyici olur.
- internal, unavailable – geçici; bekleyerek yeniden dene.
Kapanış kodları
- 1000, 1001, 1006, 1011, 1013, 4004 – widget yeniden bağlanır (bekleyerek).
- 1008 – kaynak reddedildi, tekrarlanan geçersiz JSON, kötüye kullanım koruması engeli. Bu sayfada yeniden deneme yok.
- 4001 – sürümde uzlaşılamıyor. Yeniden deneme yok.
- 4002 – site anahtarı bilinmiyor veya proje etkin değil. Yeniden deneme yok.
- 4008 – tekrarlanan hız sınırlama. Widget
retry_after_mskadar bekleyip yeniden bağlanır. - 4003 – oturum çakışması; sekme diğer sekmenin izleyicisi olarak çalışır.
Bağlantı başına sınırlar
Sunucu esas alınacak değerleri init_ok.limits ve init_ok.features içinde gönderir:
- heartbeat_ms 25.000 – widget son giden mesajdan 25 sn sonra
pinggönderir. - pong_timeout_ms 10.000 – iki eksik
pongyeniden bağlanmaya yol açar. - idle_timeout_ms 70.000 – sunucu 70 sn gelen çerçeve olmadan kapatır (1001).
- max_frame_bytes 65.536 – büyük çerçeveler:
payload_too_large. - msg_per_10s 20 ve frames_per_10s 120 – bağlantı başına token kovası; üzerinde
rate_limited. - reconnect_cap_ms 30.000 – denemeler arasındaki en uzun bekleme.
- dedup_window_ms 86.400.000 – 24 saat yineleme önleme.
- features.max_msg_len – ziyaretçi mesajı başına karakter (Unicode kod noktası): Free planında 1.000, ücretli planlarda 4.000. Widget fazla uzun metinleri göndermez.
- features.max_upload_bytes, features.allowed_mime – Sınırlar ve kotalar bölümüne bakın.
Yeniden bağlanma, sıra, yinelemeler
- Bekleme:
min(30000, 500 × 2^(attempt−1))ms; üst yarıdan rastgele değer kullanılır (1. deneme: 250–500 ms; 7. denemeden itibaren: 15–30 sn). Arka plan sekmelerinde üç kat uzun. Sunucununretry_after_msdeğeri alt sınırdır. Deneme sayısı sınırsızdır; sayaç yalnızcainit_okile sıfırlanır. Tarayıcıonlinebildirirse widget hemen dener; çevrimdışıysa bekler. - Sıra: Sohbetin her mesajında 1’den başlayan kesintisiz
seqbulunur. Mesajlar zamana değilseqdeğerine göre gösterilir. Yeniden bağlanırken widgetresume.last_seqve en fazla 50 bekleyen kimlik gönderir; sunucu sonrasındaki her şeyi iletir (en fazla 100 mesaj; aksi durumdahas_more) ve ulaşmış mesajların onaylarını tekrarlar. - Yineleme yok: Sunucu her mesajın
iddeğerini 24 saat hatırlar. Tekrarlanan mesaj yeniden saklanmaz, aynı onayı alır. Widget’taki “Tekrar gönder” aynıidkullanır. - Giden mesaj durumları:
pending→sent→delivered(sunucudan yankı) →read; 5 denemeden, 24 saatten sonra veyaretry: "no"durumundafailed. - Çevrimdışı arabellek: Bağlantı kesilirse mesajlar arabelleğe alınır (en fazla 50 kayıt, 128 KiB, 24 saat); onayla
localStorage, onaysızsessionStorageiçinde. Sonrakiinit_okile gönderilir. - Birden fazla sekme, tek bağlantı: Web sitesinin sekmeleri lider seçer (Web Locks; yoksa
localStorageiçinde canlı tutma); yalnızca lider bağlantıyı tutar, diğerleriBroadcastChannelile iletişim kurar.
HTTP yedeği
Ağ WebSocket’e izin vermiyorsa sohbet normal HTTPS istekleriyle devam eder; aynı çerçeve ve sınırlarla. Yalnızca widget kullanır; temsilci arayüzü her zaman WebSocket ile bağlanır. Editörler için kısa sürüm HTTP yedeği bölümündedir.
Devreye girdiği durumlar:
- tarayıcı WebSocket desteklemiyor;
- bu sayfada henüz hiç WebSocket kurulmadan önce, arka arkaya iki WebSocket denemesi başarısız (8 saniye sonra sonuçsuz deneme başarısız sayılır);
sessionStorageiçinde 30 dakikadan yenirc_httpkaydı var (aynı sekmedeki sonraki sayfalar);data-rc-transport="http"ile (başlangıçta belgede bulunan herhangi bir öğede) veya yükleyiciden öncewindow.ReactiveChatSettings = { transport: 'http' }ile zorluyorsunuz.ReactiveChat('boot', { transport: 'http' })etkisizdir; bağlantı türü başlangıçta belirlenir.
Tarayıcıda fetch yoksa yedek yoktur. Mevcut WebSocket kesilirse widget yine WebSocket ile bağlanır. Yedeğe geçtikten sonra WebSocket’in artık geçip geçmediğini sayfa başına bir kez sessizce kontrol eder; geçerse rc_http silinir ve sonraki sayfa yeniden WebSocket kullanır.
İstekler (https://ws.reactive.chat/rc_wss/h/ altında):
- POST h/auf – bağlantıyı açar. Yanıt
{"v":1,"cid":"…","tok":"…","poll_ms":25000,"idle_ms":60000}.tokkısa ömürlü bağlantı token’ıdır (32 karakter). - GET h/<cid>/sse?tok=… – Server-Sent Events; çerçeve başına
id:vedata:, her 15 sn’de canlı tutma. Kaçırılan çerçevelerLast-Event-IDile iletilir. - GET h/<cid>/poll?tok=…&nach=<n> – uzun yoklama; sunucu isteği en fazla 25 sn açık tutar ve
{"v":1,"n":…,"rahmen":[…]}ile yanıtlar. - POST h/<cid>/tx?tok=… – gönderim,
text/plain, tek çerçeve veya en fazla 20 çerçevelik dizi; yanıt 204. - POST h/<cid>/zu?tok=… – kapatma (
sendBeaconüzerinden).
Widget önce SSE dener; ilk çerçeve 5 saniyede gelmezse (örneğin proxy arabelleğe alıyorsa) uzun yoklamaya geçer. 404 (unbekannt), 403, 413 veya 429 gibi hataları kesilen bağlantı gibi ele alır; bekleyerek yeniden dener. 60 saniye istek gelmezse sunucu bağlantıyı kapatır. CORS: Access-Control-Allow-Origin kaynağı, erişim bilgileri olmadan yansıtır; kaynak kontrolü WebSocket’teki gibi init içinde yapılır.
Sizin tarafınızdaki gereksinimler:
- CSP’nizin
connect-srcalanında sohbet adresi iki biçimde bulunur:wss://vehttps://. - Güvenlik duvarları ve proxy’ler en az 30 saniye süren isteklere izin verir.
- Kendi proxy’niz
/rc_wss/yolunu arabelleğe almadan iletir (nginxproxy_buffering offveproxy_cache off, Apacheflushpackets=on, Caddyflush_interval -1);/rc_wss/h/erişim günlüğüne yazılmaz (sorguda token). Özel alan adı bölümüne bakın.
Tarayıcıda saklanan: Yalnızca sessionStorage içinde HTTPS bağlantısının zamanıyla rc_http kaydı; kişisel veri yoktur.
Hangi yol etkin?
Geliştirici araçlarının ağ sekmesinde:
- WebSocket:
wss://ws.reactive.chat/rc_wss/adresine (veya alt alan adınıza) WebSocket türünde bağlantı. Çerçevelerdeinit,init_ok,ping/pongve mesajlar görünür. - HTTP yedeği: Önce
h/auf, sonra uzun süren…/sse(veya tekrarlanan…/poll), her gönderilen mesaj için…/tx.
Sonraki: Sınırlar ve kotalar · Sorun giderme
Paskutinį kartą atnaujinta: