javascript - 为什么我的 websocket php+javascript 代码不起作用?
问题描述
我在互联网上找到了一些脚本。我试图配置它,但它对我不起作用。我添加了它,我对websocket功能不太了解,所以请帮助我,如果可以的话!当我尝试向服务器发送消息时,总是得到相同的错误代码:
“InvalidStateError:无法在 'WebSocket' 上执行 'send':仍处于 CONNECTING 状态。”
该脚本不会产生包含此评论的 else :
// 与服务器连接的客户端将进入这种情况
// 第一个客户端将与服务器握手,然后与服务器交换数据
我不知道为什么,但我真的很想了解这些东西。可以帮我一个人吗?(握手是好的。如果不是好的,我会得到一个javascript错误。)
<?php
error_reporting(E_ALL);
set_time_limit(0);
ob_implicit_flush();
$address = "127.0.0.1";
$port = "1234";
GLOBAL $clients;
GLOBAL $client_list;
// socket creation
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_set_option($socket, SOL_SOCKET, SO_REUSEADDR, 1);
if (!is_resource($socket))
console("socket_create() failed: ".socket_strerror(socket_last_error()), true);
if (!socket_bind($socket, $address, $port))
console("socket_bind() failed: ".socket_strerror(socket_last_error()), true);
if(!socket_listen($socket, 20))
console("socket_listen() failed: ".socket_strerror(socket_last_error()), true);
console("Server started on $address : $port\n\n");
$master = $socket;
$sockets = array($socket);
$counert = 0;
while(true) {
$changed = $sockets;
foreach($changed as $socket) {
if($socket == $master) {
$log = "Egyenlők!";
} else {
$log = "Nem egyenlők!";
}
//console($log);
if($socket == $master) {
// new client will enter in this case and connect with server
socket_select($changed,$write=NULL,$except=NULL,NULL);
console("Master Socket Changed.\n\n");
$client = socket_accept($master);
if($client < 0) {
console("socket_accept() failed\n\n");
continue;
} else {
console("Connecting socket.\n\n");
fnConnectacceptedSocket($socket,$client); $master=null;
}
} else {
// clients who are connected with server will enter into this case
// first client will handshake with server and then exchange data with server
$client = getClientBySocket($socket);
if($client) {
if ($clients[$socket]["handshake"] == false) {
$bytes = @socket_recv($client, $data, 2048, MSG_DONTWAIT);
if ((int)$bytes == 0)
continue;
console("Handshaking headers from client:".$data);
if (handshake($client, $data, $socket))
$clients[$socket]["handshake"] = true;
} else if ($clients[$socket]["handshake"] == true) {
$bytes = @socket_recv($client, $data, 2048, MSG_DONTWAIT);
if ($data != "") {
$decoded_data = unmask($data);
socket_write($client, encode("You have entered: ".$decoded_data));
console("Data from client:".$decoded_data);
socket_close($socket);
}
}
}
}
}
}
# Close the master sockets
socket_close($socket);
function unmask($payload) {
$length = ord($payload[1]) & 127;
if($length == 126) {
$masks = substr($payload, 4, 4);
$data = substr($payload, 8);
}
elseif($length == 127) {
$masks = substr($payload, 10, 4);
$data = substr($payload, 14);
}
else {
$masks = substr($payload, 2, 4);
$data = substr($payload, 6);
}
$text = '';
for ($i = 0; $i < strlen($data); ++$i) {
$text .= $data[$i] ^ $masks[$i%4];
}
return $text;
}
function encode($text) {
// 0x1 text frame (FIN + opcode)
$b1 = 0x80 | (0x1 & 0x0f);
$length = strlen($text);
if($length <= 125)
$header = pack('CC', $b1, $length);
elseif($length > 125 && $length < 65536)
$header = pack('CCS', $b1, 126, $length);
elseif($length >= 65536)
$header = pack('CCN', $b1, 127, $length);
return $header.$text;
}
function fnConnectacceptedSocket($socket, $client) {
GLOBAL $clients;
GLOBAL $client_list;
$clients[$socket]["id"] = uniqid();
$clients[$socket]["socket"] = $socket;
$clients[$socket]["handshake"] = false;
console("Accepted client \n\n");
$client_list[$socket] = $client;
}
function getClientBySocket($socket) {
GLOBAL $client_list;
return $client_list[$socket];
}
function handshake($client, $headers, $socket) {
if(preg_match("/Sec-WebSocket-Version: (.*)\r\n/", $headers, $match))
$version = $match[1];
else {
console("The client doesn't support WebSocket");
return false;
}
if($version == 13) {
// Extract header variables
if(preg_match("/GET (.*) HTTP/", $headers, $match))
$root = $match[1];
if(preg_match("/Host: (.*)\r\n/", $headers, $match))
$host = $match[1];
if(preg_match("/Origin: (.*)\r\n/", $headers, $match))
$origin = $match[1];
if(preg_match("/Sec-WebSocket-Key: (.*)\r\n/", $headers, $match))
$key = $match[1];
$acceptKey = $key.'258EAFA5-E914-47DA-95CA-C5AB0DC85B11';
$acceptKey = base64_encode(sha1($acceptKey, true));
$upgrade = "HTTP/1.1 101 Switching Protocols\r\n".
"Upgrade: websocket\r\n".
"Connection: Upgrade\r\n".
"Sec-WebSocket-Accept: $acceptKey".
"\r\n\r\n";
socket_write($client, $upgrade);
return true;
}
else {
console("WebSocket version 13 required (the client supports version {$version})");
return false;
}
}
function console($text) {
$text = $text . "\r\n";
$File = "log.txt";
$Handle = fopen($File, 'a');
fwrite($Handle, $text);
fclose($Handle);
}
?>
这是javascript代码:
<script>
var socket;
var host = "ws://localhost:1234/chat/server.php";
function init() {
try {
socket = new WebSocket(host);
//log('WebSocket - status '+socket.readyState);
socket.onopen = function(msg){ socket.send("asdf"); log("Welcome - status "+this.readyState); };
socket.onmessage = function(msg){ log("Received: "+msg.data); };
socket.onclose = function(msg){ log("Disconnected - status "+this.readyState); };
}
catch(ex){ log(ex); }
$("msg").focus();
}
function send() {
var txt,msg;
txt = $("msg");
msg = txt.value;
if(!msg){ alert("Message can not be empty"); return; }
txt.value="";
txt.focus();
try{ socket.send(msg); log('Sent: '+msg); } catch(ex){ log(ex); }
}
function quit(){
log("Goodbye!");
socket.close();
socket=null;
}
// Utilities
function $(id){ return document.getElementById(id); }
function log(msg){ $("log").innerHTML+="\n"+msg; }
function onkey(event){ if(event.keyCode==13){ send(); } }
</script>
解决方案
您是如何准确运行 PHP 代码的?我对其进行了测试,至少这里发生了一些事情:)。我不确定使用 PHP 来实现 websocket 服务器是否可行!
推荐阅读
- excel - Excel VBA根据单元格值停止msgbox显示循环
- javascript - 无法在反应中存储到localStorage
- python - 在 manim 中,如何将轴标签的文本设置为与轴单位不同?
- php - 目标类 [Database\Seeders\UsersTableSeeder] 不存在
- django - 模型字段类型从 CharField 更改为 ForeignKey 时 Django 模板损坏
- python - 使用 `requests` 和 `MultipartEncoder` 发布是否可能导致传输错误或部分上传?
- reactjs - React - 我必须点击一个按钮三次才能生效
- nativescript - 如何在不“重写”的情况下扩展 NativeScript 插件?
- .net - PlayWright-Sharp 的好的 PageObject 示例似乎不存在
- mosquitto - 在 mosquitto 中限制客户端的消息