{"id":5970,"date":"2026-11-01T14:11:10","date_gmt":"2026-11-01T11:11:10","guid":{"rendered":"https:\/\/www.dchost.com\/blog\/?p=5970"},"modified":"2026-11-01T07:07:41","modified_gmt":"2026-11-01T04:07:41","slug":"sse-proxy-tamponlama-sorunu","status":"publish","type":"post","link":"https:\/\/www.dchost.com\/blog\/sse-proxy-tamponlama-sorunu\/","title":{"rendered":"SSE Yan\u0131tlar\u0131 Neden Toplu Geliyor? Proxy Tamponlama"},"content":{"rendered":"<div class=\"dchost-blog-content-wrapper\"><div class=\"aiw-summary\">\n<p class=\"aiw-box-title\">H\u0131zl\u0131 \u00f6zet<\/p>\n<p>SSE (Server-Sent Events), sunucunun a\u00e7\u0131k bir HTTP ba\u011flant\u0131s\u0131 \u00fczerinden taray\u0131c\u0131ya olay g\u00f6ndermesidir. Bu olaylar toplu geliyorsa veri, uygulamada veya aradaki bir katmanda bekliyor olabilir. Proxy tamponlamas\u0131, yani arac\u0131 sunucunun yan\u0131t par\u00e7alar\u0131n\u0131 iletmeden \u00f6nce biriktirmesi, olas\u0131 nedenlerden biridir. S\u0131k\u0131\u015ft\u0131rma ve taray\u0131c\u0131n\u0131n ekran\u0131 g\u00fcncelleme bi\u00e7imi de benzer bir belirti olu\u015fturabilir. \u0130lk ad\u0131m, gecikmenin hangi katmanda ba\u015flad\u0131\u011f\u0131n\u0131 bulmakt\u0131r.<\/p>\n<ul>\n<li>Uygulamaya do\u011frudan eri\u015fimi ve Nginx \u00fczerinden gelen ak\u0131\u015f\u0131, komut sat\u0131r\u0131ndan HTTP iste\u011fi g\u00f6nderen curl arac\u0131yla kar\u015f\u0131la\u015ft\u0131r\u0131n.<\/li>\n<li>Her olay\u0131n bo\u015f sat\u0131rla tamamland\u0131\u011f\u0131n\u0131 ve uygulaman\u0131n veriyi bekletmeden g\u00f6nderdi\u011fini kontrol edin.<\/li>\n<li>Tamponlama de\u011fi\u015fikli\u011fini b\u00fct\u00fcn siteye de\u011fil, yaln\u0131zca SSE ak\u0131\u015f\u0131n\u0131n sunuldu\u011fu adrese uygulay\u0131n.<\/li>\n<li>Sunucuda d\u00fczenli gelen olaylar\u0131n taray\u0131c\u0131da ve kullan\u0131c\u0131lar\u0131n ba\u011fland\u0131\u011f\u0131 d\u0131\u015f eri\u015fim yolunda da d\u00fczenli ula\u015ft\u0131\u011f\u0131n\u0131 kontrol edin.<\/li>\n<\/ul>\n<\/div>\n<p>Canl\u0131 bildirimleriniz bir s\u00fcre g\u00f6r\u00fcnm\u00fcyor, ard\u0131ndan ayn\u0131 anda m\u0131 beliriyor? Yapay zek\u00e2 yan\u0131t\u0131n\u0131z par\u00e7a par\u00e7a gelmesi gerekirken tek seferde mi g\u00f6r\u00fcn\u00fcyor? SSE, bu g\u00fcncellemeleri geldik\u00e7e g\u00f6stermeyi sa\u011flar. Ancak uygulaman\u0131n veri \u00fcretmesi, o verinin hemen ekrana ula\u015ft\u0131\u011f\u0131 anlam\u0131na gelmez; verinin \u00fcretilmesini, iletilmesini ve ekranda g\u00f6sterilmesini ayr\u0131 ayr\u0131 kontrol etmek gerekir.<\/p>\n<p>T\u00fcm sunucunun ayarlar\u0131n\u0131 de\u011fi\u015ftirmek yerine, \u00f6rnek bir Python uygulamas\u0131na do\u011frudan ve Nginx \u00fczerinden ba\u011flanarak ilerleyece\u011fiz. B\u00f6ylece gecikmenin hangi yolda ba\u015flad\u0131\u011f\u0131n\u0131 bulabilecek, gerekli ayar\u0131 yaln\u0131z ilgili yolda de\u011fi\u015ftirebilecek ve yeni bir ba\u011flant\u0131yla olaylar\u0131n d\u00fczenli ula\u015f\u0131p ula\u015fmad\u0131\u011f\u0131n\u0131 kontrol edebileceksiniz.<\/p>\n<div id=\"toc_container\" role=\"navigation\" aria-label=\"Table of Contents\" data-nosnippet class=\"toc_transparent no_bullets toc_numbered toc_title_center\"><p class=\"toc_title\">\u0130\u00e7indekiler<\/p><ul class=\"toc_list\"><li><a href=\"#SSE_akisini_anlamak_ve_ornek_ortami_kurmak\"><span class=\"toc_number toc_depth_1\">1.<\/span> SSE ak\u0131\u015f\u0131n\u0131 anlamak ve \u00f6rnek ortam\u0131 kurmak<\/a><ul><li><a href=\"#Paketleri_kurun_ve_olay_ureten_uygulamayi_baslatin\"><span class=\"toc_number toc_depth_2\">1.1.<\/span> Paketleri kurun ve olay \u00fcreten uygulamay\u0131 ba\u015flat\u0131n<\/a><\/li><li><a href=\"#Nginx_uzerinden_ikinci_erisim_yolunu_acin\"><span class=\"toc_number toc_depth_2\">1.2.<\/span> Nginx \u00fczerinden ikinci eri\u015fim yolunu a\u00e7\u0131n<\/a><\/li><\/ul><\/li><li><a href=\"#curl_ile_olaylarin_nerede_bekledigini_ayirmak\"><span class=\"toc_number toc_depth_1\">2.<\/span> curl ile olaylar\u0131n nerede bekledi\u011fini ay\u0131rmak<\/a><ul><li><a href=\"#Dogrudan_uygulama_ile_Nginx_akisini_karsilastirin\"><span class=\"toc_number toc_depth_2\">2.1.<\/span> Do\u011frudan uygulama ile Nginx ak\u0131\u015f\u0131n\u0131 kar\u015f\u0131la\u015ft\u0131r\u0131n<\/a><\/li><li><a href=\"#Gelis_zamanini_ve_olay_sinirini_dogrulayin\"><span class=\"toc_number toc_depth_2\">2.2.<\/span> Geli\u015f zaman\u0131n\u0131 ve olay s\u0131n\u0131r\u0131n\u0131 do\u011frulay\u0131n<\/a><\/li><\/ul><\/li><li><a href=\"#Nginx_tamponlamasini_yalniz_SSE_yolunda_kapatmak\"><span class=\"toc_number toc_depth_1\">3.<\/span> Nginx tamponlamas\u0131n\u0131 yaln\u0131z SSE yolunda kapatmak<\/a><ul><li><a href=\"#Mevcut_ayari_yedekleyip_SSE_konumunu_degistirin\"><span class=\"toc_number toc_depth_2\">3.1.<\/span> Mevcut ayar\u0131 yedekleyip SSE konumunu de\u011fi\u015ftirin<\/a><\/li><li><a href=\"#Ayari_yukleyin_ve_yeni_baglantiyla_dogrulayin\"><span class=\"toc_number toc_depth_2\">3.2.<\/span> Ayar\u0131 y\u00fckleyin ve yeni ba\u011flant\u0131yla do\u011frulay\u0131n<\/a><\/li><li><a href=\"#Gerekirse_onceki_ayara_donun\"><span class=\"toc_number toc_depth_2\">3.3.<\/span> Gerekirse \u00f6nceki ayara d\u00f6n\u00fcn<\/a><\/li><\/ul><\/li><li><a href=\"#Sikistirma_ara_katmanlar_ve_tarayicidaki_gecikmeler\"><span class=\"toc_number toc_depth_1\">4.<\/span> S\u0131k\u0131\u015ft\u0131rma, ara katmanlar ve taray\u0131c\u0131daki gecikmeler<\/a><ul><li><a href=\"#Sikistirmayi_ve_uygulamanin_tamponlama_basligini_ayirin\"><span class=\"toc_number toc_depth_2\">4.1.<\/span> S\u0131k\u0131\u015ft\u0131rmay\u0131 ve uygulaman\u0131n tamponlama ba\u015fl\u0131\u011f\u0131n\u0131 ay\u0131r\u0131n<\/a><\/li><li><a href=\"#CDN_gecikmesini_bosta_baglanti_kopmasindan_ayirin\"><span class=\"toc_number toc_depth_2\">4.2.<\/span> CDN gecikmesini bo\u015fta ba\u011flant\u0131 kopmas\u0131ndan ay\u0131r\u0131n<\/a><\/li><li><a href=\"#Tarayici_cizimini_ve_PHP_yolunu_ayri_degerlendirin\"><span class=\"toc_number toc_depth_2\">4.3.<\/span> Taray\u0131c\u0131 \u00e7izimini ve PHP yolunu ayr\u0131 de\u011ferlendirin<\/a><\/li><\/ul><\/li><li><a href=\"#Sik_Sorulan_Sorular\"><span class=\"toc_number toc_depth_1\">5.<\/span> S\u0131k Sorulan Sorular<\/a><ul><li><a href=\"#Baglanti_kopunca_olaylar_kaybolur_mu\"><span class=\"toc_number toc_depth_2\">5.1.<\/span> Ba\u011flant\u0131 kopunca olaylar kaybolur mu?<\/a><\/li><li><a href=\"#EventSource_ile_kimlik_dogrulamasi_nasil_yapilir\"><span class=\"toc_number toc_depth_2\">5.2.<\/span> EventSource ile kimlik do\u011frulamas\u0131 nas\u0131l yap\u0131l\u0131r?<\/a><\/li><li><a href=\"#SSE_icin_HTTP2_zorunlu_mu\"><span class=\"toc_number toc_depth_2\">5.3.<\/span> SSE i\u00e7in HTTP\/2 zorunlu mu?<\/a><\/li><li><a href=\"#Bir_sunucu_kac_SSE_baglantisi_tasiyabilir\"><span class=\"toc_number toc_depth_2\">5.4.<\/span> Bir sunucu ka\u00e7 SSE ba\u011flant\u0131s\u0131 ta\u015f\u0131yabilir?<\/a><\/li><\/ul><\/li><li><a href=\"#Yayina_gecmeden_once_akis_kontrol_listesi\"><span class=\"toc_number toc_depth_1\">6.<\/span> Yay\u0131na ge\u00e7meden \u00f6nce ak\u0131\u015f kontrol listesi<\/a><\/li><\/ul><\/div>\n<h2><span id=\"SSE_akisini_anlamak_ve_ornek_ortami_kurmak\">SSE ak\u0131\u015f\u0131n\u0131 anlamak ve \u00f6rnek ortam\u0131 kurmak<\/span><\/h2>\n<p>SSE (Server-Sent Events), sunucunun a\u00e7\u0131k tuttu\u011fu HTTP yan\u0131t\u0131 \u00fczerinden taray\u0131c\u0131ya olay g\u00f6ndermesidir. B\u00f6ylece siz sayfay\u0131 yenilemeden canl\u0131 bildirimleri veya yapay zek\u00e2 yan\u0131t\u0131n\u0131n par\u00e7alar\u0131n\u0131 g\u00f6rebilirsiniz. Ancak verinin uygulamada \u00fcretilmesi ile taray\u0131c\u0131ya ula\u015fmas\u0131 ayr\u0131 a\u015famalard\u0131r; gecikmeyi bulmak i\u00e7in bu a\u015famalar\u0131 kar\u015f\u0131la\u015ft\u0131rmak gerekir.<\/p>\n<p>Bir SSE olay\u0131 <code>data:<\/code> alan\u0131yla g\u00f6nderilebilir ve bo\u015f sat\u0131rla tamamlan\u0131r. Uygulama \u00e7\u0131kt\u0131y\u0131 kendi belle\u011finde bekletiyorsa <code>flush<\/code>, yani yazma tamponunu bo\u015faltma \u00e7a\u011fr\u0131s\u0131 gerekir. \u0130ste\u011fi uygulamaya ileten ters proxy de yan\u0131t par\u00e7alar\u0131n\u0131 biriktirebilir. Bu nedenle uygulamadaki ve arac\u0131 sunucudaki beklemeyi ayr\u0131 inceleyece\u011fiz. Tek bir yazma \u00e7a\u011fr\u0131s\u0131, verinin tek a\u011f paketiyle ula\u015faca\u011f\u0131n\u0131 veya ekran\u0131n hemen g\u00fcncellenece\u011fini garanti etmez.<\/p>\n<div class=\"aiw-note aiw-note-example\">\n<p class=\"aiw-box-title\">\u00d6rnek senaryo<\/p>\n<p>Sudo ile y\u00f6netici komutlar\u0131 \u00e7al\u0131\u015ft\u0131rabildi\u011finiz, \u00fcretim trafi\u011fi olmayan bir Ubuntu 24.04 sunucusunda \u00e7al\u0131\u015faca\u011f\u0131z. Python saniyede bir, toplam 10 zaman damgal\u0131 olay \u00fcretecek; Nginx ayn\u0131 uygulamaya ikinci bir eri\u015fim yolu sa\u011flayacak. \u00d6rnek i\u00e7in a\u00e7aca\u011f\u0131m\u0131z iki dinleme adresi de yaln\u0131z yerel ba\u011flant\u0131lar\u0131 kabul edecek ve testler sunucunun terminalinde yap\u0131lacak.<\/p>\n<\/div>\n<h3><span id=\"Paketleri_kurun_ve_olay_ureten_uygulamayi_baslatin\">Paketleri kurun ve olay \u00fcreten uygulamay\u0131 ba\u015flat\u0131n<\/span><\/h3>\n<p>Sunucunun terminalinde a\u015fa\u011f\u0131daki komutlarla Python, Nginx ve HTTP yan\u0131tlar\u0131n\u0131 terminalden incelemek i\u00e7in curl paketlerini kurun. Ubuntu 24.04 depolar\u0131ndaki paketleri kullanaca\u011f\u0131z. Bu \u00f6rnek, 9000 ve 8080 portlar\u0131n\u0131n bo\u015f oldu\u011funu ve a\u015fa\u011f\u0131da olu\u015fturulacak \u00f6rnek dosyalar\u0131n\u0131n hen\u00fcz bulunmad\u0131\u011f\u0131n\u0131 varsayar; mevcut dosyalar\u0131n\u0131z varsa \u00fczerlerine yazmadan \u00f6nce kopyalar\u0131n\u0131 al\u0131n.<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">sudo apt update\nsudo apt install -y python3 nginx curl<\/code><\/pre>\n<p>Ayn\u0131 terminalde a\u015fa\u011f\u0131daki komutla <code>\/tmp\/sse-demo.py<\/code> dosyas\u0131n\u0131 olu\u015fturup uygulamay\u0131 ba\u015flat\u0131n. Python standart kitapl\u0131\u011f\u0131ndaki <code>ThreadingHTTPServer<\/code>, ba\u011flant\u0131lar\u0131 ayr\u0131 i\u015f par\u00e7ac\u0131klar\u0131nda ele al\u0131r. Her olay\u0131n sonundaki \u00e7ift sat\u0131r sonu, taray\u0131c\u0131n\u0131n olay\u0131 tamamlanm\u0131\u015f saymas\u0131n\u0131 sa\u011flar. <code>wfile.flush()<\/code> \u00e7a\u011fr\u0131s\u0131 da uygulaman\u0131n yazma tamponunda bekleyen veri varsa bunu g\u00f6nderir.<\/p>\n<pre class=\"language-python line-numbers\"><code class=\"language-python\">cat &gt; \/tmp\/sse-demo.py &lt;&lt;&#039;PY&#039;\nfrom datetime import datetime, timezone\nfrom http.server import BaseHTTPRequestHandler, ThreadingHTTPServer\nimport time\n\n\nclass Handler(BaseHTTPRequestHandler):\n    def do_GET(self):\n        if self.path != &quot;\/events&quot;:\n            self.send_error(404)\n            return\n\n        self.send_response(200)\n        self.send_header(&quot;Content-Type&quot;, &quot;text\/event-stream&quot;)\n        self.send_header(&quot;Cache-Control&quot;, &quot;no-cache&quot;)\n        self.end_headers()\n\n        try:\n            for number in range(1, 11):\n                stamp = datetime.now(timezone.utc).isoformat()\n                event = f&quot;data: {number} {stamp}\\n\\n&quot;\n                self.wfile.write(event.encode(&quot;utf-8&quot;))\n                self.wfile.flush()\n                time.sleep(1)\n        except (BrokenPipeError, ConnectionResetError):\n            pass\n\n\nprint(&quot;SSE uygulamas\u0131 127.0.0.1:9000 \u00fczerinde haz\u0131r&quot;, flush=True)\nThreadingHTTPServer((&quot;127.0.0.1&quot;, 9000), Handler).serve_forever()\nPY\npython3 \/tmp\/sse-demo.py<\/code><\/pre>\n<p>Haz\u0131r mesaj\u0131ndan sonra hata g\u00f6r\u00fcnmeden terminalin beklemesi normaldir; uygulama \u00f6n planda \u00e7al\u0131\u015f\u0131r. Sonraki testlerde istekleri kar\u015f\u0131layabilmesi i\u00e7in bu oturumu a\u00e7\u0131k b\u0131rak\u0131n. Deneme bitti\u011finde uygulamay\u0131 <code>Ctrl+C<\/code> ile durdurabilirsiniz. Bu ge\u00e7ici servis, \u00fcretim ortam\u0131nda kullan\u0131lmak i\u00e7in tasarlanmam\u0131\u015ft\u0131r.<\/p>\n<h3><span id=\"Nginx_uzerinden_ikinci_erisim_yolunu_acin\">Nginx \u00fczerinden ikinci eri\u015fim yolunu a\u00e7\u0131n<\/span><\/h3>\n<p>Python&#8217;u durdurmadan sunucuya ikinci bir terminal oturumu a\u00e7\u0131n. Nginx, istekleri ayn\u0131 uygulamaya iletecek; b\u00f6ylece arac\u0131 sunucunun ak\u0131\u015fa etkisini kar\u015f\u0131la\u015ft\u0131rabileceksiniz. <a href=\"https:\/\/www.dchost.com\/blog\/nginx-reverse-proxy-ve-basit-load-balancer-kurulumu-kucuk-projeler\/\">Nginx ile ters proxy kurulumu<\/a> yakla\u015f\u0131m\u0131yla yaln\u0131z belirli bir yolu uygulamaya ba\u011flayaca\u011f\u0131z. A\u015fa\u011f\u0131daki komutun olu\u015fturdu\u011fu dosya, <code>\/events<\/code> isteklerini adres yolunu de\u011fi\u015ftirmeden Python&#8217;a aktar\u0131r.<\/p>\n<p>\u00d6rnekte Nginx, 127.0.0.1 adresinin 8080 portunu dinler; bu adrese yaln\u0131z sunucunun i\u00e7inden ula\u015f\u0131l\u0131r. Bu ayar, paket kurulumu s\u0131ras\u0131nda etkinle\u015febilen varsay\u0131lan siteyi veya ba\u015fka Nginx dinleme adreslerini kapatmaz.<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">sudo tee \/etc\/nginx\/conf.d\/sse-demo.conf &gt; \/dev\/null &lt;&lt;&#039;NGINX&#039;\nserver {\n    listen 127.0.0.1:8080;\n    server_name localhost;\n\n    location = \/events {\n        proxy_pass http:\/\/127.0.0.1:9000;\n        proxy_buffering on;\n    }\n}\nNGINX\nsudo nginx -t<\/code><\/pre>\n<p>S\u00f6zdizimi testinde ayar\u0131n ge\u00e7erli oldu\u011funu belirten mesajlar\u0131 g\u00f6r\u00fcrseniz a\u015fa\u011f\u0131daki komutlarla servisi ba\u015flat\u0131p ayar\u0131 y\u00fckleyin. Test hata verirse yeniden y\u00fcklemeye ge\u00e7meden bildirilen dosya ve sat\u0131r\u0131 d\u00fczeltin, ard\u0131ndan testi tekrar \u00e7al\u0131\u015ft\u0131r\u0131n.<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">sudo systemctl start nginx\nsudo systemctl reload nginx<\/code><\/pre>\n<p>Art\u0131k sunucudan 9000 portuna yap\u0131lan istek do\u011frudan Python&#8217;a, 8080 portuna yap\u0131lan istek ise Nginx \u00fczerinden ayn\u0131 uygulamaya ula\u015f\u0131r. Ba\u015flang\u0131\u00e7ta <code>proxy_buffering on<\/code> b\u0131rakt\u0131k; b\u00f6ylece tamponlamay\u0131 kapatmadan \u00f6nce iki yolu kar\u015f\u0131la\u015ft\u0131rabilece\u011fiz. Bu ayar tek ba\u015f\u0131na olaylar\u0131n mutlaka toplu gelece\u011fini g\u00f6stermez. Sonraki ak\u0131\u015f testinde olaylar\u0131n ger\u00e7ekten hangi aral\u0131klarla ula\u015ft\u0131\u011f\u0131na bakaca\u011f\u0131z.<\/p>\n<h2><span id=\"curl_ile_olaylarin_nerede_bekledigini_ayirmak\">curl ile olaylar\u0131n nerede bekledi\u011fini ay\u0131rmak<\/span><\/h2>\n<p>Ayn\u0131 uygulamaya do\u011frudan ve Nginx \u00fczerinden ba\u011flanarak gecikmenin hangi yolda ortaya \u00e7\u0131kt\u0131\u011f\u0131n\u0131 ay\u0131rabilirsiniz. Python uygulamas\u0131n\u0131n \u00e7al\u0131\u015ft\u0131\u011f\u0131 terminali a\u00e7\u0131k tutun; a\u015fa\u011f\u0131daki testleri sunucudaki ikinci terminalde s\u0131rayla yap\u0131n. \u00d6nce mevcut ak\u0131\u015f\u0131 g\u00f6zleyece\u011fiz, ard\u0131ndan bulguya g\u00f6re ilgili ayara ge\u00e7ece\u011fiz.<\/p>\n<figure class=\"aiw-figure\" data-aiw-visual-id=\"5968\" data-aiw-visual-key=\"71567c56a86269c06a8d78363c97e5bbf9240fd397238a24c8ea50f8fae5f5d7\"><img decoding=\"async\" src=\"https:\/\/www.dchost.com\/blog\/wp-content\/uploads\/2026\/11\/dchost-flow-tr-95067a7093a75307d38f.png\" alt=\"Do\u011frudan uygulama ve Nginx ak\u0131\u015flar\u0131n\u0131n curl ile kar\u015f\u0131la\u015ft\u0131r\u0131l\u0131p geciken katman\u0131n se\u00e7ildi\u011fi te\u015fhis ak\u0131\u015f\u0131.\" width=\"840\" height=\"987\" loading=\"lazy\" class=\"aiw-article-visual wp-image-5968\" srcset=\"https:\/\/www.dchost.com\/blog\/wp-content\/uploads\/2026\/11\/dchost-flow-tr-95067a7093a75307d38f.png 840w, https:\/\/www.dchost.com\/blog\/wp-content\/uploads\/2026\/11\/dchost-flow-tr-95067a7093a75307d38f-255x300.png 255w, https:\/\/www.dchost.com\/blog\/wp-content\/uploads\/2026\/11\/dchost-flow-tr-95067a7093a75307d38f-768x902.png 768w\" sizes=\"auto, (max-width: 840px) 100vw, 840px\" \/><figcaption>Ak\u0131\u015f \u015femas\u0131: \u0130ki eri\u015fim yolunu kar\u015f\u0131la\u015ft\u0131rmak, ayar de\u011fi\u015ftirmeden \u00f6nce gecikmenin uygulamada m\u0131 yoksa Nginx yolunda m\u0131 olu\u015ftu\u011funu ay\u0131rman\u0131za yard\u0131mc\u0131 olur.<\/figcaption><\/figure>\n<h3><span id=\"Dogrudan_uygulama_ile_Nginx_akisini_karsilastirin\">Do\u011frudan uygulama ile Nginx ak\u0131\u015f\u0131n\u0131 kar\u015f\u0131la\u015ft\u0131r\u0131n<\/span><\/h3>\n<p>\u0130lk komut do\u011frudan Python uygulamas\u0131na ba\u011flan\u0131r. <code>-N<\/code>, curl&#8217;\u00fcn ald\u0131\u011f\u0131 veriyi ekrana yazarken kendi tamponunda bekletmesini kapat\u0131r; uygulaman\u0131n veya Nginx&#8217;in tamponlamas\u0131n\u0131 de\u011fi\u015ftirmez. <code>-i<\/code> yan\u0131t ba\u015fl\u0131klar\u0131n\u0131 g\u00f6sterir, <code>-sS<\/code> ilerleme g\u00f6stergesini gizlerken hata mesajlar\u0131n\u0131 g\u00f6r\u00fcn\u00fcr b\u0131rak\u0131r.<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">curl -sS -N -i http:\/\/127.0.0.1:9000\/events<\/code><\/pre>\n<p>Bu \u00f6rnekte, yakla\u015f\u0131k saniyede bir gelen ve aralar\u0131nda bo\u015f sat\u0131r bulunan 10 adet <code>data:<\/code> sat\u0131r\u0131 g\u00f6rmelisiniz. Ak\u0131\u015f tamamlan\u0131nca ayn\u0131 testi Nginx&#8217;in dinledi\u011fi 8080 portunda \u00e7al\u0131\u015ft\u0131r\u0131n:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">curl -sS -N -i http:\/\/127.0.0.1:8080\/events<\/code><\/pre>\n<p>Olaylar\u0131n i\u00e7indeki zaman damgalar\u0131 <strong>\u00fcretim zaman\u0131n\u0131<\/strong> g\u00f6sterir, curl&#8217;e ula\u015fma zaman\u0131n\u0131 de\u011fil. Damgalar birer saniye ilerledi\u011fi h\u00e2lde sat\u0131rlar ekranda birlikte beliriyorsa veri, \u00fcretim ile ekrana yaz\u0131lma aras\u0131nda beklemi\u015ftir. \u0130ki istek ayr\u0131 olay dizileri \u00fcretir; bu nedenle damgalar\u0131n ayn\u0131 olmas\u0131n\u0131 de\u011fil, sat\u0131rlar\u0131n hangi aral\u0131klarla geldi\u011fini kar\u015f\u0131la\u015ft\u0131r\u0131n.<\/p>\n<h3><span id=\"Gelis_zamanini_ve_olay_sinirini_dogrulayin\">Geli\u015f zaman\u0131n\u0131 ve olay s\u0131n\u0131r\u0131n\u0131 do\u011frulay\u0131n<\/span><\/h3>\n<p>Geli\u015f aral\u0131klar\u0131n\u0131 g\u00f6zle ay\u0131rt edemiyorsan\u0131z ayn\u0131 terminalde zaman damgal\u0131 curl izini kaydedin. <code>--trace-ascii<\/code> g\u00f6nderilen ve al\u0131nan veriyi okunabilir bi\u00e7imde dosyaya yazar; <code>--trace-time<\/code> her kayda zaman bilgisi ekler.<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">curl -sS -N --trace-time --trace-ascii \/tmp\/sse-direct.trace http:\/\/127.0.0.1:9000\/events\ncurl -sS -N --trace-time --trace-ascii \/tmp\/sse-nginx.trace http:\/\/127.0.0.1:8080\/events<\/code><\/pre>\n<p>Dosyalar\u0131 <code>less \/tmp\/sse-direct.trace<\/code> ve <code>less \/tmp\/sse-nginx.trace<\/code> ile a\u00e7\u0131n. <code>Recv data<\/code>, curl&#8217;\u00fcn veri ald\u0131\u011f\u0131 kay\u0131tlar\u0131 g\u00f6sterir. Her dosyada bu kay\u0131tlar aras\u0131ndaki s\u00fcreye ve i\u00e7erdikleri olaylara bak\u0131n; ard\u0131ndan iki yolun geli\u015f aral\u0131klar\u0131n\u0131 kar\u015f\u0131la\u015ft\u0131r\u0131n. Bir kay\u0131t birden fazla olay i\u00e7erebilir; tek kay\u0131t tek olay demek de\u011fildir. Bu \u00f6rnek hassas veri i\u00e7ermez, ancak ger\u00e7ek uygulamalarda iz dosyalar\u0131 kimlik do\u011frulama bilgilerini ve yan\u0131t i\u00e7eri\u011fini de saklayabilir.<\/p>\n<p>\u0130lk iki komutun g\u00f6sterdi\u011fi yan\u0131t ba\u015fl\u0131klar\u0131nda durumun <code>200<\/code>, <code>Content-Type<\/code> de\u011ferinin <code>text\/event-stream<\/code> oldu\u011funu kontrol edin. Farkl\u0131 bir durum veya i\u00e7erik t\u00fcr\u00fc varsa \u00f6nce bekledi\u011finiz SSE yan\u0131t\u0131na ula\u015f\u0131p ula\u015fmad\u0131\u011f\u0131n\u0131z\u0131 ay\u0131r\u0131n. <code>Cache-Control: no-cache<\/code> \u00f6nbellek davran\u0131\u015f\u0131yla ilgilidir; tamponlamay\u0131 kapatmaz. <code>Content-Encoding: gzip<\/code> g\u00f6r\u00fcrseniz yan\u0131t s\u0131k\u0131\u015ft\u0131r\u0131lm\u0131\u015ft\u0131r. Bu tek ba\u015f\u0131na gecikmenin nedenini kan\u0131tlamaz, ancak s\u0131k\u0131\u015ft\u0131rmay\u0131 ayr\u0131ca s\u0131naman\u0131z gerekti\u011fini g\u00f6sterir.<\/p>\n<ul>\n<li><strong>\u0130ki yol da gecikiyorsa:<\/strong> \u00d6nce uygulamada olay\u0131n <code>\\n\\n<\/code> ile tamamland\u0131\u011f\u0131n\u0131 ve yazmadan sonra <code>wfile.flush()<\/code> \u00e7a\u011fr\u0131ld\u0131\u011f\u0131n\u0131 kontrol edin. curl tamamlanmam\u0131\u015f olay\u0131n metnini g\u00f6sterebilir, fakat taray\u0131c\u0131 bo\u015f sat\u0131r gelmeden olay\u0131 uygulaman\u0131za teslim etmez. Eksik olan k\u0131sm\u0131 d\u00fczelttikten sonra do\u011frudan uygulama testini tekrarlay\u0131n.<\/li>\n<li><strong>Yaln\u0131z 8080 gecikiyorsa:<\/strong> Bu yerel \u00f6rnekte fark Nginx yolundad\u0131r. Sonraki ad\u0131mda yaln\u0131z SSE yolunun tamponlama ayar\u0131n\u0131 de\u011fi\u015ftirip yeni bir ba\u011flant\u0131yla geli\u015f aral\u0131klar\u0131n\u0131 yeniden kar\u015f\u0131la\u015ft\u0131rabilirsiniz.<\/li>\n<li><strong>\u0130ki yol da d\u00fczenliyse:<\/strong> Bu testte olaylar\u0131n toplu geldi\u011fi g\u00f6zlenmemi\u015ftir. Gecikmenin ya\u015fand\u0131\u011f\u0131 taray\u0131c\u0131y\u0131 ve ger\u00e7ek d\u0131\u015f eri\u015fim yolunu ayr\u0131ca inceleyin; yerel test bu katmanlar\u0131 kapsam\u0131yor.<\/li>\n<\/ul>\n<h2><span id=\"Nginx_tamponlamasini_yalniz_SSE_yolunda_kapatmak\">Nginx tamponlamas\u0131n\u0131 yaln\u0131z SSE yolunda kapatmak<\/span><\/h2>\n<p>Do\u011frudan uygulama ak\u0131\u015f\u0131 d\u00fczenliyken yaln\u0131z 8080 portundaki ak\u0131\u015f gecikiyorsa, de\u011fi\u015fikli\u011fi Nginx&#8217;in <code>\/events<\/code> yoluyla s\u0131n\u0131rlay\u0131n. B\u00f6ylece di\u011fer sayfalar\u0131n ayarlar\u0131na dokunmadan SSE yan\u0131tlar\u0131n\u0131n Nginx&#8217;te birikmesini \u00f6nleyebilirsiniz. \u0130ki yol da d\u00fczenliyse bu de\u011fi\u015fiklik, tespit edilmi\u015f bir gecikmeyi d\u00fczeltmekten \u00e7ok SSE yolunda tamponlamay\u0131 a\u00e7\u0131k\u00e7a kapatmaya yarar.<\/p>\n<h3><span id=\"Mevcut_ayari_yedekleyip_SSE_konumunu_degistirin\">Mevcut ayar\u0131 yedekleyip SSE konumunu de\u011fi\u015ftirin<\/span><\/h3>\n<p>Python uygulamas\u0131 \u00e7al\u0131\u015fmaya devam ederken sunucudaki ikinci terminalde mevcut ayar dosyas\u0131n\u0131n kopyas\u0131n\u0131 al\u0131n. Bu kopya, de\u011fi\u015fiklik \u00f6ncesindeki ayara d\u00f6nmenizi sa\u011flar. Komut ayn\u0131 adl\u0131 yede\u011fin \u00fczerine yazaca\u011f\u0131 i\u00e7in bu ad\u0131m\u0131 daha \u00f6nce yapt\u0131ysan\u0131z ilk yede\u011finizi koruyun ve kopyalama komutunu tekrar \u00e7al\u0131\u015ft\u0131rmay\u0131n.<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">sudo cp -p \/etc\/nginx\/conf.d\/sse-demo.conf \/etc\/nginx\/conf.d\/sse-demo.conf.bak<\/code><\/pre>\n<p>Yede\u011fi ald\u0131ktan sonra ayn\u0131 terminalde a\u015fa\u011f\u0131daki komutu \u00e7al\u0131\u015ft\u0131r\u0131n. Komut, \u00f6rnek ortam i\u00e7in olu\u015fturdu\u011fumuz dosyan\u0131n i\u00e7eri\u011fini a\u015fa\u011f\u0131daki ayarlarla de\u011fi\u015ftirir. Ger\u00e7ek sitenizin ba\u015fka ayarlar da i\u00e7eren dosyas\u0131n\u0131 bununla de\u011fi\u015ftirmeyin; burada yaln\u0131z deneme dosyas\u0131 \u00fczerinde ilerliyoruz.<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">sudo tee \/etc\/nginx\/conf.d\/sse-demo.conf &gt; \/dev\/null &lt;&lt;&#039;NGINX&#039;\nserver {\n    listen 127.0.0.1:8080;\n    server_name localhost;\n\n    location = \/events {\n        proxy_pass http:\/\/127.0.0.1:9000;\n        proxy_buffering off;\n        gzip off;\n        proxy_read_timeout 60s;\n    }\n}\nNGINX<\/code><\/pre>\n<p><code>location = \/events<\/code> yaln\u0131z bu yolla tam e\u015fle\u015fen istekleri kapsar; sonunda e\u011fik \u00e7izgi bulunan <code>\/events\/<\/code> farkl\u0131 bir yoldur. <code>proxy_buffering off<\/code>, Nginx&#8217;in uygulamadan ald\u0131\u011f\u0131 yan\u0131t\u0131 tamponlarda biriktirerek iletmesini kapat\u0131r. Bu ayar, her par\u00e7an\u0131n ayr\u0131 bir a\u011f paketiyle veya s\u0131f\u0131r gecikmeyle ula\u015faca\u011f\u0131n\u0131 garanti etmez.<\/p>\n<p><code>gzip off<\/code>, bu konumda Nginx&#8217;in yan\u0131t\u0131 gzip ile s\u0131k\u0131\u015ft\u0131rmas\u0131n\u0131 kapat\u0131r. Uygulaman\u0131n zaten s\u0131k\u0131\u015ft\u0131rd\u0131\u011f\u0131 yan\u0131t\u0131 a\u00e7maz; \u00f6rnekteki Python uygulamas\u0131 s\u0131k\u0131\u015ft\u0131rma yapm\u0131yor.<\/p>\n<p><code>proxy_read_timeout 60s<\/code> ise uygulamadan yap\u0131lan ard\u0131\u015f\u0131k okumalar aras\u0131ndaki bekleme s\u0131n\u0131r\u0131d\u0131r; ba\u011flant\u0131n\u0131n toplam \u00f6mr\u00fc de\u011fildir. \u00d6rnekte saniyede bir veri geldi\u011fi i\u00e7in normal ak\u0131\u015f\u0131n bu s\u0131n\u0131ra tak\u0131lmas\u0131 beklenmez.<\/p>\n<h3><span id=\"Ayari_yukleyin_ve_yeni_baglantiyla_dogrulayin\">Ayar\u0131 y\u00fckleyin ve yeni ba\u011flant\u0131yla do\u011frulay\u0131n<\/span><\/h3>\n<p>Dosyay\u0131 de\u011fi\u015ftirmek, \u00e7al\u0131\u015fan Nginx&#8217;in yeni ayar\u0131 kullanmas\u0131 i\u00e7in yeterli de\u011fildir. Ayn\u0131 terminalde a\u015fa\u011f\u0131daki komutu \u00e7al\u0131\u015ft\u0131r\u0131n. Yeniden y\u00fckleme yaln\u0131z s\u00f6zdizimi testi ba\u015far\u0131l\u0131ysa yap\u0131l\u0131r; <code>reload<\/code>, Nginx&#8217;i durdurmadan yeni ayar\u0131 y\u00fckler.<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">sudo nginx -t &amp;&amp; sudo systemctl reload nginx<\/code><\/pre>\n<p>Test hata verirse bildirilen dosya ve sat\u0131rdaki sorunu d\u00fczeltip ayn\u0131 komutu yeniden \u00e7al\u0131\u015ft\u0131r\u0131n. Yeniden y\u00fckleme de hatas\u0131z tamamland\u0131ktan sonra a\u015fa\u011f\u0131daki komutla yeni bir ba\u011flant\u0131 a\u00e7\u0131n. \u00d6nceden a\u00e7\u0131lm\u0131\u015f bir ak\u0131\u015f eski ayarla devam edebilece\u011finden yeni ayar\u0131 o ba\u011flant\u0131 \u00fczerinden de\u011ferlendirmeyin.<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">curl -sS -N -i -H &#039;Accept-Encoding: gzip&#039; http:\/\/127.0.0.1:8080\/events<\/code><\/pre>\n<p>Beklenen g\u00f6r\u00fcn\u00fcm, yakla\u015f\u0131k saniyede bir ula\u015fan 10 olayd\u0131r. Yan\u0131t\u0131n durum kodunun <code>200<\/code>, i\u00e7erik t\u00fcr\u00fcn\u00fcn <code>text\/event-stream<\/code> oldu\u011funu kontrol edin. Komut s\u0131k\u0131\u015ft\u0131rma istedi\u011fi h\u00e2lde yan\u0131t ba\u015fl\u0131klar\u0131nda <code>Content-Encoding: gzip<\/code> bulunmamal\u0131d\u0131r. Olaylar h\u00e2l\u00e2 toplu geliyorsa \u00f6nceki zaman damgal\u0131 curl testini tekrarlay\u0131p geli\u015f aral\u0131klar\u0131n\u0131 kar\u015f\u0131la\u015ft\u0131r\u0131n; bu bulgu olmadan ba\u015fka konumlar\u0131n tampon ayarlar\u0131n\u0131 de\u011fi\u015ftirmeyin.<\/p>\n<h3><span id=\"Gerekirse_onceki_ayara_donun\">Gerekirse \u00f6nceki ayara d\u00f6n\u00fcn<\/span><\/h3>\n<p>De\u011fi\u015fikli\u011fi geri almak i\u00e7in sunucudaki ikinci terminalde a\u015fa\u011f\u0131daki komutlar\u0131 \u00e7al\u0131\u015ft\u0131r\u0131n. \u0130lk komut yede\u011fi etkin dosyan\u0131n yerine koyar; ikinci komut geri y\u00fcklenen ayar\u0131 test eder ve test ba\u015far\u0131l\u0131ysa Nginx&#8217;e y\u00fckler.<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">sudo cp -p \/etc\/nginx\/conf.d\/sse-demo.conf.bak \/etc\/nginx\/conf.d\/sse-demo.conf\nsudo nginx -t &amp;&amp; sudo systemctl reload nginx<\/code><\/pre>\n<p>Ard\u0131ndan ayn\u0131 curl komutuyla yeni ba\u011flant\u0131 a\u00e7\u0131n ve yan\u0131t\u0131n h\u00e2l\u00e2 al\u0131nabildi\u011fini kontrol edin. \u00d6nceki ayar tamponlamay\u0131 a\u00e7\u0131k b\u0131rakt\u0131\u011f\u0131 i\u00e7in olaylar yeniden toplu gelebilir; bu kontrolde ama\u00e7, geri d\u00f6n\u00fc\u015ften sonra eri\u015fimin \u00e7al\u0131\u015ft\u0131\u011f\u0131n\u0131 g\u00f6rmektir.<\/p>\n<h2><span id=\"Sikistirma_ara_katmanlar_ve_tarayicidaki_gecikmeler\">S\u0131k\u0131\u015ft\u0131rma, ara katmanlar ve taray\u0131c\u0131daki gecikmeler<\/span><\/h2>\n<p>Yerel Nginx yolu olaylar\u0131 d\u00fczenli iletiyorsa kalan gecikmenin hangi katmanda ba\u015flad\u0131\u011f\u0131n\u0131 ara\u015ft\u0131r\u0131n. Toplu geli\u015f, proxy tamponlamas\u0131n\u0131n yan\u0131 s\u0131ra s\u0131k\u0131\u015ft\u0131rmadan veya taray\u0131c\u0131n\u0131n ekran\u0131 g\u00fcncelleme bi\u00e7iminden de kaynaklanabilir. A\u015fa\u011f\u0131daki kontrolleri yaln\u0131z ilgili katman varsa uygulay\u0131n; Python \u00f6rne\u011fine yeni bile\u015fen eklemeniz gerekmiyor.<\/p>\n<h3><span id=\"Sikistirmayi_ve_uygulamanin_tamponlama_basligini_ayirin\">S\u0131k\u0131\u015ft\u0131rmay\u0131 ve uygulaman\u0131n tamponlama ba\u015fl\u0131\u011f\u0131n\u0131 ay\u0131r\u0131n<\/span><\/h3>\n<p>Sunucudaki terminalde ayn\u0131 yolu \u00f6nce s\u0131k\u0131\u015ft\u0131rmas\u0131z, ard\u0131ndan s\u0131k\u0131\u015ft\u0131rma isteyerek s\u0131nay\u0131n. <code>--compressed<\/code>, curl&#8217;\u00fcn destekledi\u011fi s\u0131k\u0131\u015ft\u0131rmalar\u0131 istemesini ve gelen s\u0131k\u0131\u015ft\u0131r\u0131lm\u0131\u015f yan\u0131t\u0131 a\u00e7mas\u0131n\u0131 sa\u011flar:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">curl -sS -N -i -H &#039;Accept-Encoding: identity&#039; http:\/\/127.0.0.1:8080\/events\ncurl -sS -N -i --compressed http:\/\/127.0.0.1:8080\/events<\/code><\/pre>\n<p>\u00d6rnekte iki ak\u0131\u015f\u0131n da d\u00fczenli, yan\u0131tlar\u0131n s\u0131k\u0131\u015ft\u0131rmas\u0131z olmas\u0131 beklenir. Ger\u00e7ek uygulamada yaln\u0131z s\u0131k\u0131\u015ft\u0131r\u0131lm\u0131\u015f yan\u0131t gecikiyorsa <code>Content-Encoding<\/code> ba\u015fl\u0131\u011f\u0131n\u0131 do\u011frudan uygulamadan ald\u0131\u011f\u0131n\u0131z yan\u0131ttaki de\u011ferle kar\u015f\u0131la\u015ft\u0131r\u0131n. Bu ba\u015fl\u0131k, yan\u0131ta uygulanan s\u0131k\u0131\u015ft\u0131rmay\u0131 g\u00f6sterir. Uygulama s\u0131k\u0131\u015ft\u0131r\u0131yorsa mevcut ayar\u0131n\u0131n kopyas\u0131n\u0131 al\u0131n ve yaln\u0131z SSE yolunu s\u0131k\u0131\u015ft\u0131rma d\u0131\u015f\u0131nda b\u0131rak\u0131n; Nginx&#8217;teki <code>gzip off<\/code> uygulaman\u0131n s\u0131k\u0131\u015ft\u0131rmas\u0131n\u0131 kapatmaz. De\u011fi\u015fiklikten sonra ayn\u0131 iki testi tekrarlay\u0131n; beklenen etkiyi g\u00f6rmezseniz \u00f6nceki ayara d\u00f6n\u00fcn.<\/p>\n<p>Uygulaman\u0131n g\u00f6nderdi\u011fi <code>X-Accel-Buffering: no<\/code> yan\u0131t ba\u015fl\u0131\u011f\u0131 da Nginx&#8217;e tamponlamay\u0131 kapatmas\u0131n\u0131 s\u00f6yleyebilir. Ancak ilgili ayarlarda <code>proxy_ignore_headers X-Accel-Buffering;<\/code> varsa bu ba\u015fl\u0131k dikkate al\u0131nmaz. Sunucuda <code>sudo nginx -T<\/code> \u00e7\u0131kt\u0131s\u0131nda SSE iste\u011fini kar\u015f\u0131layan konumu ve \u00fcst d\u00fczeyden devrald\u0131\u011f\u0131 ayarlar\u0131 inceleyin. Nginx bu ba\u015fl\u0131\u011f\u0131 normalde istemciye ge\u00e7irmedi\u011finden taray\u0131c\u0131da g\u00f6r\u00fcnmemesi, uygulaman\u0131n g\u00f6ndermedi\u011fini kan\u0131tlamaz. Mevcut \u00f6rnekte a\u00e7\u0131k\u00e7a yazd\u0131\u011f\u0131n\u0131z <code>proxy_buffering off<\/code> yeterlidir; ayr\u0131ca ba\u015fl\u0131k eklemeniz gerekmez.<\/p>\n<h3><span id=\"CDN_gecikmesini_bosta_baglanti_kopmasindan_ayirin\">CDN gecikmesini bo\u015fta ba\u011flant\u0131 kopmas\u0131ndan ay\u0131r\u0131n<\/span><\/h3>\n<p>CDN, yani i\u00e7erik da\u011f\u0131t\u0131m a\u011f\u0131 kullan\u0131yorsan\u0131z kendi bilgisayar\u0131n\u0131zda ger\u00e7ek HTTPS alan ad\u0131n\u0131zdaki SSE yolunu ayn\u0131 curl se\u00e7enekleriyle s\u0131nay\u0131n. Yerel yol d\u00fczenliyken d\u0131\u015f yol toplu geliyorsa CDN&#8217;in ilgili yol kural\u0131nda \u00f6nbellek, s\u0131k\u0131\u015ft\u0131rma ve ak\u0131\u015f deste\u011fini kontrol edin. Bu fark, d\u0131\u015f eri\u015fim yolunu incelemeniz gerekti\u011fini g\u00f6sterir; tek ba\u015f\u0131na CDN&#8217;in sorumlu oldu\u011funu kan\u0131tlamaz.<\/p>\n<p>De\u011fi\u015fiklik gerekiyorsa mevcut kural\u0131 kaydedip yaln\u0131z SSE yolunda ilgili \u00f6zelli\u011fi de\u011fi\u015ftirin; yeni ba\u011flant\u0131da fark yoksa geri al\u0131n. \u00d6nbelle\u011fi atlamak tek ba\u015f\u0131na tamponlamay\u0131 kapatmaz. Sa\u011flay\u0131c\u0131n\u0131n ak\u0131\u015f deste\u011fi ve ba\u011flant\u0131 s\u00fcresi s\u0131n\u0131rlar\u0131 da de\u011ferlendirmeye dahildir.<\/p>\n<p>Olaylar d\u00fczenli gelirken yaln\u0131z sessiz d\u00f6nemlerde ba\u011flant\u0131 kopuyorsa sorun tamponlama olmayabilir. Uygulama, ba\u011flant\u0131y\u0131 canl\u0131 tutmak i\u00e7in <strong>heartbeat<\/strong> ad\u0131 verilen periyodik mesaj\u0131 <code>: ping\\n\\n<\/code> bi\u00e7iminde yaz\u0131p tamponunu bo\u015faltabilir. Bu, SSE yorum sat\u0131r\u0131d\u0131r; taray\u0131c\u0131 bunu normal bir olay olarak i\u015fleyiciye teslim etmez. \u00d6rne\u011fin bilinen en k\u0131sa bo\u015fta kalma s\u0131n\u0131r\u0131 60 saniyeyse 15 saniyelik g\u00f6nderim aral\u0131\u011f\u0131 bu s\u0131n\u0131r\u0131n alt\u0131nda kal\u0131r. Ancak bu mesajlar ba\u011flant\u0131n\u0131n toplam \u00f6mr\u00fcne konan s\u0131n\u0131r\u0131 ortadan kald\u0131rmaz. Mevcut 10 olayl\u0131k \u00f6rnek uzun sessizli\u011fi s\u0131namaz; ayr\u0131 bir denemede i\u015f olay\u0131 \u00fcretilmezken ba\u011flant\u0131n\u0131n a\u00e7\u0131k kald\u0131\u011f\u0131n\u0131 g\u00f6zleyin.<\/p>\n<h3><span id=\"Tarayici_cizimini_ve_PHP_yolunu_ayri_degerlendirin\">Taray\u0131c\u0131 \u00e7izimini ve PHP yolunu ayr\u0131 de\u011ferlendirin<\/span><\/h3>\n<p>Ger\u00e7ek d\u0131\u015f eri\u015fim yolunda da curl d\u00fczenliyse taray\u0131c\u0131n\u0131n geli\u015ftirici ara\u00e7lar\u0131nda <code>Network<\/code> (a\u011f) b\u00f6l\u00fcm\u00fcnden ak\u0131\u015f iste\u011fini a\u00e7\u0131n. Olay geldi\u011finde \u00e7al\u0131\u015fan i\u015flevin, yani olay i\u015fleyicisinin ba\u015f\u0131nda konsola <code>performance.now()<\/code> de\u011ferini yazd\u0131r\u0131n. Bu de\u011fer, \u00e7a\u011fr\u0131n\u0131n sayfan\u0131n zaman ba\u015flang\u0131c\u0131na g\u00f6re ne zaman \u00e7al\u0131\u015ft\u0131\u011f\u0131n\u0131 g\u00f6sterir; ard\u0131\u015f\u0131k kay\u0131tlar\u0131n fark\u0131yla i\u015fleyicinin \u00e7al\u0131\u015fma aral\u0131klar\u0131n\u0131 kar\u015f\u0131la\u015ft\u0131rabilirsiniz.<\/p>\n<p>\u0130\u015fleyici d\u00fczenli \u00e7al\u0131\u015f\u0131rken metin toplu g\u00f6r\u00fcn\u00fcyorsa aray\u00fcz\u00fcn g\u00fcncellemeleri birle\u015ftirmesini veya taray\u0131c\u0131n\u0131n ana i\u015f par\u00e7ac\u0131\u011f\u0131n\u0131 me\u015fgul eden i\u015fleri inceleyin. Deneme ortam\u0131nda a\u011f\u0131r i\u015flemi ge\u00e7ici olarak devre d\u0131\u015f\u0131 b\u0131rak\u0131p ayn\u0131 ak\u0131\u015f\u0131 yeniden izleyin. Ekran g\u00fcncellemeleri d\u00fczeliyorsa proxy ayar\u0131 yerine aray\u00fczdeki i\u015flem y\u00fck\u00fcne odaklan\u0131n.<\/p>\n<p>PHP isteklerini \u00e7al\u0131\u015ft\u0131ran s\u00fcre\u00e7 y\u00f6neticisi PHP-FPM&#8217;e <code>fastcgi_pass<\/code> ile ba\u011flanan sitelerde farkl\u0131 bir ileti\u015fim yolu vard\u0131r: <code>proxy_buffering<\/code> yerine <code>fastcgi_buffering off;<\/code> kullan\u0131l\u0131r. \u00d6nce SSE iste\u011fini kar\u015f\u0131layan konumun ger\u00e7ekten bu ileti\u015fim yolunu kulland\u0131\u011f\u0131n\u0131 kontrol edin. \u0130lgili ayar dosyas\u0131n\u0131 yedekleyip de\u011fi\u015fikli\u011fi yaln\u0131z SSE konumuna ekleyin; s\u00f6zdizimi testi ba\u015far\u0131l\u0131ysa Nginx ayar\u0131n\u0131 yeniden y\u00fckleyin. Yeni ba\u011flant\u0131da ak\u0131\u015f\u0131 kar\u015f\u0131la\u015ft\u0131r\u0131n; geri d\u00f6nmeniz gerekirse yede\u011fi yerine koyup yine testten sonra y\u00fckleyin.<\/p>\n<p>PHP taraf\u0131nda \u00fcretilen \u00e7\u0131kt\u0131 daha Nginx&#8217;e ula\u015fmadan bekliyorsa PHP \u00e7\u0131kt\u0131 tamponlar\u0131n\u0131 ve s\u0131k\u0131\u015ft\u0131rmas\u0131n\u0131 inceleyin. Yaln\u0131z <code>flush()<\/code> \u00e7a\u011fr\u0131s\u0131 b\u00fct\u00fcn katmanlar\u0131 bo\u015faltmaz; uygulaman\u0131n kendi \u00e7\u0131kt\u0131 tamponunda tuttu\u011fu veriyi de g\u00f6ndermesi gerekir.<\/p>\n<h2><span id=\"Sik_Sorulan_Sorular\">S\u0131k Sorulan Sorular<\/span><\/h2>\n<h3><span id=\"Baglanti_kopunca_olaylar_kaybolur_mu\">Ba\u011flant\u0131 kopunca olaylar kaybolur mu?<\/span><\/h3>\n<p>Ba\u011flant\u0131n\u0131n yeniden kurulmas\u0131, arada ka\u00e7\u0131r\u0131lan olaylar\u0131n geri gelece\u011fi anlam\u0131na gelmez. Taray\u0131c\u0131n\u0131n yerle\u015fik SSE istemcisi <code>EventSource<\/code>, ba\u011flant\u0131 kesildi\u011finde normalde yeniden ba\u011flanmay\u0131 dener. Sunucu olaylara <code>id:<\/code> alan\u0131 eklerse istemci yeniden ba\u011flant\u0131da son olay kimli\u011fini <code>Last-Event-ID<\/code> ba\u015fl\u0131\u011f\u0131yla iletebilir.<\/p>\n<p>Kay\u0131ps\u0131z devam i\u00e7in uygulaman\u0131z\u0131n bu kimli\u011fi okuyup ard\u0131ndan gelen, saklanm\u0131\u015f olaylar\u0131 yeniden g\u00f6ndermesi gerekir. Ayn\u0131 olay\u0131n iki kez i\u015flenmesini \u00f6nlemek i\u00e7in tekrar gelen olaylar\u0131 kimliklerine g\u00f6re ay\u0131klay\u0131n. \u00d6rnekteki Python u\u00e7 noktas\u0131 olay ge\u00e7mi\u015fi tutmad\u0131\u011f\u0131ndan kay\u0131ps\u0131z devam sa\u011flamaz.<\/p>\n<h3><span id=\"EventSource_ile_kimlik_dogrulamasi_nasil_yapilir\">EventSource ile kimlik do\u011frulamas\u0131 nas\u0131l yap\u0131l\u0131r?<\/span><\/h3>\n<p>Yerle\u015fik <code>EventSource<\/code> aray\u00fcz\u00fc \u00f6zel <code>Authorization<\/code> ba\u015fl\u0131\u011f\u0131 eklemenize izin vermez. Ayn\u0131 kaynakta, yani ayn\u0131 protokol, alan ad\u0131 ve portta, oturum \u00e7erezi kullanabilirsiniz. Ba\u015fka bir kayna\u011fa \u00e7erezle ba\u011flanmak i\u00e7in <code>withCredentials: true<\/code> ve sunucuda uygun CORS, yani kaynaklar aras\u0131 eri\u015fim izinleri gerekir. Bu izinler verilse bile taray\u0131c\u0131n\u0131n \u00e7erez k\u0131s\u0131tlamalar\u0131 ge\u00e7erlili\u011fini korur.<\/p>\n<p>Eri\u015fim belirtecini ba\u015fl\u0131kla g\u00f6ndermeniz gerekiyorsa <code>fetch<\/code> \u00fczerinden ak\u0131\u015f\u0131 okuyabilirsiniz. Bu durumda gelen veriyi SSE olaylar\u0131na ay\u0131rmay\u0131 ve yeniden ba\u011flanma mant\u0131\u011f\u0131n\u0131 da sizin y\u00f6netmeniz gerekir. Uzun \u00f6m\u00fcrl\u00fc belirte\u00e7leri URL&#8217;ye koymay\u0131n; eri\u015fim g\u00fcnl\u00fcklerine kaydedilebilirler.<\/p>\n<h3><span id=\"SSE_icin_HTTP2_zorunlu_mu\">SSE i\u00e7in HTTP\/2 zorunlu mu?<\/span><\/h3>\n<p>Hay\u0131r, SSE HTTP\/1.1 \u00fczerinde de \u00e7al\u0131\u015f\u0131r. HTTP\/2, tek ba\u011flant\u0131da birden fazla ak\u0131\u015f ta\u015f\u0131yarak \u00e7ok sekmeli kullan\u0131mda taray\u0131c\u0131n\u0131n ba\u011flant\u0131 s\u0131n\u0131rlar\u0131n\u0131n etkisini azaltabilir. Yine de e\u015fzamanl\u0131 ak\u0131\u015f say\u0131s\u0131 s\u0131n\u0131rs\u0131z de\u011fildir. HTTP\/2&#8217;ye ge\u00e7meniz, uygulaman\u0131n veya ters proxy&#8217;nin veriyi bekletmesini \u00f6nlemez; protokol de\u011fi\u015fikli\u011fi tamponlama d\u00fczeltmesinin yerine ge\u00e7mez.<\/p>\n<h3><span id=\"Bir_sunucu_kac_SSE_baglantisi_tasiyabilir\">Bir sunucu ka\u00e7 SSE ba\u011flant\u0131s\u0131 ta\u015f\u0131yabilir?<\/span><\/h3>\n<p>Her sunucu i\u00e7in ge\u00e7erli tek bir say\u0131 yoktur. Kapasite; a\u00e7\u0131k ba\u011flant\u0131 s\u0131n\u0131rlar\u0131na, belle\u011fe, uygulaman\u0131n e\u015fzamanl\u0131 \u00e7al\u0131\u015fma modeline, olay s\u0131kl\u0131\u011f\u0131na ve yava\u015f istemciler i\u00e7in biriken veriye ba\u011fl\u0131d\u0131r. Hesab\u0131n\u0131za yaln\u0131z taray\u0131c\u0131 ba\u011flant\u0131lar\u0131n\u0131 de\u011fil, Nginx&#8217;in uygulamaya a\u00e7t\u0131\u011f\u0131 ba\u011flant\u0131lar\u0131 da kat\u0131n.<\/p>\n<p>\u00d6rnekteki <code>ThreadingHTTPServer<\/code> her ba\u011flant\u0131 i\u00e7in ayr\u0131 i\u015f par\u00e7ac\u0131\u011f\u0131 kullan\u0131r; \u00fcretimdeki uygulaman\u0131z\u0131n kapasitesini temsil etmez. Kendi s\u0131n\u0131r\u0131n\u0131z\u0131 g\u00f6rmek i\u00e7in \u00fcretimden ayr\u0131 bir y\u00fck testinde e\u015fzamanl\u0131 ba\u011flant\u0131 say\u0131s\u0131n\u0131 bekledi\u011finiz kullan\u0131c\u0131 say\u0131s\u0131na do\u011fru kademeli art\u0131r\u0131n. Bellek kullan\u0131m\u0131n\u0131, a\u00e7\u0131k ba\u011flant\u0131 say\u0131s\u0131n\u0131, olaylar\u0131n ula\u015fma gecikmesini ve ba\u011flant\u0131 kopmalar\u0131n\u0131 birlikte izleyin.<\/p>\n<h2><span id=\"Yayina_gecmeden_once_akis_kontrol_listesi\">Yay\u0131na ge\u00e7meden \u00f6nce ak\u0131\u015f kontrol listesi<\/span><\/h2>\n<p>Nginx ayar\u0131n\u0131n y\u00fcklenmi\u015f olmas\u0131 tek ba\u015f\u0131na yeterli de\u011fildir; olaylar\u0131n kullan\u0131c\u0131ya bekledi\u011finiz aral\u0131klarla ula\u015fmas\u0131 gerekir. A\u015fa\u011f\u0131daki kontrollerle hem yerel ak\u0131\u015f\u0131 hem de ger\u00e7ek uygulaman\u0131n d\u0131\u015far\u0131dan eri\u015fildi\u011finde nas\u0131l davrand\u0131\u011f\u0131n\u0131 s\u0131nayabilirsiniz.<\/p>\n<ul>\n<li><strong>Do\u011frudan ve proxy ak\u0131\u015f\u0131:<\/strong> Sunucuda <code>curl -N<\/code> ile \u00f6nce <code>127.0.0.1:9000\/events<\/code>, ard\u0131ndan <code>127.0.0.1:8080\/events<\/code> yolunu s\u0131nay\u0131n. \u00d6rnek uygulamada her iki yolda da 10 olay\u0131n yakla\u015f\u0131k birer saniye arayla g\u00f6r\u00fcnmesi beklenir. Yaln\u0131z olaylar\u0131n i\u00e7indeki zaman damgalar\u0131n\u0131n farkl\u0131 olmas\u0131 yeterli de\u011fildir; sat\u0131rlar\u0131n ekrana geli\u015f aral\u0131klar\u0131n\u0131 kar\u015f\u0131la\u015ft\u0131r\u0131n.<\/li>\n<li><strong>Taray\u0131c\u0131 g\u00f6r\u00fcn\u00fcm\u00fc:<\/strong> Ger\u00e7ek uygulamada olay i\u015fleyicisinin \u00e7a\u011fr\u0131ld\u0131\u011f\u0131 anlarla ekran g\u00fcncellemelerini kar\u015f\u0131la\u015ft\u0131r\u0131n. Olaylar d\u00fczenli al\u0131nd\u0131\u011f\u0131 h\u00e2lde metin toplu g\u00f6r\u00fcn\u00fcyorsa proxy yerine aray\u00fcz\u00fcn g\u00fcncellemeleri birle\u015ftirip birle\u015ftirmedi\u011fini veya a\u011f\u0131r i\u015flemler nedeniyle bekletip bekletmedi\u011fini inceleyin.<\/li>\n<li><strong>Bo\u015fta ba\u011flant\u0131:<\/strong> On olayl\u0131k \u00f6rnekten ayr\u0131 olarak, uygulaman\u0131n yeni bildirim \u00fcretmedi\u011fi uzun bir aral\u0131\u011f\u0131 s\u0131nay\u0131n. Ba\u011flant\u0131y\u0131 canl\u0131 tutan heartbeat mesajlar\u0131n\u0131n ula\u015ft\u0131\u011f\u0131n\u0131 ve ba\u011flant\u0131n\u0131n bekledi\u011finiz sessiz d\u00f6nem boyunca a\u00e7\u0131k kald\u0131\u011f\u0131n\u0131 kontrol edin.<\/li>\n<li><strong>Geri d\u00f6n\u00fc\u015f:<\/strong> <code>\/etc\/nginx\/conf.d\/sse-demo.conf.bak<\/code> yede\u011fini koruyun. De\u011fi\u015fikli\u011fi geri alman\u0131z gerekirse yede\u011fi etkin dosyaya kopyalay\u0131n; <code>sudo nginx -t<\/code> ba\u015far\u0131l\u0131 olduktan sonra <code>sudo systemctl reload nginx<\/code> \u00e7al\u0131\u015ft\u0131r\u0131n. Ard\u0131ndan yeni bir ba\u011flant\u0131 a\u00e7\u0131p ak\u0131\u015f\u0131n h\u00e2l\u00e2 al\u0131nabildi\u011fini kontrol edin.<\/li>\n<li><strong>\u00dcretim yolu:<\/strong> Deneme ama\u00e7l\u0131 Python sunucusunu \u00fcretim servisi olarak kullanmay\u0131n. Ger\u00e7ek uygulamada yetkisiz eri\u015fimin engellendi\u011fini ve ba\u011flant\u0131 koptu\u011funda yeniden ba\u011flanman\u0131n beklendi\u011fi gibi \u00e7al\u0131\u015ft\u0131\u011f\u0131n\u0131 kontrol edin. Beklenen e\u015fzamanl\u0131 ba\u011flant\u0131 y\u00fck\u00fcn\u00fc \u00fcretimden ayr\u0131 bir y\u00fck testinde s\u0131nay\u0131n.<\/li>\n<\/ul>\n<p>Bir sonraki ad\u0131m, kendi bilgisayar\u0131n\u0131zdan ger\u00e7ek HTTPS alan ad\u0131ndaki SSE yolunu <code>curl -N<\/code> ve taray\u0131c\u0131yla s\u0131namak olsun. B\u00f6ylece yerel testte bulunmayan CDN ve y\u00fck dengeleyici gibi ara katmanlar\u0131 da denemeye katars\u0131n\u0131z. Yerel ak\u0131\u015f d\u00fczenli, d\u0131\u015f ak\u0131\u015f topluysa \u00e7al\u0131\u015fan uygulama ayarlar\u0131n\u0131 de\u011fi\u015ftirmek yerine bu ek katmanlar\u0131n SSE yoluna uygulad\u0131\u011f\u0131 kurallar\u0131 inceleyin.<\/p>\n<\/div>","protected":false},"excerpt":{"rendered":"<p>Canl\u0131 bildirimler veya yapay zek\u00e2 yan\u0131tlar\u0131 neden par\u00e7a par\u00e7a de\u011fil, toplu g\u00f6r\u00fcn\u00fcr? \u00d6rnek bir SSE u\u00e7 noktas\u0131 \u00fczerinden curl ile uygulama ve Nginx ak\u0131\u015f\u0131n\u0131 kar\u015f\u0131la\u015ft\u0131r\u0131n; tamponlama, s\u0131k\u0131\u015ft\u0131rma ve taray\u0131c\u0131 gecikmesini birbirinden ay\u0131r\u0131n.<\/p>\n","protected":false},"author":4,"featured_media":5964,"comment_status":"closed","ping_status":"","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[26],"tags":[683,682,503,681,680],"class_list":["post-5970","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-teknoloji","tag-akis-teshisi","tag-canli-bildirim","tag-nginx","tag-proxy-tamponlama","tag-sse"],"_links":{"self":[{"href":"https:\/\/www.dchost.com\/blog\/wp-json\/wp\/v2\/posts\/5970","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.dchost.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.dchost.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.dchost.com\/blog\/wp-json\/wp\/v2\/users\/4"}],"replies":[{"embeddable":true,"href":"https:\/\/www.dchost.com\/blog\/wp-json\/wp\/v2\/comments?post=5970"}],"version-history":[{"count":1,"href":"https:\/\/www.dchost.com\/blog\/wp-json\/wp\/v2\/posts\/5970\/revisions"}],"predecessor-version":[{"id":5974,"href":"https:\/\/www.dchost.com\/blog\/wp-json\/wp\/v2\/posts\/5970\/revisions\/5974"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.dchost.com\/blog\/wp-json\/wp\/v2\/media\/5964"}],"wp:attachment":[{"href":"https:\/\/www.dchost.com\/blog\/wp-json\/wp\/v2\/media?parent=5970"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.dchost.com\/blog\/wp-json\/wp\/v2\/categories?post=5970"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.dchost.com\/blog\/wp-json\/wp\/v2\/tags?post=5970"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}