Pratik Java Uygulamaları

WebSocket’in Temelleri ve Java ile Dinamik Çoklu Sohbet Uygulaması

ierdoganierdogan10 Aralık 2025
WebSocket’in Temelleri ve Java ile Dinamik Çoklu Sohbet Uygulaması

WebSocket, TCP protokolü üzerinden çift yönlü (full-duplex) iletişim kanalları sağlayan esnek ve yüksek verimli bir iletişim protokoldür.Web sunucularında ve tarayıcılarda kullanılmak üzere tasarlanmıştır. 2011 yılında RFC 6455 olarak standart hale getirilmiştir.WebSocket, istemci ile sunucu arasında kalıcı (persistent) bir bağlantı kurulmasını sağlar.Çift yönlü iletişim modeli sayesinde, istemci ve sunucu birbirine istediği anda ve istediği ölçüde veri gönderebilir. Bu özellik, WebSocket’i klasik HTTP protokolün ayırmaktadır.

WebSocket Kullanmanın Avantajları nelerdir?

WebSocket protokolünün başlıca avantajlarını aşağıdaki gibi özetleyebiliriz :

Gerçek Zamanlı İletişim
WebSocket, sunucu ile istemci arasında gerçek zamanlı (real-time) iletişim sağlar. Bu sayede daha hızlı ve tepkisel uygulamalar geliştirmeye olanak tanır.

Düşük Gecikme (Low Latency)
HTTP’ye kıyasla çok daha az başlık bilgisi taşır bu durum gecikme süresini oldukça düşürür. Veri paketleri çok daha hızlı gönderilip alınır. Bu nedenle hızlı tepki süresi gerektiren uygulamalar (sohbet, canlı skor, borsa takibi vb.) için idealdir.

Daha Az Bant Genişliği Tüketimi
Kalıcı (persistent) bir bağlantı kurduğu için gereksiz veri alışverişi ortadan kalkar. Bağlantı bir kez kurulduktan sonra kapanana kadar devam eder. HTTP’de her istekte yeni bağlantı kurulurken, WebSocket'te kalıcı bağlantı sayesinde, kaynak ve bant genişliği tasarrufu sağlanır.

Çift Yönlü (Bi-Directional) İletişim
Sunucu, istemciden bağımsız olarak istediği anda istemciye veri gönderebilir (server-push). Bu özellik, klasik HTTP’nin yalnızca istek → yanıt mantığıyla çalışan yapısından tamamen farklıdır ve gerçek zamanlı uygulamaların temelini oluşturur.

Esnek ve Verimli Protokol
WebSocket çok geniş bir kullanım alanına sahip esnek bir protokoldür. Web uygulamalarından IoT cihazlarına kadar her ortamda rahatlıkla kullanılabilir. HTTP’ye göre çok daha küçük başlık (header) boyutuna sahip olduğu için daha küçük paketlerin oluşmasına olanak tanır, daha az kaynak tüketir bu durum yüksek verimlilik sağlar.

WebSocket, gerçek zamanlı, düşük gecikmeli ve bant genişliği dostu uygulamalar geliştirmek için günümüzün en önemli protokolüdür.

1*de9VVpUpwXsnEilfuVWFww.png

WebSocket protokolünün temel taşı Frame'lere genel bir bakış;

Frame'ler , istemci ile sunucu arasında düşük gecikmeli, çift yönlü (full-duplex) iletişimin gerçekleşmesini sağlayan en küçük veri birimidir. Her bir WebSocket mesajı, bir veya birden fazla frame’den oluşur. Büyük mesajlar parçalara bölünerek iletilir (fragmentation) ve alıcı tarafında yeniden birleştirilir.

Bir WebSocket frame’inin bileşenleri aşağıdaki gibidir;

1-Temel Header (2 bayt)

FIN biti (1 bit): Mesajın son frame’i olup olmadığını belirtir. 1 = bu mesajın son parçası, 0 = devamı gelecek.

RSV1, RSV2, RSV3 (her biri 1 bit): Sadece uzantılar (extension) tanımlandığında kullanılabilir (örneğin per-message compression extension).

Opcode (4 bit): Frame’in türünü tanımlar.

0x0 = devam frame’i
0x1 = text frame
0x2 = binary frame
0x8 = connection close
0x9 = ping
0xA = pong
diğerleri kontrol frame’leri veya gelecekte kullanılmak üzere ayrılmış bitlerdir.

Mask biti (1 bit): Payload’un maskelenip ,maskelenmediğini belirtmek için kullanılan pinlerdir.

İstemciden → sunucuya gönderilen tüm frame’lerde bu bit zorunlu olarak 1 olmalıdır.

Sunucudan → istemciye gönderilenlerde ise 0'dır.

Payload length (7 bit): uzunluk alanıdır.

0–125 → gerçek uzunluk
126 → sonraki 2 bayt (16-bit unsigned) gerçek uzunluğu verir
127 → sonraki 8 bayt (64-bit unsigned) gerçek uzunluğu verir

2-Extended Payload

Length (opsiyonel) : Payload length alanı 126 ise → 2 bayt daha okunur
127 ise → 8 bayt daha okunur

3-Masking Key (4 bayt)

Mask biti 1 ise bulunur. İstemciden gelen tüm frame’ler bu 4 baytlık rastgele anahtarla maskelenir.

Maskeleme işlemi sırasında kullanılan algoritmik mantık : gerçek_veri[i] = gizlenmiş_veri[i] XOR mask[i mod 4] şeklindedir.

Sunucu bu anahtarı kullanarak veriyi geri çözer (unmask).

4-Payload Data (Yük Verisi) Gerçek mesaj içeriği burada yer alır. Text frame’lerde (opcode=1) payload mutlaka geçerli ve UTF-8 olmalıdır. Binary frame’lerde (opcode=2) herhangi ikili veri olabilir.

Kontrol frame’leri (close, ping, pong) için payload uzunluğu maksimum 125 bayttır.

Kalıcı Bağlantı Kurmak, Veri Aktarım Gecikmesini Önemli Ölçüde Azaltır

WebSocket’in en büyük güçlerinden biri, bağlantıyı bir kez kurduktan sonra açık (persistent) tutmasıdır. Geleneksel HTTP’de her istek (mesaj, bildirim, güncelleme) için şu adımlar tekrarlanır:

  • Yeni TCP bağlantısı kurulur (3-way handshake)

  • HTTP başlıkları gönderilir/alınır (~200–800 byte)

  • TLS/SSL handshake (eğer HTTPS ise)

  • Veri aktarılır

  • Bağlantı kapatılır veya yeniden kullanılır (ama yine de başlık maliyeti vardır)

Bu döngü, özellikle sık veri alışverişi gereken uygulamalarda milisaniyeler hatta saniyeler düzeyinde gecikme yaratır.

WebSocket’te ise:

  • Bağlantı sadece bir kez kurulur (HTTP Upgrade ile başlar)

  • İlk handshake’ten sonra başlık boyutu yalnızca 2–14 byte olur

  • TCP bağlantısı açık kaldığı sürece ek handshake gerekmez

  • Veri,doğrudan gönderilir/alınır

1*KOaIOc_1Bj9-Oq4z9bwEqQ.png

WebSocket’in düşük gecikme ve gerçek zamanlı iletişim yeteneği sayesinde günümüzde neredeyse her sektörde tercih edilmektedir:

Kullanım Alanı

Örnekler

Mesajlaşma Uygulamaları

WhatsApp, Slack, Discord, Telegram gibi sistemlerin canlı sohbet özelliği WebSocket ile çalışır.

Gerçek Zamanlı Oyunlar

Agar.io, online satranç, çok oyunculu battle-royale veya tarayıcı tabanlı MMO oyunlar.

Canlı Güncellemeler

Borsa takip ekranları, kripto para fiyatları, canlı spor skorları, haber akışları.

IoT (Nesnelerin İnterneti)

Akıllı ev cihazları, sensör verilerinin anlık izlenmesi, uzaktan kontrol panelleri.

Finans Uygulamaları

Algo-trading platformları, gerçek zamanlı portföy takibi, emir iletimi, finansal dashboard’ları.

Güvenlik ve İzleme Sistemleri

IP kamera canlı yayınları, hırsız alarmı anlık bildirimleri, erişim kontrol sistemleri.

Blockchain ve Kripto

Cüzdan bakiyesi güncellemeleri, yeni blok/mempool takibi, DEX’lerde fiyat ve işlem akışı.

İşbirliği Araçları

Google Docs, Figma, Miro, Notion gibi aynı anda birden çok kişinin düzenleme yaptığı uygulamalar.

Canlı Yayın Kontrolü

Twitch chat, YouTube canlı yorumlar, OBS kontrol sinyalleri.

Eğitim ve Online Sınav

Canlı yoklama, anlık soru-cevap, interaktif whiteboard sistemleri.

Kullanıcıların birbirine veya sisteme anında ve sürekli veri göndermesi/alması gereken her türlü uygulama WebSocket’in doğal kullanım alanıdır.

Java ile Temel Socket Programlama: Sohbet Uygulaması

Bu bölümde, harici bir kütüphane kullanmadan,java (java.net ve java.io) ile çalışan çok kullanıcılı basit bir sohbet uygulaması oluşturuldu.Bu uygulama, socket programlamanın temel kavramlarını öğrenmek ve pratik yapmak isteyenler için, temel bilgileri içermektedir.

Uygulanın özelliklerini basitçe aşağıdaki gibi özetleyebiliriz,

  • Gerçek zamanlı mesajlaşma

  • Çoklu kullanıcı desteği

  • Kullanıcı giriş/çıkış bildirimleri

  • Düşük gecikme, hafif ve anlaşılır kod yapısı

Uygulama klasik istemci-sunucu (client-server) mimarisine dayalıdır ve iki ana bileşenden oluşur:

  • ChatSocketServer → Sunucu tarafını temsil etmektedir.

  • ChatSocketClient → İstemci tarafını temsil etmektedir.

ChatSocketServer;

ChatSocketServer 'daki temel iş akışı aşağıdaki gibidir;

1. Sunucu Başlatılır ve Port Dinlemeye Alınır

(ServerSocket serverSocket = new ServerSocket(12345))

2. Her İstemci İçin Ayrı Bir İş Parçacığı (Thread) Oluşturulur

(new ClientHandler(clientSocket).start();)

3. Kullanıcı Adı Alınır ve Sisteme Kaydedilir

(Enter your username:)

4. Yeni Katılım ve Çıkış Bildirimleri Otomatik Yapılır

broadcastMessage("Server", username + " has joined the chat.");

broadcastMessage("Server", username + " has left the chat.");

5. Mesajlar Tüm İstemcilere Anında Yayınlanır (Broadcast)

while ((message = in.readLine()) != null) {
broadcastMessage(username, message);
}

1-ChatSocketServer’a ait kod bloğu;

package com.testsocket;

import java.io.*;
import java.net.*;
import java.util.*;

public class ChatSocketServer {

private static final int PORT = 12345;
private static Map<String, PrintWriter> clientWriters = new HashMap<>();

public static void main(String[] args) {
System.out.println("Server is starting...");
try (ServerSocket serverSocket = new ServerSocket(PORT)) {
while (true) {
Socket clientSocket = serverSocket.accept();
new ClientHandler(clientSocket).start();
}
} catch (IOException e) {
e.printStackTrace();
}
}

private static class ClientHandler extends Thread {
private Socket socket;
private String username;
private BufferedReader in;
private PrintWriter out;

public ClientHandler(Socket socket) {
this.socket = socket;
}

public void run() {
try {
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out = new PrintWriter(socket.getOutputStream(), true);

out.println("Enter your username:");
username = in.readLine();
synchronized (clientWriters) {
clientWriters.put(username, out);
}
System.out.println(username + " has connected.");

// Notify other clients that a user has joined
broadcastMessage("Server", username + " has joined the chat.");

// Listen for incoming messages and forward them
String message;
while ((message = in.readLine()) != null) {
System.out.println("[" + username + "]: " + message);
broadcastMessage(username, message);
}
} catch (IOException e) {
e.printStackTrace();
} finally {

if (username != null) {
synchronized (clientWriters) {
clientWriters.remove(username);
}
broadcastMessage("Server", username + " has left the chat.");
}
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

// Send the message to all clients
private void broadcastMessage(String sender, String message) {
synchronized (clientWriters) {
for (PrintWriter writer : clientWriters.values()) {
writer.println("[" + sender + "]: " + message);
}
}
}
}
}


ChatSocketClient;

ChatSocketClient'daki temel iş akışı aşağıdaki gibidir;

1-Sunucuya Bağlantı Kurulur

2-Giriş/Çıkış Akışları (Stream) Hazırlanır

3-Kullanıcı Adı Sunucu Tarafından Sorulur ve Gönderilir

4-Gelen Mesajları Gerçek Zamanlı Göstermek İçin Ayrı Bir Thread Başlatılır

5-Kullanıcının Yazdıkları Sunucuya Anında Gönderilir (Ana Thread)

6-Bağlantı Koparsa veya Sunucu Kapanırsa Program Temiz Şekilde Sonlanır

2-ChatSocketClient'a ait kod bloğu;

package com.testsocket;

import java.io.*;
import java.net.*;
import java.util.Scanner;

public class ChatSocketClient {

private static final String SERVER_ADDRESS = "127.0.0.1";
private static final int SERVER_PORT = 12345;

public static void main(String[] args) {
try (Socket socket = new Socket(SERVER_ADDRESS, SERVER_PORT)) {
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);

Scanner scanner = new Scanner(System.in);

// A separate thread to listen for messages from the server
new Thread(() -> {
try {
String message;
while ((message = in.readLine()) != null) {
System.out.println(message);
}
} catch (IOException e) {
e.printStackTrace();
}
}).start();

// Read user messages and send them to the server
while (true) {
String message = scanner.nextLine();
out.println(message);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}

Uygulama akışı aşağıdaki gibidir;

1. Sunucu Bağlantısı

İstemci, belirtilen IP adresi ve port üzerinden sunucuya bağlanarak iletişim kanalını oluşturur.

1*LSLmQMD8XeG8Ow1qFj4Fxg.png

2.İstemci Bağlantısı:

ChatSocketCLient çalıştırılır, sunucuya bağlanır ve kullanıcıdan bir kullanıcı adı girmesi beklenilir.

1*EP0vJtFHH2GlDNgrCBwhMw.png

3.Mesajlaşma:
Kullanıcılar mesaj yazdıkça, bu mesajlar sunucu aracılığıyla tüm bağlı diğer istemcilere iletilir.

1*LTYsP2u1QUMlV089Lss7gg.png

4.Bağlantı Yönetimi:
Bir istemci bağlantıyı kestiğinde, sunucu diğer istemcileri bilgilendirir ve bağlantısı kesilen istemciye ait kaynakları serbest bırakır.

WebSocket protokolü ve temel socket programlama hakkında bu makaleyi okuduğunuz için teşekkür ederim! WebSocket veya socket programlamayla ilgili düşüncelerinizi ve deneyimlerinizi yorumlarda paylaşmaktan çekinmeyin. Bu teknolojiyle geliştirdiğiniz projeleri veya karşılaştığınız zorlukları özellikle duymak isterim.

Eğer bu makaleyi faydalı bulduysanız, daha fazla kişiye ulaşmasına yardımcı olmak için paylaşmanızı rica ederim.

(Not: Aynı makale 2025 yılında Medium’da da yayınlanmıştır.)

Bu makaleyi beğendiniz mi?

Arkadaşlarınızla paylaşın