Как сервер сокетов PHP принимает соединение и обмен данными с несколькими клиентами (Android)

#php #sockets #socketserver

#php #сокеты #socketserver

Вопрос:

У меня есть сервер сокетов PHP, которому необходимо взаимодействовать с несколькими клиентами. Я знаю if(socket_listen($sock, 5) , что прослушивает 5 клиентов. Но когда я пытаюсь подключить 2-е устройство, оно не подключается, это похоже на соединение с первым устройством, блокирующим другое соединение.

У меня также возникает проблема, когда сервер и клиент обмениваются данными, и по какой-то причине соединение закрывается, тогда, если я попытаюсь снова подключить то же устройство или другое, оно не будет работать. Затем мне нужно перезапустить сервер, чтобы он мог снова принимать соединения.

 <?php
require "init.php";
$sql = "SELECT * FROM `info` where sent = 0 order by id desc";

error_reporting(E_ALL);

/* Allow the script to hang around waiting for connections. */
set_time_limit(0);

/* Turn on implicit output flushing so we see what we're getting
 * as it comes in. */
ob_implicit_flush();

$address = '192.168.50.30';
$port = 3005;
if(($sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) === false) {
    echo "socket_create() failed: reason: " . socket_strerror(socket_last_error()) . "n";
}

if(socket_bind($sock, $address, $port) === false) {
    echo "socket_bind() failed: reason: " . socket_strerror(socket_last_error($sock)) . "n";
}

if(socket_listen($sock, 5) === false) {
    echo "socket_listen() failed: reason: " . socket_strerror(socket_last_error($sock)) . "n";
}

do {
    if (($msgsock = socket_accept($sock)) === false) {
        echo "socket_accept() failed: reason: " . socket_strerror(socket_last_error($sock)) . "n";
        break;
    }
    /* Send Welcome. */
    $msg = "HELLO".chr(0);
    socket_write($msgsock, utf8_encode ($msg), strlen($msg));


    do {

        $result = $con->query($sql);
        $row = $result->fetch_assoc();

        if(!empty($row["Token"])){
            $msg = $row["Token"]. chr(0);

            socket_write($msgsock, utf8_encode($msg), strlen($msg));
            $result = $con->query("update info set sent = 1 where id = ".$row["id"]);
        }


//        $talkback = $_SERVER['REMOTE_ADDR']." Said: '$buf'.n".chr(0);
//        socket_write($msgsock, $talkback, strlen($talkback));
    } while (true);
    socket_close($msgsock);
} while (true);

socket_close($sock);
?>
  

Комментарии:

1. PHP является однопоточным, поэтому вы не можете обслуживать несколько сокетов одновременно. Вы можете попробовать что-то с помощью select или fork . Но вам следует серьезно подумать о том, чтобы сделать это на другом языке, который поддерживает параллелизм. PHP действительно разработан вокруг циклов запроса / ответа, а не долго работающих серверов. Если все, что вы делаете, это помещаете значения базы данных в TCP-соединение, у вас есть много и много вариантов.

2. @Peter Вы говорите мне, что мне нужно создать сервер с другим языком программирования, чтобы я мог обслуживать несколько сокетов? У вас есть какие-либо предложения или какой-нибудь пример исходного кода демо-версии сервера. На данный момент я знаю только PHP и немного Java.

3. Вы можете взглянуть на reactphp, это может решить вашу проблему

4. Нет, вам не нужно использовать другой язык. Я просто говорю, что PHP не очень подходит для этой задачи. В моем предыдущем комментарии я предложил два способа заставить его работать на PHP. Reactphp — еще один, хотя, насколько я помню, запросы к базе данных все равно будут блокироваться.