Как правильно прописать путь к серверу для отправки сокета

152
11 декабря 2019, 02:50

Я делаю чат на сайте, и для этого у меня есть сервер или дежурный скрипт, который принимает сообщения и отправляет сообщения клиенту.

Сайт размещён на VDS-сервере. в Cron'е сервера добавлена задача:

php /home/admin/web/cy84161.tw1.ru/public_html/messages/server.php

Первоначально на клиенте я создаю сокет:

var socket = new WebSocket("ws://cy84161.tw1.ru:8070/messages/server.php");

Но при этом сокет выдаёт ошибку, связанную с отсутствием соединения. Подскажите, как правильно прописать путь до дежурного файла при создании сокета, и что здесь не так. Ниже приведу полностью тексты скриптов, ответственных за обмен сообщениями.

chat.js

function message(text) {
    var a = $('#chat-result');
    a.append(text);
    a.animate({scrollTop: a.prop("scrollHeight")},'slow');
}
function writeMessage(message) {
    //Сохранение сообщений в БД, здесь всё работает без ошибок
    var http = false;
    if(navigator.appName == "Microsoft Internet Explorer") http = new ActiveXObject("Microsoft.XMLHTTP");
    else http = new XMLHttpRequest();
    http.abort();
    http.open("POST", "talking_write.php", true);
    http.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    http.send(
        "sender=" + message.chat_sender +
        "&message=" + message.chat_message);
}
jQuery(document).ready(function($) {
    var socket = new WebSocket("ws://cy84161.tw1.ru:8070/messages/server.php");
    socket.onopen = function() {
        message("<div>Соединение установлено</div>");
    };
    socket.onerror = function(error) {
        message("<div>Ошибка при соединении" + (error.message ? error.message : "") + "</div>");
    };
    socket.onclose = function() {
        message("<div>Соединение закрыто</div>")
    };
    socket.onmessage = function(event) {
        var data = JSON.parse(event.data);
        switch (data.type) {
            case "connected":
                message('<div>Присоединение с IP-адреса: ' + data.message + '</div>');
                break;
            case "disconnected":
                message('<div>Отсоединение IP-адреса: ' + data.message + '</div>');
                break;
            case "chat-box":
                message('<div><span style = "color: red">' + data.sender + ': </span>' + data.message + '</div>');
                break;
        }
    };
    $("#chat").on('submit', function() {
        var message = {
            chat_sender: $("#chat-sender").val(),
            chat_message: $("#chat-message").val(),
        };
        writeMessage(message);
        socket.send(JSON.stringify(message));
        return false;
    });
});

server.php

<?php
    require_once("chat.php");
    define("PORT", "8070");
    $chat = new Chat();
    $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
    socket_set_option($socket, SOL_SOCKET, SO_REUSEADDR, 1);
    socket_bind($socket, 0, PORT);
    socket_listen($socket);
    $clentSocketarray = array($socket);
    while(true) {
        $newSocketArray = $clentSocketarray;
        $nullA = array();
        socket_select($newSocketArray, $nullA, $nullA, 0, 10);
        if(in_array($socket, $newSocketArray)) {
            $newSocket = socket_accept($socket);
            $clentSocketarray[] = $newSocket;
            $header = socket_read($newSocket, 1024);
            $chat->sendHeaders($header, $newSocket, "EOPMS/messages", PORT);
            socket_getpeername($newSocket, $client_ip_address);
            $connectionACK = $chat->newConnectionACK($client_ip_address);
            $chat->send($connectionACK, $clentSocketarray);
            $newSocketArrayIndex = array_search($socket, $newSocketArray);
            unset($newSocketArray[$newSocketArrayIndex]);
        }
        foreach($newSocketArray as $newSocketArrayResource) {
            //1
            while(socket_recv($newSocketArrayResource, $socketData, 1024, 0) >= 1) {
                $socketMessage = $chat->unseal($socketData);
                $messageObj = json_decode($socketMessage);
                if ($messageObj->chat_sender != null) {
                    $chatMessage = $chat->createChatMessage($messageObj->chat_sender, $messageObj->chat_message);
                    $chat->send($chatMessage, $clentSocketarray);
                }
                break 2;
            }
            ///2
            $socketData = @socket_read($newSocketArrayResource, 1024, PHP_NORMAL_READ);
            if ($socketData === false) {
                socket_getpeername($newSocketArrayResource, $client_ip_address);
                $connectionACK = $chat->newDisconnectedACK($client_ip_address);
                $chat->send($connectionACK, $clentSocketarray);
                $newSocketArrayIndex = array_search($newSocketArrayResource, $clentSocketarray);
                unset($clentSocketarray[$newSocketArrayIndex]);
            }
        }
    }
    socket_close($socket);
?>

chat.php

<?php
    class Chat
    {
        public function sendHeaders($headersText, $newSocket, $host, $port) {
            $headers = array();
            $tmpLine = preg_split("/\r\n/", $headersText);
            foreach($tmpLine as $line) {
                $line = rtrim($line);
                if(preg_match("/\A(\S+): (.*)\z/", $line, $matches)) {
                    $headers[$matches[1]] = $matches[2];
                }
            }
            $key = $headers["Sec-WebSocket-Key"];
            $sKey = base64_encode(pack("H*", sha1($key."258EAFA5-E914-47DA-95CA-C5AB0DC85B11")));
            $strHeader = "HTTP/1.1 101 Switching Protocols \r\n".
                "Upgrade: websocket\r\n".
                "Connection: Upgrade\r\n".
                "WebSocket-Origin: $host\r\n".
                "WebSocket-Location: ws://$host:$port/messages/server.php\r\n".
                "Sec-WebSocket-Accept: $sKey\r\n\r\n";
            socket_write($newSocket, $strHeader, strlen($strHeader));
        }
        public function seal($socketData) {
            $b1 = 0x81;
            $length = strlen($socketData);
            $header = "";
            if ($length <= 125) {
                $header = pack("CC", $b1, $length);
            } elseif ($length > 125 && $length < 65536) {
                $header = pack("CCn", $b1, 126, $length);
            } elseif ($length > 65536) {
                $header = pack("CCNN", $b1, 127, $length);
            }
            return $header.$socketData;
        }
        public function unseal($socketData) {
            $length = ord($socketData[1]) & 127;
            if ($length == 126) {
                $mask = substr($socketData, 4, 4);
                $data = substr($socketData, 8);
            } elseif ($length == 127) {
                $mask = substr($socketData, 10, 4);
                $data = substr($socketData, 14);
            } else {
                $mask = substr($socketData, 2, 4);
                $data = substr($socketData, 6);
            }
            $socketStr = "";
            for ($i = 0; $i < strlen($data); ++$i) {
                $socketStr .= $data[$i] ^ $mask[$i%4];
            }
            return $socketStr;
        }
        public function send($message, $clentSocketArray) {
            $messageLength = strlen($message);
            foreach ($clentSocketArray as $clentSocket) {
                @socket_write($clentSocket, $message, $messageLength);
            }
            return true;
        }
        public function createChatMessage($sender, $messageStr) {
            $messageArray = array('type' => "chat-box", 'sender' => $sender, 'message' => $messageStr);
            return $this->seal(json_encode($messageArray));
        }
        public function newConnectionACK($client_ip_address) {
            $messageArray = array("type" => "connected", "message" => $client_ip_address);
            return $this->seal(json_encode($messageArray));
        }
        public function newDisconnectedACK($client_ip_address) {
            $messageArray = array("type" => "disconnected", "message" => $client_ip_address);
            return $this->seal(json_encode($messageArray));
        }
    }
?>

P.S. На вирутальном хостинге, хотя дежурный скрипт принудительно закрывался (почему я и перешёл на VDS), но чат работал. В связи с этим я предполагаю, что здесь просто где-то неправильно прописан путь.

READ ALSO
htaccess в двух сайтах

htaccess в двух сайтах

знатакиЕсть проблема с сайтами, два сайта в одному выходит, один основной и второй залит в папку в нём же, но проблема состоит в том, что htaccess...

146
SIGSEGV в дестукторе вектора при некорректном смещении итератора

SIGSEGV в дестукторе вектора при некорректном смещении итератора

В программе была найдена причина Segmentation Fault при освобождении памяти (в деструкторе вектора)Как оказалось, происходило смещение begin-итератора...

155
Отправка GET/POST-запроса средствами чистого C++

Отправка GET/POST-запроса средствами чистого C++

Как реализовать простой GET/POST запрос без использования сторонних библиотек?

123
Как сделать текст курсивным в Qt

Как сделать текст курсивным в Qt

В продолжении вопроса

152