Hallo Leute,
ich komme gerade nicht so wirklich weiter. Ich möchte mehrere Clients verbinden könnten auf einen ServerSocket. Das funktioniert soweit prinzipiell auch. Nur weiß ich ja, dass es in PHP Schwierigkeiten mit Threads gibt (sollte man nicht unter einem Webserver betreiben, warum auch immer).
Normalerweise, so kenne ich das aus C# / Java, würde ich an der Stelle einen Thread pro Connection erstellen. Das Accept kann dann ruhig weiterhin blockieren, solange bis neue Connection kommen.
Bisher habe ich folgendes:
Klasse SimpleServer:
Aufruf der Klasse (Konsole Skript bisher):
Der Client:
Mir fehlt die Parallelität im SimpleServer::accept(). Außerdem kann ich so aktuell den Server nicht stoppen (es kommt nie zu den boolschen Flag). Wenn ich also Threads vermeiden will, dann bräuchte ich etwas nicht blockierendes. Aber auf der anderen Seite soll es doch wieder blockieren, bis eine neue Connection kommt. Also irgendwie zweischneidig. Am Rande sei noch erwähnt, dass das ganze auf Linux laufen wird. Also die pctnl Zeug müsste auch gehen.
MFG
derwunner
ich komme gerade nicht so wirklich weiter. Ich möchte mehrere Clients verbinden könnten auf einen ServerSocket. Das funktioniert soweit prinzipiell auch. Nur weiß ich ja, dass es in PHP Schwierigkeiten mit Threads gibt (sollte man nicht unter einem Webserver betreiben, warum auch immer).
Normalerweise, so kenne ich das aus C# / Java, würde ich an der Stelle einen Thread pro Connection erstellen. Das Accept kann dann ruhig weiterhin blockieren, solange bis neue Connection kommen.
Bisher habe ich folgendes:
Klasse SimpleServer:
PHP-Code:
namespace Server;
class SimpleServer
{
protected $serverSocket;
protected $serverSocketsChange;
protected $host;
protected $port;
protected $clients;
protected $run;
const WS_VERSION = 13;
public function __construct($host, $port)
{
$this->host = $host;
$this->port = $port;
// Socket erstellen
$this->serverSocket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_set_option($this->serverSocket, SOL_SOCKET, SO_REUSEADDR, 1);
$this->clients = array();
}
public function bind()
{
// Socket an Adresse und Port binden
socket_bind($this->serverSocket, $this->host, $this->port);
}
public function listen()
{
// An Port lauschen
socket_listen($this->serverSocket);
}
public function accept()
{
$this->run = true;
while ($this->run) {
echo 'Warte auf Verbindung...' . \PHP_EOL;
$client = socket_accept($this->serverSocket);
echo 'Verbindung angenommen.' . \PHP_EOL;
$this->sendHeaders($client);
for ($i = 0; $i < 3; $i++) {
$this->multicast('hi from server', $client);
sleep(2);
}
$this->clients[] = $client;
}
$this->disconect();
}
public function multicast($msg, $client = null)
{
if ($client !== null) {
$response = chr(129).chr(\mb_strlen($msg)) . $msg;
socket_write($client, $response);
} else {
foreach ($this->clients as $client) {
$response = chr(129).chr(\mb_strlen($msg)) . $msg;
socket_write($client, $response);
}
}
}
public function stop()
{
$this->run = false;
}
public function disconect()
{
foreach ($this->clients as $client) {
socket_close($client);
}
}
private function sendHeaders($client)
{
$request = socket_read($client, 5000);
preg_match('#Sec-WebSocket-Key: (.*)\r\n#', $request, $matches);
$key = base64_encode(pack(
'H*',
sha1($matches[1] . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11')
));
$headers = "HTTP/1.1 101 Switching Protocols\r\n";
$headers .= "Upgrade: websocket\r\n";
$headers .= "Connection: Upgrade\r\n";
$headers .= 'Sec-WebSocket-Version: ' . self::WS_VERSION . "\r\n";
$headers .= 'Sec-WebSocket-Accept: ' . $key . "\r\n\r\n";
socket_write($client, $headers, \mb_strlen($headers));
}
}
PHP-Code:
require 'vendor/autoload.php';
use Server\SimpleServer;
$server = new SimpleServer('127.0.0.1', 8090);
$server->bind();
$server->listen();
$server->accept();
$server->stop();
HTML-Code:
<!DOCTYPE html> <html lang="de"> <head> <title>Websocket Test</title> </head> <body> <h1>Chatbox</h1> <div id="chat"></div> <script type="text/javascript" src="//code.jquery.com/jquery-3.3.1.min.js"></script> <script type="text/javascript"> var con = new WebSocket('ws://127.0.0.1:8090'); var $chat = $('#chat'); con.onmessage = function(e) { $chat.append('<p>' + e.data + '</p>'); }; con.onopen = function(e) { con.send('Hello Me!'); }; con.onclose = function (e) { console.log('connection closed.', arguments); } </script> </body> </html>
MFG
derwunner
Kommentar