Skip to content

Instantly share code, notes, and snippets.

@diloabininyeri
Created December 28, 2023 10:10
Show Gist options
  • Save diloabininyeri/1adb0889a663c131e5fcef576a7b995c to your computer and use it in GitHub Desktop.
Save diloabininyeri/1adb0889a663c131e5fcef576a7b995c to your computer and use it in GitHub Desktop.
An example of php socket server and js socket client
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>WebSocket Client</title>
</head>
<body>
<button onclick="sendCalculation()">Calculate</button>
<div id="result"></div>
<script>
const socket = new WebSocket('ws://127.0.0.1:8080');
socket.addEventListener('open', (event) => {
console.log('WebSocket connection opened');
// Her iki saniyede bir mesaj gönder
setInterval(() => {
const message = 'Hello from JavaScript';
console.log(`Sending message: ${message}`);
socket.send(message);
}, 4000);
});
socket.addEventListener('message', (event) => {
const message = event.data;
console.log(`Received message: ${message}`);
});
socket.addEventListener('close', (event) => {
console.log('socket is closed', JSON.stringify(event));
});
function sendCalculation() {
if (socket.readyState === WebSocket.OPEN) {
// Bağlantı tamamlandı, şimdi mesaj gönderebiliriz
socket.send('test foo');
} else {
// Bağlantı tamamlanmadı, bir hata mesajı gösterebiliriz veya başka bir işlem yapabiliriz
console.error('Bağlantı hala tamamlanmadı.');
}
}
</script>
</body>
</html>
<?php
class SocketServer
{
private $ip;
private $port;
private $masterSocket;
private $clients = [];
private string $message;
public function __construct($ip, $port)
{
$this->ip = $ip;
$this->port = $port;
$this->createSocket();
$this->bindAndListen();
$this->acceptConnections();
}
private function createSocket()
{
$this->masterSocket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if ($this->masterSocket === false) {
die('Hata: Soket oluşturulamadı: ' . socket_strerror(socket_last_error()));
}
}
private function bindAndListen()
{
if (!socket_bind($this->masterSocket, $this->ip, $this->port)) {
die('Hata: Soket bağlanamadı: ' . socket_strerror(socket_last_error()));
}
if (!socket_listen($this->masterSocket)) {
die('Hata: Soket dinlenemedi: ' . socket_strerror(socket_last_error()));
}
echo "Sunucu $this->ip:$this->port adresinde dinleniyor.\n";
}
private function acceptConnections()
{
while (true) {
$readSockets = $this->getReadSockets();
usleep(1000);
$write = $except = [];
if (socket_select($readSockets, $arr, $arr1, 0) > 0) {
foreach ($readSockets as $socket) {
usleep(10000);
if ($socket === $this->masterSocket) {
$clientSocket = socket_accept($this->masterSocket);
$this->handleHandshake($clientSocket);
$this->handleNewConnection($clientSocket);
} else {
$this->handleData($socket);
}
}
}
}
}
private function getReadSockets()
{
$readSockets = [$this->masterSocket];
foreach ($this->clients as $client) {
$readSockets[] = $client;
}
return $readSockets;
}
private function handleNewConnection($clientSocket)
{
$clientId = uniqid();
$this->clients[$clientId] = $clientSocket;
echo "Yeni bağlantı kabul edildi. İstemci ID: $clientId\n";
}
private function handleData($clientSocket)
{
$data = socket_read($clientSocket, 1024);
$decodedData = $this->decodeMessage($data);
if ($decodedData === false || $decodedData === '') {
$this->disconnectClient($clientSocket);
} else {
$message = "Server Response: $decodedData";
$this->sendResponse($clientSocket, $message);
}
}
private function disconnectClient($clientSocket)
{
$clientId = array_search($clientSocket, $this->clients, true);
unset($this->clients[$clientId]);
socket_close($clientSocket);
echo "İstemci bağlantısı kapatıldı. İstemci ID: $clientId\n";
}
private function sendResponse($clientSocket, $message)
{
$encodedMessage = $this->encodeMessage($message);
socket_write($clientSocket, $encodedMessage, strlen($encodedMessage));
}
private function encodeMessage($message)
{
// Gereksinimlere uygun bir şekilde rezerve bitleri sıfırlayın
$firstByte = 0x81; // FIN biti 1, RSV1, RSV2, RSV3 bitleri 0
$length = strlen($message);
if ($length <= 125) {
$encodedData = chr($firstByte) . chr($length) . $message;
} elseif ($length <= 65535) {
$encodedData = chr($firstByte) . chr(126) . pack('n', $length) . $message;
} else {
$encodedData = chr($firstByte) . chr(127) . pack('NN', 0, $length) . $message;
}
return $encodedData;
}
private function decodeMessage($data)
{
$opcode = ord($data[0]) & 0x0F;
if ($opcode !== 0x01) {
return ''; // Sadece metin verilerini destekliyoruz, farklı bir opcode geldiyse boş bir dize döndürün.
}
$payloadLength = ord($data[1]) & 127;
if ($payloadLength === 126) {
$masks = substr($data, 4, 4);
$payload = substr($data, 8);
} elseif ($payloadLength === 127) {
$masks = substr($data, 10, 4);
$payload = substr($data, 14);
} else {
$masks = substr($data, 2, 4);
$payload = substr($data, 6);
}
$decodedData = '';
for ($i = 0; $i < strlen($payload); ++$i) {
$decodedData .= $payload[$i] ^ $masks[$i % 4];
}
return $decodedData;
}
private function handleHandshake($clientSocket)
{
$headers = [];
$lines = preg_split("/\r\n/", socket_read($clientSocket, 4096), -1, PREG_SPLIT_NO_EMPTY);
foreach ($lines as $line) {
$line = rtrim($line);
if (preg_match('/\A(\S+): (.*)\z/', $line, $matches)) {
$headers[$matches[1]] = $matches[2];
}
}
$this->sendHandshakeResponse($clientSocket, $headers);
echo "Handshake tamamlandı.\n";
}
private function sendHandshakeResponse($clientSocket, $headers)
{
$key = $headers['Sec-WebSocket-Key'];
$acceptKey = base64_encode(sha1($key . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11', true));
$response = "HTTP/1.1 101 Switching Protocols\r\n";
$response .= "Upgrade: websocket\r\n";
$response .= "Connection: Upgrade\r\n";
$response .= "Sec-WebSocket-Accept: $acceptKey\r\n\r\n";
socket_write($clientSocket, $response, strlen($response));
}
}
// Kullanım
$ip = '127.0.0.1';
$port = 8080;
$server = new SocketServer($ip, $port);
@diloabininyeri
Copy link
Author

Send a message to all sockets

  private function sendAllClients(string $message)
    {
        foreach ($this->clients as $client) {
            socket_write($client, $this->encodeMessage($message));
        }
    }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment