@danchikraw
Веб-додик

Как связать js и php веб сокеты?

Решил написать свой сервер на php для обработки websocket, узнал что нужно в ответ отсылать заголовок "рукопожатия". Так вот, когда я не отслыю заголовок то клиент подключаеться и ждёт, а когда отсылаю обратно то сразу закрываеться соединение и я получаюи сообщение: Connect close!
let socket = new WebSocket("ws://chat:8000/server.php");
socket.onopen = function () {
    message("<div>Connect!</div>")
}

socket.onerror = function () {
    message("<div>Connect error!</div>")
}

socket.onclose = function () {
    message("<div>Connect close!</div>")
}

socket.onmessage = function (e) {
    let data = JSON.parse(e.data);
    message("<div>" + data.type + " - " + data.message + "</div>>")
}

setInterval(function () {
    // console.log(socket.readyState)
})

function message(str) {
    let block = document.querySelector('.chat-result');

    block.insertAdjacentHTML('beforeend', str);
}

<?php
error_reporting(E_ALL);

/* Позволяет скрипту ожидать соединения бесконечно. */
set_time_limit(0);

/* Включает скрытое очищение вывода так, что мы видим данные
 * как только они появляются. */
ob_implicit_flush();

$address = '127.0.0.1';
$port = 8000;

if (($sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) === false) {
    echo "Не удалось выполнить socket_create(): причина: " . socket_strerror(socket_last_error()) . "\n";
}

if (socket_bind($sock, $address, $port) === false) {
    echo "Не удалось выполнить socket_bind(): причина: " . socket_strerror(socket_last_error($sock)) . "\n";
}

if (socket_listen($sock, 5) === false) {
    echo "Не удалось выполнить socket_listen(): причина: " . socket_strerror(socket_last_error($sock)) . "\n";
}

do {
    if (($newSock = socket_accept($sock)) === false) {
        echo "Не удалось выполнить socket_accept(): причина: " . socket_strerror(socket_last_error($sock)) . "\n";
        break;
    }
    handshake($newSock);

} while (true);

socket_close($sock);

function handshake($newSock) {

    $header = socket_read($newSock, 1024);

    if (preg_match('/Sec-WebSocket-Key: (.*)/', $header, $match)) {
//        echo 'ok';
        $SecWebSocketAccept = base64_encode(pack('H*', sha1($match[1] . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11')));
        $in_header = "HTTP/1.1 101 Web Socket Protocol Handshake\r\n" .
            "Upgrade: websocket\r\n" .
            "Connection: Upgrade\r\n" .
            "Sec-WebSocket-Accept:".$SecWebSocketAccept."\r\n\r\n";
        var_dump($in_header);
// Когда эта функция не выполнеяеться соединение висит не не отключаеться, а после её выполнения закрываеться сразу.
        socket_write($newSock, $in_header);
    }
}
  • Вопрос задан
  • 603 просмотра
Решения вопроса 1
sergiks
@sergiks Куратор тега PHP
♬♬
Хотя и можно найти или написать реализацию WS handshake на чистом PHP. Но далее продолжатся неудобства: для работы в (почти) реальном времени придется писать бесконечный цикл, в итерации которого проверять, есть ли новости в сокете. Будет работать, но костыльно и неэффективно.

Удобнее, например, добавить PHP модуль Swoole, который реализует полноценный WebSocket сервер, и заняться уже обработкой сообщений на высоком уровне — логикой вашего приложения.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы