Я делаю чат на сайте, и для этого у меня есть сервер или дежурный скрипт, который принимает сообщения и отправляет сообщения клиенту.
Сайт размещён на 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), но чат работал. В связи с этим я предполагаю, что здесь просто где-то неправильно прописан путь.
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
знатакиЕсть проблема с сайтами, два сайта в одному выходит, один основной и второй залит в папку в нём же, но проблема состоит в том, что htaccess...
В программе была найдена причина Segmentation Fault при освобождении памяти (в деструкторе вектора)Как оказалось, происходило смещение begin-итератора...
Как реализовать простой GET/POST запрос без использования сторонних библиотек?