I want to create a TCP socket using PHP code that can handle a large number of clients. In fact, my clients are network modules that want to connect to the server and have a two-way connection.
I have a few goals in mind:
Display a list of connected clients. Ability to send messages to a specific client through an HTML page. Ability to connect multiple clients simultaneously (in this case, I mean 10). I have a shared host, and I run all the server code on it. This host doesn't provide console access, so I have no idea how to use ready-made libraries like ReactPHP.
Currently, I have only managed to create a list of connected clients. Here is the code for that:
<?php
error_reporting(E_ALL);
$host = '0.0.0.0';
$port = 8085;
$clients = [];
$onlineUsersFile = 'online_users.json';
$server = stream_socket_server("tcp://$host:$port", $errno, $errstr);
if (!$server) {
die("Error: $errstr ($errno)\n");
}
echo "Server started on $host:$port\n";
while (true) {
$read = $clients;
$read[] = $server;
if (!stream_select($read, $write, $except, 1)) {
// Check every 1 second for changes in connections
continue;
}
if (in_array($server, $read)) {
$newClient = stream_socket_accept($server);
socket_set_blocking($newClient, 0);
$clients[] = $newClient;
$data = "Welcome to the chat room!\n";
stream_socket_sendto($newClient, $data);
echo "New client connected\n";
broadcastToAll($clients, "New client connected\n");
$key = array_search($server, $read);
unset($read[$key]);
}
foreach ($read as $key => $client) {
stream_set_timeout($client, 1);
$data = fread($client, 1024);
if ($data === false || feof($client)) {
fclose($client);
unset($clients[$key]);
echo "Client disconnected\n";
broadcastToAll($clients, "Client disconnected\n");
continue;
}
if ($data != '') {
broadcast($client, $data, $clients);
}
}
updateOnlineUsers($clients, $onlineUsersFile);
}
function broadcast($sender, $message, $clients)
{
foreach ($clients as $client) {
if ($client !== $sender) {
stream_socket_sendto($client, $message);
}
}
}
function broadcastToAll($clients, $message)
{
foreach ($clients as $client) {
stream_socket_sendto($client, $message);
}
}
function updateOnlineUsers($clients, $file)
{
$onlineUsers = [];
foreach ($clients as $client) {
$address = stream_socket_get_name($client, true);
$onlineUsers[] = $address;
}
file_put_contents($file, json_encode($onlineUsers));
}
$onlineUsers[] = $address;
}
file_put_contents($file, json_encode($onlineUsers));
}
Ability to send messages to a specific client through an HTML page.