{"id":41433,"date":"2026-04-25T21:04:19","date_gmt":"2026-04-25T18:04:19","guid":{"rendered":"https:\/\/fatihsoysal.com\/blog\/next-js-socket-io-ve-webrtc-ile-gercek-zamanli-satranc-ve-goruntulu-gorusme-rehberi\/"},"modified":"2026-04-25T21:04:19","modified_gmt":"2026-04-25T18:04:19","slug":"next-js-socket-io-ve-webrtc-ile-gercek-zamanli-satranc-ve-goruntulu-gorusme-rehberi","status":"publish","type":"post","link":"https:\/\/fatihsoysal.com\/blog\/next-js-socket-io-ve-webrtc-ile-gercek-zamanli-satranc-ve-goruntulu-gorusme-rehberi\/","title":{"rendered":"Next.js, Socket.IO ve WebRTC ile Ger\u00e7ek Zamanl\u0131 Satran\u00e7 ve G\u00f6r\u00fcnt\u00fcl\u00fc G\u00f6r\u00fc\u015fme Rehberi"},"content":{"rendered":"<h2>Next.js, Socket.IO ve WebRTC ile Ger\u00e7ek Zamanl\u0131 Satran\u00e7 ve G\u00f6r\u00fcnt\u00fcl\u00fc G\u00f6r\u00fc\u015fme Rehberi<\/h2>\n<p>Modern web uygulamalar\u0131, kullan\u0131c\u0131lar\u0131na giderek daha zengin ve etkile\u015fimli deneyimler sunmay\u0131 hedefliyor. Peki, ger\u00e7ek zamanl\u0131 \u00e7ok oyunculu bir satran\u00e7 oyununu, rakiplerinizle ayn\u0131 anda g\u00f6r\u00fcnt\u00fcl\u00fc konu\u015fma imkan\u0131yla birle\u015ftiren karma\u015f\u0131k bir platformu nas\u0131l in\u015fa edebiliriz? Bu makale, Next.js&#8217;in g\u00fc\u00e7l\u00fc frontend yeteneklerini, Socket.IO&#8217;nun h\u0131zl\u0131 ger\u00e7ek zamanl\u0131 ileti\u015fimini ve WebRTC&#8217;nin kesintisiz g\u00f6r\u00fcnt\u00fcl\u00fc g\u00f6r\u00fc\u015fme \u00f6zelliklerini kullanarak b\u00f6yle bir projeyi ad\u0131m ad\u0131m nas\u0131l hayata ge\u00e7irebilece\u011finizi derinlemesine inceliyor. Gelin, bu heyecan verici teknoloji yolculu\u011funa birlikte \u00e7\u0131kal\u0131m.<\/p>\n<h2>Ger\u00e7ek Zamanl\u0131 Web Uygulamalar\u0131n\u0131n Temelleri: Neden Next.js, Socket.IO ve WebRTC?<\/h2>\n<p>Ger\u00e7ek zamanl\u0131 etkile\u015fim, modern web uygulamalar\u0131n\u0131n vazge\u00e7ilmez bir par\u00e7as\u0131 haline geldi. \u00c7evrimi\u00e7i oyunlar, anl\u0131k mesajla\u015fma platformlar\u0131, i\u015f birli\u011fi ara\u00e7lar\u0131 ve canl\u0131 yay\u0131nlar gibi bir\u00e7ok alanda kullan\u0131c\u0131lar, an\u0131nda geri bildirim ve kesintisiz ileti\u015fim bekliyor. Bu beklentiyi kar\u015f\u0131lamak i\u00e7in do\u011fru teknoloji y\u0131\u011f\u0131n\u0131n\u0131 se\u00e7mek projenin ba\u015far\u0131s\u0131 i\u00e7in kritik \u00f6neme sahiptir. Bizim \u00e7ok oyunculu satran\u00e7 ve g\u00f6r\u00fcnt\u00fcl\u00fc g\u00f6r\u00fc\u015fme projemizde, bu ihtiyac\u0131 kar\u015f\u0131lamak \u00fczere Next.js, Socket.IO ve WebRTC \u00fc\u00e7l\u00fcs\u00fcn\u00fc tercih ettik. Her bir teknolojinin kendine \u00f6zg\u00fc avantajlar\u0131, bir araya geldiklerinde g\u00fc\u00e7l\u00fc ve \u00f6l\u00e7eklenebilir bir \u00e7\u00f6z\u00fcm sunar.<\/p>\n<p><strong>Next.js<\/strong>, React tabanl\u0131 bir framework (yaz\u0131l\u0131m \u00e7er\u00e7evesi) olup, sunucu taraf\u0131 render (SSR) ve statik site olu\u015fturma (SSG) gibi \u00f6zellikleriyle performans ve SEO (Arama Motoru Optimizasyonu) a\u00e7\u0131s\u0131ndan b\u00fcy\u00fck avantajlar sa\u011flar. Geli\u015ftirici deneyimini iyile\u015ftiren dosya tabanl\u0131 y\u00f6nlendirme, API rotalar\u0131 ve otomatik kod b\u00f6lme gibi \u00f6zellikler sayesinde, b\u00fcy\u00fck ve karma\u015f\u0131k uygulamalar\u0131n geli\u015ftirilmesi \u00e7ok daha verimli hale gelir. Satran\u00e7 tahtas\u0131 gibi dinamik ve etkile\u015fimli kullan\u0131c\u0131 aray\u00fczlerini (UI) Next.js ile olu\u015fturmak, hem geli\u015ftirme h\u0131z\u0131n\u0131 art\u0131r\u0131r hem de son kullan\u0131c\u0131ya ak\u0131c\u0131 bir deneyim sunar.<\/p>\n<p><strong>Socket.IO<\/strong> ise, sunucu ile istemci aras\u0131nda \u00e7ift y\u00f6nl\u00fc, d\u00fc\u015f\u00fck gecikmeli ve olay tabanl\u0131 ger\u00e7ek zamanl\u0131 ileti\u015fim sa\u011flayan bir k\u00fct\u00fcphanedir. WebSocket protokol\u00fcn\u00fc temel al\u0131r ve taray\u0131c\u0131 uyumlulu\u011fu i\u00e7in HTTP uzun yoklama (long-polling) gibi alternatifleri otomatik olarak kullan\u0131r. Satran\u00e7 gibi anl\u0131k hamlelerin senkronize edilmesi gereken oyunlar i\u00e7in Socket.IO ideal bir \u00e7\u00f6z\u00fcmd\u00fcr. Bir oyuncunun yapt\u0131\u011f\u0131 hamle, an\u0131nda di\u011fer oyuncuya iletilmeli ve oyun durumu her iki tarafta da g\u00fcncellenmelidir. Socket.IO&#8217;nun &#8220;odalar&#8221; (rooms) kavram\u0131 sayesinde, belirli bir oyundaki oyuncular\u0131 kolayca grupland\u0131rabilir ve sadece ilgili oyunculara veri g\u00f6nderebiliriz. \u00d6rne\u011fin, iki oyuncunun bir satran\u00e7 odas\u0131na kat\u0131lmas\u0131 ve hamlelerini sadece o odadaki di\u011fer oyuncuya iletmesi gibi senaryolar\u0131 kolayca y\u00f6netebiliriz.<\/p>\n<p>Son olarak, <strong>WebRTC (Web Real-Time Communication)<\/strong>, taray\u0131c\u0131lar aras\u0131nda do\u011frudan (peer-to-peer) ger\u00e7ek zamanl\u0131 sesli ve g\u00f6r\u00fcnt\u00fcl\u00fc ileti\u015fim sa\u011flayan a\u00e7\u0131k kaynakl\u0131 bir teknolojidir. Bu sayede, oyuncular\u0131n birbirleriyle g\u00f6r\u00fcnt\u00fcl\u00fc konu\u015fma yapabilmesi i\u00e7in ayr\u0131 bir sunucuya ihtiya\u00e7 duyulmaz; veri do\u011frudan taray\u0131c\u0131lar aras\u0131nda akar. Bu, gecikmeyi azalt\u0131r ve sunucu y\u00fck\u00fcn\u00fc hafifletir. WebRTC, medya ak\u0131\u015flar\u0131n\u0131 y\u00f6netme, a\u011f ba\u011flant\u0131lar\u0131n\u0131 kurma ve g\u00fcvenlik sa\u011flama gibi karma\u015f\u0131k g\u00f6revleri basitle\u015ftirir. Ancak, ilk ba\u011flant\u0131 kurulumu ve a\u011f adres \u00e7evirisi (NAT traversal) gibi konular i\u00e7in bir sinyalle\u015fme sunucusuna ihtiya\u00e7 duyar. \u0130\u015fte bu noktada Socket.IO devreye girer; WebRTC&#8217;nin sinyalle\u015fme s\u00fcrecini Socket.IO \u00fczerinden g\u00fcvenilir bir \u015fekilde ger\u00e7ekle\u015ftirebiliriz. Bu \u00fc\u00e7 teknolojinin entegrasyonu, hem performansl\u0131 bir oyun deneyimi hem de zengin bir ileti\u015fim ortam\u0131 sunarak, projemizi modern web standartlar\u0131na uygun hale getirir.<\/p>\n<h3>Next.js ile Kullan\u0131c\u0131 Aray\u00fcz\u00fc (UI) ve Oyun Mant\u0131\u011f\u0131 Geli\u015ftirme<\/h3>\n<p>Next.js, React&#8217;in g\u00fcc\u00fcn\u00fc arkas\u0131na alarak, dinamik ve etkile\u015fimli kullan\u0131c\u0131 aray\u00fczleri olu\u015fturmak i\u00e7in m\u00fckemmel bir platform sunar. \u00c7ok oyunculu satran\u00e7 oyunumuzun temelini atarken, Next.js&#8217;in sundu\u011fu geli\u015ftirme kolayl\u0131klar\u0131ndan ve performans avantajlar\u0131ndan faydalanaca\u011f\u0131z. \u0130lk ad\u0131m, bir Next.js projesi olu\u015fturmak ve gerekli bile\u015fenleri tasarlamakt\u0131r. Proje kurulumu i\u00e7in a\u015fa\u011f\u0131daki komutu kullanabiliriz:<\/p>\n<div class=\"code-container\">\n<pre><code>npx create-next-app satranc-oyunu --ts<\/pre>\n<p><\/code>\n<\/div>\n<p>Bu komut, TypeScript deste\u011fiyle yeni bir Next.js projesi ba\u015flatacakt\u0131r. Projemizin temel yap\u0131s\u0131 olu\u015ftuktan sonra, satran\u00e7 tahtas\u0131n\u0131, ta\u015flar\u0131 ve oyun durumunu y\u00f6netecek React bile\u015fenlerini tasarlamaya ba\u015flayabiliriz. Ana sayfam\u0131zda (<code>pages\/index.tsx<\/code> veya <code>app\/page.tsx<\/code>), bir <code>ChessBoard<\/code> bile\u015feni ve belki de bir <code>VideoCall<\/code> bile\u015feni bulunacakt\u0131r.<\/p>\n<p>Satran\u00e7 tahtas\u0131 genellikle 8x8'lik bir \u0131zgara yap\u0131s\u0131na sahiptir ve her kare, kendi i\u00e7inde bir bile\u015fen olabilir. Her kare, \u00fczerine bir ta\u015f\u0131n yerle\u015fip yerle\u015fmedi\u011fini, se\u00e7ili olup olmad\u0131\u011f\u0131n\u0131 veya olas\u0131 bir hamle hedefi olup olmad\u0131\u011f\u0131n\u0131 g\u00f6steren durum bilgisine sahip olacakt\u0131r. Ta\u015flar (piyon, kale, at, fil, vezir, \u015fah) da ayr\u0131 birer bile\u015fen olarak tasarlanabilir ve konumlar\u0131na g\u00f6re tahta \u00fczerinde render (i\u015fleme) edilirler. Oyunun g\u00f6rsel temsilini olu\u015ftururken, CSS mod\u00fclleri veya Tailwind CSS gibi ara\u00e7larla stil vermek, bile\u015fenlerin temiz ve mod\u00fcler kalmas\u0131na yard\u0131mc\u0131 olur.<\/p>\n<p>Oyun mant\u0131\u011f\u0131, yani hamlelerin do\u011frulanmas\u0131, s\u0131ra kontrol\u00fc, \u015fah \u00e7ekme\/mat durumu gibi kurallar, istemci taraf\u0131nda y\u00f6netilecektir. Ancak, \u00e7ok oyunculu bir oyunda, sunucunun oyunun tek do\u011fruluk kayna\u011f\u0131 olmas\u0131 esast\u0131r. Bu nedenle, istemci taraf\u0131ndaki mant\u0131k sadece kullan\u0131c\u0131ya g\u00f6rsel geri bildirim sa\u011flamak ve potansiyel hamleleri g\u00f6stermek i\u00e7in kullan\u0131l\u0131rken, nihai hamle do\u011frulamas\u0131 ve oyun durumu g\u00fcncellemesi sunucu taraf\u0131ndan yap\u0131lmal\u0131d\u0131r. Bu, hileleri \u00f6nlemek ve oyunun b\u00fct\u00fcnl\u00fc\u011f\u00fcn\u00fc korumak i\u00e7in kritik bir ad\u0131md\u0131r.<\/p>\n<p>Oyun durumunu y\u00f6netmek i\u00e7in React'in kendi <code>useState<\/code> ve <code>useReducer<\/code> hook'lar\u0131n\u0131 kullanabiliriz. Daha karma\u015f\u0131k senaryolar i\u00e7in, React Context API veya Zustand, Jotai gibi hafif durum y\u00f6netimi k\u00fct\u00fcphaneleri tercih edilebilir. \u00d6rne\u011fin, oyunun mevcut durumu (hangi oyuncunun s\u0131ras\u0131 oldu\u011fu, tahtadaki ta\u015flar\u0131n konumu, olas\u0131 hamleler vb.) bir Context i\u00e7inde tutulabilir ve ilgili bile\u015fenler bu Context'ten bilgi alabilir. A\u015fa\u011f\u0131daki basit Next.js bile\u015fen yap\u0131s\u0131, satran\u00e7 tahtas\u0131n\u0131n nas\u0131l temsil edilebilece\u011fine dair bir fikir vermektedir:<\/p>\n<div class=\"code-container\">\n<pre><code>\/\/ components\/ChessBoard.tsx\nimport React from 'react';\n\ninterface ChessBoardProps {\n  boardState: string[][]; \/\/ \u00d6rne\u011fin, 'bP' siyah piyon, 'wK' beyaz \u015fah\n  onMove: (from: string, to: string) => void;\n  selectedSquare: string | null;\n  possibleMoves: string[];\n}\n\nconst ChessBoard: React.FC<ChessBoardProps> = ({ boardState, onMove, selectedSquare, possibleMoves }) => {\n  \/\/ Tahta \u00fczerinde kareleri ve ta\u015flar\u0131 render etme mant\u0131\u011f\u0131\n  return (\n    <div className=\"chess-board\">\n      {boardState.map((row, rowIndex) => (\n        <div key={rowIndex} className=\"board-row\">\n          {row.map((piece, colIndex) => {\n            const squareId = <code>${String.fromCharCode(97 + colIndex)}${8 - rowIndex}<\/code>; \/\/ 'a1', 'b2' gibi\n            const isSelected = selectedSquare === squareId;\n            const isPossibleMove = possibleMoves.includes(squareId);\n\n            return (\n              <div\n                key={squareId}\n                className={<code>square ${ (rowIndex + colIndex) % 2 === 0 ? 'light' : 'dark' } ${isSelected ? 'selected' : ''} ${isPossibleMove ? 'possible-move' : ''}<\/code>}\n                onClick={() => { \/* Kareye t\u0131klama mant\u0131\u011f\u0131 *\/ }}\n              >\n                {piece && <span className={<code>piece ${piece[0] === 'w' ? 'white' : 'black'}<\/code>}>{piece[1]}<\/span>}\n              <\/div>\n            );\n          })}\n        <\/div>\n      ))}\n    <\/div>\n  );\n};\n\nexport default ChessBoard;<\/pre>\n<p><\/code>\n<\/div>\n<p>Bu yap\u0131, satran\u00e7 tahtas\u0131n\u0131n temel g\u00f6rsel temsilini sa\u011flar ve kullan\u0131c\u0131 etkile\u015fimlerini (kareye t\u0131klama, ta\u015f se\u00e7me) y\u00f6netmek i\u00e7in bir temel olu\u015fturur. <code>onMove<\/code> gibi prop'lar arac\u0131l\u0131\u011f\u0131yla, kullan\u0131c\u0131 aray\u00fcz\u00fcnden gelen hamle isteklerini \u00fcst bile\u015fenlere iletebilir ve bu istekleri daha sonra Socket.IO \u00fczerinden sunucuya g\u00f6nderebiliriz. Bu sayede, hem g\u00f6rsel olarak zengin hem de i\u015flevsel bir oyun aray\u00fcz\u00fc elde etmi\u015f oluruz.<\/p>\n<h2>Socket.IO ile Ger\u00e7ek Zamanl\u0131 \u0130leti\u015fim Altyap\u0131s\u0131 Kurulumu<\/h2>\n<p>\u00c7ok oyunculu bir satran\u00e7 oyununda, oyuncular aras\u0131ndaki anl\u0131k etkile\u015fim hayati \u00f6neme sahiptir. Bir oyuncunun yapt\u0131\u011f\u0131 hamle, milisaniyeler i\u00e7inde di\u011fer oyuncuya iletilmeli ve tahta durumu senkronize edilmelidir. \u0130\u015fte bu noktada Socket.IO devreye girerek, istemci ve sunucu aras\u0131nda \u00e7ift y\u00f6nl\u00fc, d\u00fc\u015f\u00fck gecikmeli ve g\u00fcvenilir bir ileti\u015fim kanal\u0131 kurar. Socket.IO, WebSocket protokol\u00fcn\u00fc kullan\u0131r ve taray\u0131c\u0131 veya a\u011f k\u0131s\u0131tlamalar\u0131 nedeniyle WebSocket ba\u011flant\u0131s\u0131 kurulamad\u0131\u011f\u0131nda otomatik olarak HTTP uzun yoklama (long-polling) gibi alternatif y\u00f6ntemlere geri d\u00f6ner. Bu sayede, geni\u015f bir taray\u0131c\u0131 ve a\u011f ortam\u0131nda kesintisiz ger\u00e7ek zamanl\u0131 ileti\u015fim garantisi verir.<\/p>\n<p>Sunucu taraf\u0131nda, genellikle Node.js ve Express.js ile bir arka u\u00e7 (backend) uygulamas\u0131 geli\u015ftiririz. Socket.IO k\u00fct\u00fcphanesini bu sunucuya entegre etmek olduk\u00e7a basittir. \u0130lk olarak, Socket.IO sunucusunu ba\u015flat\u0131r ve HTTP sunucumuza ba\u011flar\u0131z. A\u015fa\u011f\u0131daki kod blo\u011fu, temel bir Socket.IO sunucusunun nas\u0131l kurulaca\u011f\u0131n\u0131 g\u00f6stermektedir:<\/p>\n<div class=\"code-container\">\n<pre><code>\/\/ server\/index.ts (Node.js\/Express sunucusu)\nimport express from 'express';\nimport { createServer } from 'http';\nimport { Server } from 'socket.io';\nimport cors from 'cors';\n\nconst app = express();\nconst httpServer = createServer(app);\nconst io = new Server(httpServer, {\n  cors: {\n    origin: \"*\", \/\/ G\u00fcvenlik i\u00e7in belirli bir domain ile k\u0131s\u0131tlay\u0131n\n    methods: [\"GET\", \"POST\"]\n  }\n});\n\napp.use(cors());\napp.get('\/', (req, res) => {\n  res.send('Satran\u00e7 sunucusu \u00e7al\u0131\u015f\u0131yor!');\n});\n\nio.on('connection', (socket) => {\n  console.log(<code>Kullan\u0131c\u0131 ba\u011fland\u0131: ${socket.id}<\/code>);\n\n  \/\/ Bir odaya kat\u0131lma olay\u0131\n  socket.on('joinRoom', (roomId: string) => {\n    socket.join(roomId);\n    console.log(<code>${socket.id} kullan\u0131c\u0131s\u0131 ${roomId} odas\u0131na kat\u0131ld\u0131.<\/code>);\n    io.to(roomId).emit('playerJoined', <code>${socket.id} odaya kat\u0131ld\u0131.<\/code>);\n  });\n\n  \/\/ Hamle yapma olay\u0131\n  socket.on('makeMove', (data: { roomId: string; move: any; }) => {\n    console.log(<code>Odada hamle yap\u0131ld\u0131 ${data.roomId}:<\/code>, data.move);\n    \/\/ Hamleyi odadaki di\u011fer oyunculara ilet\n    socket.to(data.roomId).emit('moveMade', data.move);\n  });\n\n  \/\/ Ba\u011flant\u0131 kesildi\u011finde\n  socket.on('disconnect', () => {\n    console.log(<code>Kullan\u0131c\u0131 ba\u011flant\u0131s\u0131 kesildi: ${socket.id}<\/code>);\n  });\n});\n\nconst PORT = process.env.PORT || 3001;\nhttpServer.listen(PORT, () => {\n  console.log(<code>Socket.IO sunucusu ${PORT} portunda \u00e7al\u0131\u015f\u0131yor.<\/code>);\n});<\/pre>\n<p><\/code>\n<\/div>\n<p>Bu sunucu kodu, yeni bir istemci ba\u011fland\u0131\u011f\u0131nda bunu loglar, <code>joinRoom<\/code> olay\u0131 ile oyuncular\u0131n belirli odalara kat\u0131lmas\u0131n\u0131 sa\u011flar ve <code>makeMove<\/code> olay\u0131 ile bir oyuncunun hamlesini ayn\u0131 odadaki di\u011fer oyuncuya iletir. Socket.IO'nun en g\u00fc\u00e7l\u00fc \u00f6zelliklerinden biri olan \"odalar\" (rooms), belirli bir oyun veya sohbet kanal\u0131 i\u00e7in \u00f6zel ileti\u015fim alanlar\u0131 olu\u015fturmam\u0131z\u0131 sa\u011flar. Bir oyuncu bir odaya kat\u0131ld\u0131\u011f\u0131nda (<code>socket.join(roomId)<\/code>), o odaya ait t\u00fcm olaylar\u0131 dinleyebilir ve o odaya \u00f6zel mesajlar g\u00f6nderebiliriz (<code>io.to(roomId).emit(...)<\/code> veya <code>socket.to(roomId).emit(...)<\/code>). Bu, mesajlar\u0131n gereksiz yere t\u00fcm ba\u011fl\u0131 istemcilere g\u00f6nderilmesini engelleyerek sunucu y\u00fck\u00fcn\u00fc azalt\u0131r ve gizlili\u011fi art\u0131r\u0131r.<\/p>\n<p>\u0130stemci taraf\u0131nda ise, Next.js uygulamam\u0131zdan Socket.IO sunucusuna ba\u011flan\u0131r ve sunucudan gelen olaylar\u0131 dinleriz. \u0130stemci taraf\u0131ndaki ba\u011flant\u0131 ve olay dinleme a\u015fa\u011f\u0131daki gibi yap\u0131labilir:<\/p>\n<div class=\"code-container\">\n<pre><code>\/\/ client\/components\/GameComponent.tsx (Next.js istemcisi)\nimport React, { useEffect, useState } from 'react';\nimport io from 'socket.io-client';\n\nconst socket = io('http:\/\/localhost:3001'); \/\/ Sunucunuzun adresi\n\nconst GameComponent: React.FC = () => {\n  const [messages, setMessages] = useState<string[]>([]);\n  const roomId = 'chess-game-123'; \/\/ \u00d6rnek oda ID'si\n\n  useEffect(() => {\n    socket.on('connect', () => {\n      console.log('Sunucuya ba\u011fland\u0131:', socket.id);\n      socket.emit('joinRoom', roomId); \/\/ Odaya kat\u0131lma iste\u011fi g\u00f6nder\n    });\n\n    socket.on('playerJoined', (message: string) => {\n      setMessages((prev) => [...prev, message]);\n    });\n\n    socket.on('moveMade', (move: any) => {\n      console.log('Yeni hamle al\u0131nd\u0131:', move);\n      \/\/ Satran\u00e7 tahtas\u0131n\u0131 g\u00fcncelleme mant\u0131\u011f\u0131 buraya gelecek\n      setMessages((prev) => [...prev, <code>Hamle yap\u0131ld\u0131: ${JSON.stringify(move)}<\/code>]);\n    });\n\n    socket.on('disconnect', () => {\n      console.log('Sunucu ba\u011flant\u0131s\u0131 kesildi.');\n    });\n\n    return () => {\n      socket.off('connect');\n      socket.off('playerJoined');\n      socket.off('moveMade');\n      socket.off('disconnect');\n    };\n  }, []);\n\n  const sendMove = (move: any) => {\n    socket.emit('makeMove', { roomId, move });\n  };\n\n  return (\n    <div>\n      <h1>Satran\u00e7 Oyunu<\/h1>\n      <button onClick={() => sendMove({ from: 'e2', to: 'e4' })}>Hamle Yap (\u00d6rnek)<\/button>\n      <div>\n        <h2>Oyun Loglar\u0131<\/h2>\n        <ul>\n          {messages.map((msg, index) => (\n            <li key={index}>{msg}<\/li>\n          ))}\n        <\/ul>\n      <\/div>\n    <\/div>\n  );\n};\n\nexport default GameComponent;<\/pre>\n<p><\/code>\n<\/div>\n<p>Bu istemci kodu, sunucuya ba\u011fland\u0131ktan sonra belirli bir odaya kat\u0131l\u0131r ve sunucudan gelen <code>playerJoined<\/code> ve <code>moveMade<\/code> olaylar\u0131n\u0131 dinler. <code>sendMove<\/code> fonksiyonu ile de sunucuya hamle bilgilerini g\u00f6nderir. Bu temel yap\u0131, oyuncular aras\u0131ndaki ger\u00e7ek zamanl\u0131 hamle senkronizasyonunu sa\u011flamak i\u00e7in yeterlidir. Socket.IO'nun basit API'si ve g\u00fc\u00e7l\u00fc \u00f6zellikleri sayesinde, karma\u015f\u0131k ger\u00e7ek zamanl\u0131 ileti\u015fim gereksinimlerini bile kolayca y\u00f6netebiliriz.<\/p>\n<h3>Satran\u00e7 Hamlelerinin ve Oyun Durumunun Senkronizasyonu<\/h3>\n<p>\u00c7ok oyunculu bir satran\u00e7 oyununda, iki ana senkronizasyon problemiyle kar\u015f\u0131la\u015f\u0131r\u0131z: oyuncular\u0131n hamlelerini birbirlerine iletmesi ve oyunun genel durumunun (kimin s\u0131ras\u0131 oldu\u011fu, \u015fah \u00e7ekme durumu, mat olup olmad\u0131\u011f\u0131 gibi) her iki tarafta da tutarl\u0131 kalmas\u0131. Bu senkronizasyonu sa\u011flamak i\u00e7in Socket.IO'yu etkin bir \u015fekilde kullanaca\u011f\u0131z ve sunucuyu oyunun \"tek do\u011fruluk kayna\u011f\u0131\" (single source of truth) olarak konumland\u0131raca\u011f\u0131z.<\/p>\n<p>\u00d6ncelikle, oyun i\u00e7inde ger\u00e7ekle\u015febilecek olaylar\u0131 (events) tan\u0131mlamam\u0131z gerekir. Bu olaylar, istemciden sunucuya veya sunucudan istemciye g\u00f6nderilen mesajlar\u0131n t\u00fcr\u00fcn\u00fc belirler. Satran\u00e7 oyunumuz i\u00e7in ba\u015fl\u0131ca olaylar \u015funlar olabilir:<\/p>\n<ul>\n<li><code>joinRoom<\/code>: Bir oyuncunun belirli bir oyun odas\u0131na kat\u0131lma iste\u011fi.<\/li>\n<li><code>playerJoined<\/code>: Sunucunun, bir oyuncunun odaya kat\u0131ld\u0131\u011f\u0131n\u0131 di\u011fer oyunculara bildirmesi.<\/li>\n<li><code>makeMove<\/code>: Bir oyuncunun bir hamle yapma iste\u011fi. Bu hamle, ba\u015flang\u0131\u00e7 karesi, biti\u015f karesi ve belki de terfi edecek ta\u015f bilgisi gibi detaylar\u0131 i\u00e7erebilir.<\/li>\n<li><code>moveMade<\/code>: Sunucunun, ge\u00e7erli bir hamlenin yap\u0131ld\u0131\u011f\u0131n\u0131 ve tahta durumunun g\u00fcncellenmesi gerekti\u011fini di\u011fer oyunculara bildirmesi.<\/li>\n<li><code>chatMessage<\/code>: Oyuncular aras\u0131nda sohbet mesajlar\u0131.<\/li>\n<li><code>gameOver<\/code>: Oyunun sona erdi\u011fini (mat, pat, zaman a\u015f\u0131m\u0131 vb.) bildiren olay.<\/li>\n<li><code>requestVideoCall<\/code>: Bir oyuncunun g\u00f6r\u00fcnt\u00fcl\u00fc g\u00f6r\u00fc\u015fme ba\u015flatma iste\u011fi.<\/li>\n<li><code>acceptVideoCall<\/code> \/ <code>rejectVideoCall<\/code>: G\u00f6r\u00fcnt\u00fcl\u00fc g\u00f6r\u00fc\u015fme iste\u011fini kabul etme\/reddetme.<\/li>\n<\/ul>\n<p>Bir oyuncu bir hamle yapt\u0131\u011f\u0131nda, istemci bu hamle bilgisini (\u00f6rne\u011fin, <code>{ from: 'e2', to: 'e4', piece: 'wP' }<\/code>) <code>makeMove<\/code> olay\u0131 ile sunucuya g\u00f6nderir. Sunucu, bu hamleyi ald\u0131ktan sonra a\u015fa\u011f\u0131daki ad\u0131mlar\u0131 izlemelidir:<\/p>\n<ol>\n<li><strong>Hamleyi Do\u011frula:<\/strong> Sunucu, mevcut oyun durumuna g\u00f6re hamlenin ge\u00e7erli olup olmad\u0131\u011f\u0131n\u0131 kontrol eder. Bu kontrol, satran\u00e7 kurallar\u0131n\u0131 (ta\u015f\u0131n hareket kurallar\u0131, \u015fah \u00e7ekme kontrol\u00fc, kendi \u015fah\u0131n\u0131 tehlikeye atmama vb.) i\u00e7erir. Bu ad\u0131m, hileleri \u00f6nlemek i\u00e7in hayati \u00f6neme sahiptir.<\/li>\n<li><strong>Oyun Durumunu G\u00fcncelle:<\/strong> Hamle ge\u00e7erliyse, sunucu kendi b\u00fcnyesindeki oyun tahtas\u0131n\u0131n durumunu g\u00fcnceller. Bu, ta\u015f\u0131n yeni konumuna ta\u015f\u0131nmas\u0131, varsa bir ta\u015f\u0131n al\u0131nmas\u0131 ve s\u0131ran\u0131n di\u011fer oyuncuya ge\u00e7mesi gibi i\u015flemleri i\u00e7erir.<\/li>\n<li><strong>Odaya Bildir:<\/strong> G\u00fcncellenmi\u015f hamle ve yeni oyun durumu, <code>moveMade<\/code> olay\u0131 ile ayn\u0131 odadaki di\u011fer oyunculara iletilir. Sunucu, <code>socket.to(roomId).emit('moveMade', newGameState)<\/code> veya <code>io.to(roomId).emit('moveMade', newGameState)<\/code> kullanarak sadece ilgili oyunculara mesaj g\u00f6nderir.<\/li>\n<\/ol>\n<p>\u0130stemciler, <code>moveMade<\/code> olay\u0131n\u0131 dinleyerek bu g\u00fcncellemeyi al\u0131r ve kendi yerel tahtalar\u0131n\u0131 ve kullan\u0131c\u0131 aray\u00fczlerini (UI) yeni duruma g\u00f6re render ederler. Bu yakla\u015f\u0131m, \"yar\u0131\u015f ko\u015fullar\u0131n\u0131\" (race conditions) ve tutars\u0131z durumlar\u0131 \u00f6nler, \u00e7\u00fcnk\u00fc t\u00fcm hamleler tek bir merkezi otorite (sunucu) taraf\u0131ndan i\u015flenir ve onaylan\u0131r.<\/p>\n<p>A\u015fa\u011f\u0131da, bir hamle g\u00f6nderme ve alma mekanizmas\u0131n\u0131 g\u00f6steren basit bir \u00f6rnek yer almaktad\u0131r:<\/p>\n<div class=\"code-container\">\n<pre><code>\/\/ client\/utils\/socketService.ts (\u0130stemci taraf\u0131)\nimport { Socket } from 'socket.io-client';\n\nexport const sendChessMove = (socket: Socket, roomId: string, move: any) => {\n  if (socket.connected) {\n    socket.emit('makeMove', { roomId, move });\n    console.log(<code>Hamle g\u00f6nderildi: ${JSON.stringify(move)}<\/code>);\n  } else {\n    console.warn('Socket ba\u011flant\u0131s\u0131 yok, hamle g\u00f6nderilemedi.');\n  }\n};\n\n\/\/ Sunucu taraf\u0131nda (server\/index.ts) makeMove olay\u0131n\u0131 i\u015fleme\n\/*\nsocket.on('makeMove', (data: { roomId: string; move: any; }) => {\n  const { roomId, move } = data;\n  \/\/ Burada hamle do\u011frulama mant\u0131\u011f\u0131 olacak\n  const isValidMove = validateChessMove(roomId, move); \/\/ Kendi do\u011frulama fonksiyonunuz\n\n  if (isValidMove) {\n    \/\/ Oyun durumunu g\u00fcncelle\n    const newGameState = updateGameState(roomId, move); \/\/ Kendi g\u00fcncelleme fonksiyonunuz\n    \/\/ Odaya hamlenin yap\u0131ld\u0131\u011f\u0131n\u0131 ve yeni durumu bildir\n    io.to(roomId).emit('moveMade', newGameState);\n  } else {\n    \/\/ Ge\u00e7ersiz hamle ise sadece hamleyi yapan istemciye bildir\n    socket.emit('invalidMove', 'Ge\u00e7ersiz hamle!');\n  }\n});\n*\/<\/pre>\n<p><\/code>\n<\/div>\n<p>Bu senkronizasyon stratejisi, satran\u00e7 gibi karma\u015f\u0131k kurallara sahip<\/p>\n","protected":false},"excerpt":{"rendered":"Modern web uygulamalar\u0131, kullan\u0131c\u0131lar\u0131na giderek daha zengin ve etkile\u015fimli deneyimler sunmay\u0131 hedefliyor.","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"csco_page_header_type":"","csco_page_load_nextpost":"","csco_page_subscribe_form":"","csco_page_contact_form":"","footnotes":""},"categories":[1],"tags":[],"class_list":{"0":"post-41433","1":"post","2":"type-post","3":"status-publish","4":"format-standard","6":"category-genel","7":"cs-entry","8":"cs-video-wrap"},"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v20.5 (Yoast SEO v25.3.1) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Next.js, Socket.IO ve WebRTC ile Ger\u00e7ek Zamanl\u0131 Satran\u00e7 ve G\u00f6r\u00fcnt\u00fcl\u00fc G\u00f6r\u00fc\u015fme Rehberi - Kodlar\u0131n Gizemli D\u00fcnyas\u0131<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/fatihsoysal.com\/blog\/next-js-socket-io-ve-webrtc-ile-gercek-zamanli-satranc-ve-goruntulu-gorusme-rehberi\/\" \/>\n<meta property=\"og:locale\" content=\"tr_TR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Next.js, Socket.IO ve WebRTC ile Ger\u00e7ek Zamanl\u0131 Satran\u00e7 ve G\u00f6r\u00fcnt\u00fcl\u00fc G\u00f6r\u00fc\u015fme Rehberi\" \/>\n<meta property=\"og:description\" content=\"Modern web uygulamalar\u0131, kullan\u0131c\u0131lar\u0131na giderek daha zengin ve etkile\u015fimli deneyimler sunmay\u0131 hedefliyor.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/fatihsoysal.com\/blog\/next-js-socket-io-ve-webrtc-ile-gercek-zamanli-satranc-ve-goruntulu-gorusme-rehberi\/\" \/>\n<meta property=\"og:site_name\" content=\"Kodlar\u0131n Gizemli D\u00fcnyas\u0131\" \/>\n<meta property=\"article:published_time\" content=\"2026-04-25T18:04:19+00:00\" \/>\n<meta name=\"author\" content=\"Fatih Soysal\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Yazan:\" \/>\n\t<meta name=\"twitter:data1\" content=\"Fatih Soysal\" \/>\n\t<meta name=\"twitter:label2\" content=\"Tahmini okuma s\u00fcresi\" \/>\n\t<meta name=\"twitter:data2\" content=\"13 dakika\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/next-js-socket-io-ve-webrtc-ile-gercek-zamanli-satranc-ve-goruntulu-gorusme-rehberi\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/next-js-socket-io-ve-webrtc-ile-gercek-zamanli-satranc-ve-goruntulu-gorusme-rehberi\/\"},\"author\":{\"name\":\"Fatih Soysal\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"headline\":\"Next.js, Socket.IO ve WebRTC ile Ger\u00e7ek Zamanl\u0131 Satran\u00e7 ve G\u00f6r\u00fcnt\u00fcl\u00fc G\u00f6r\u00fc\u015fme Rehberi\",\"datePublished\":\"2026-04-25T18:04:19+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/next-js-socket-io-ve-webrtc-ile-gercek-zamanli-satranc-ve-goruntulu-gorusme-rehberi\/\"},\"wordCount\":2036,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/next-js-socket-io-ve-webrtc-ile-gercek-zamanli-satranc-ve-goruntulu-gorusme-rehberi\/#respond\"]}],\"copyrightYear\":\"2026\",\"copyrightHolder\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/next-js-socket-io-ve-webrtc-ile-gercek-zamanli-satranc-ve-goruntulu-gorusme-rehberi\/\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/next-js-socket-io-ve-webrtc-ile-gercek-zamanli-satranc-ve-goruntulu-gorusme-rehberi\/\",\"name\":\"Next.js, Socket.IO ve WebRTC ile Ger\u00e7ek Zamanl\u0131 Satran\u00e7 ve G\u00f6r\u00fcnt\u00fcl\u00fc G\u00f6r\u00fc\u015fme Rehberi - Kodlar\u0131n Gizemli D\u00fcnyas\u0131\",\"isPartOf\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#website\"},\"datePublished\":\"2026-04-25T18:04:19+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/next-js-socket-io-ve-webrtc-ile-gercek-zamanli-satranc-ve-goruntulu-gorusme-rehberi\/#breadcrumb\"},\"inLanguage\":\"tr\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/fatihsoysal.com\/blog\/next-js-socket-io-ve-webrtc-ile-gercek-zamanli-satranc-ve-goruntulu-gorusme-rehberi\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/next-js-socket-io-ve-webrtc-ile-gercek-zamanli-satranc-ve-goruntulu-gorusme-rehberi\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Anasayfa\",\"item\":\"https:\/\/fatihsoysal.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Next.js, Socket.IO ve WebRTC ile Ger\u00e7ek Zamanl\u0131 Satran\u00e7 ve G\u00f6r\u00fcnt\u00fcl\u00fc G\u00f6r\u00fc\u015fme Rehberi\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#website\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/\",\"name\":\"Fatihsoysal.com\",\"description\":\"Blog - Yaz\u0131l\u0131m D\u00fcnyas\u0131 Tecr\u00fcbelerim\",\"publisher\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/fatihsoysal.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"tr\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1\",\"name\":\"Fatih Soysal\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"tr\",\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png\",\"contentUrl\":\"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png\",\"width\":512,\"height\":512,\"caption\":\"Fatih Soysal\"},\"logo\":{\"@id\":\"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/\"},\"description\":\"Kullan\u0131m ve kodlama m\u00fckemmeliyetini odak alan uygulamalar olu\u015fturma deneyimine sahip, profesyonel olarak 15+ y\u0131l \u00fczeri deneyime sahip bir yaz\u0131l\u0131m m\u00fchendisi.\",\"url\":\"https:\/\/fatihsoysal.com\/blog\/author\/fatihsoysal\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Next.js, Socket.IO ve WebRTC ile Ger\u00e7ek Zamanl\u0131 Satran\u00e7 ve G\u00f6r\u00fcnt\u00fcl\u00fc G\u00f6r\u00fc\u015fme Rehberi - Kodlar\u0131n Gizemli D\u00fcnyas\u0131","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/fatihsoysal.com\/blog\/next-js-socket-io-ve-webrtc-ile-gercek-zamanli-satranc-ve-goruntulu-gorusme-rehberi\/","og_locale":"tr_TR","og_type":"article","og_title":"Next.js, Socket.IO ve WebRTC ile Ger\u00e7ek Zamanl\u0131 Satran\u00e7 ve G\u00f6r\u00fcnt\u00fcl\u00fc G\u00f6r\u00fc\u015fme Rehberi","og_description":"Modern web uygulamalar\u0131, kullan\u0131c\u0131lar\u0131na giderek daha zengin ve etkile\u015fimli deneyimler sunmay\u0131 hedefliyor.","og_url":"https:\/\/fatihsoysal.com\/blog\/next-js-socket-io-ve-webrtc-ile-gercek-zamanli-satranc-ve-goruntulu-gorusme-rehberi\/","og_site_name":"Kodlar\u0131n Gizemli D\u00fcnyas\u0131","article_published_time":"2026-04-25T18:04:19+00:00","author":"Fatih Soysal","twitter_card":"summary_large_image","twitter_misc":{"Yazan:":"Fatih Soysal","Tahmini okuma s\u00fcresi":"13 dakika"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/fatihsoysal.com\/blog\/next-js-socket-io-ve-webrtc-ile-gercek-zamanli-satranc-ve-goruntulu-gorusme-rehberi\/#article","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/next-js-socket-io-ve-webrtc-ile-gercek-zamanli-satranc-ve-goruntulu-gorusme-rehberi\/"},"author":{"name":"Fatih Soysal","@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"headline":"Next.js, Socket.IO ve WebRTC ile Ger\u00e7ek Zamanl\u0131 Satran\u00e7 ve G\u00f6r\u00fcnt\u00fcl\u00fc G\u00f6r\u00fc\u015fme Rehberi","datePublished":"2026-04-25T18:04:19+00:00","mainEntityOfPage":{"@id":"https:\/\/fatihsoysal.com\/blog\/next-js-socket-io-ve-webrtc-ile-gercek-zamanli-satranc-ve-goruntulu-gorusme-rehberi\/"},"wordCount":2036,"commentCount":0,"publisher":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"inLanguage":"tr","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/fatihsoysal.com\/blog\/next-js-socket-io-ve-webrtc-ile-gercek-zamanli-satranc-ve-goruntulu-gorusme-rehberi\/#respond"]}],"copyrightYear":"2026","copyrightHolder":{"@id":"https:\/\/fatihsoysal.com\/blog\/#organization"}},{"@type":"WebPage","@id":"https:\/\/fatihsoysal.com\/blog\/next-js-socket-io-ve-webrtc-ile-gercek-zamanli-satranc-ve-goruntulu-gorusme-rehberi\/","url":"https:\/\/fatihsoysal.com\/blog\/next-js-socket-io-ve-webrtc-ile-gercek-zamanli-satranc-ve-goruntulu-gorusme-rehberi\/","name":"Next.js, Socket.IO ve WebRTC ile Ger\u00e7ek Zamanl\u0131 Satran\u00e7 ve G\u00f6r\u00fcnt\u00fcl\u00fc G\u00f6r\u00fc\u015fme Rehberi - Kodlar\u0131n Gizemli D\u00fcnyas\u0131","isPartOf":{"@id":"https:\/\/fatihsoysal.com\/blog\/#website"},"datePublished":"2026-04-25T18:04:19+00:00","breadcrumb":{"@id":"https:\/\/fatihsoysal.com\/blog\/next-js-socket-io-ve-webrtc-ile-gercek-zamanli-satranc-ve-goruntulu-gorusme-rehberi\/#breadcrumb"},"inLanguage":"tr","potentialAction":[{"@type":"ReadAction","target":["https:\/\/fatihsoysal.com\/blog\/next-js-socket-io-ve-webrtc-ile-gercek-zamanli-satranc-ve-goruntulu-gorusme-rehberi\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/fatihsoysal.com\/blog\/next-js-socket-io-ve-webrtc-ile-gercek-zamanli-satranc-ve-goruntulu-gorusme-rehberi\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Anasayfa","item":"https:\/\/fatihsoysal.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Next.js, Socket.IO ve WebRTC ile Ger\u00e7ek Zamanl\u0131 Satran\u00e7 ve G\u00f6r\u00fcnt\u00fcl\u00fc G\u00f6r\u00fc\u015fme Rehberi"}]},{"@type":"WebSite","@id":"https:\/\/fatihsoysal.com\/blog\/#website","url":"https:\/\/fatihsoysal.com\/blog\/","name":"Fatihsoysal.com","description":"Blog - Yaz\u0131l\u0131m D\u00fcnyas\u0131 Tecr\u00fcbelerim","publisher":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/fatihsoysal.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"tr"},{"@type":["Person","Organization"],"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/002a254750921dcfd568a99e48240dd1","name":"Fatih Soysal","image":{"@type":"ImageObject","inLanguage":"tr","@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png","contentUrl":"https:\/\/fatihsoysal.com\/blog\/wp-content\/uploads\/2024\/04\/cropped-replicate-prediction-3kgg1hgjn5rgp0cf0p5tr0jw7w-1.png","width":512,"height":512,"caption":"Fatih Soysal"},"logo":{"@id":"https:\/\/fatihsoysal.com\/blog\/#\/schema\/person\/image\/"},"description":"Kullan\u0131m ve kodlama m\u00fckemmeliyetini odak alan uygulamalar olu\u015fturma deneyimine sahip, profesyonel olarak 15+ y\u0131l \u00fczeri deneyime sahip bir yaz\u0131l\u0131m m\u00fchendisi.","url":"https:\/\/fatihsoysal.com\/blog\/author\/fatihsoysal\/"}]}},"yoast_meta":{"yoast_wpseo_title":"","yoast_wpseo_metadesc":"","yoast_wpseo_canonical":""},"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/41433","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/comments?post=41433"}],"version-history":[{"count":0,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/posts\/41433\/revisions"}],"wp:attachment":[{"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/media?parent=41433"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/categories?post=41433"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fatihsoysal.com\/blog\/wp-json\/wp\/v2\/tags?post=41433"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}