Created
December 28, 2023 10:10
-
-
Save diloabininyeri/1adb0889a663c131e5fcef576a7b995c to your computer and use it in GitHub Desktop.
An example of php socket server and js socket client
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!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> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Send a message to all sockets