时间:2021-07-01 10:21:17 帮助过:48人阅读
而在 ie 和 chrome 下却触发不了 onmessage 事件,
1.首先 send()发送信息到服务端
2.socket__select 获得套接字 A , socket__read 取得信息
3.再将同样的信息用 socket__write 返回给套接字 A ,之后再监听套接字 A ,在火狐下这样就会结束
但是在 ie 下 socket__select 会再次获得套接字 A ,接着重复取得以及返回信息最后监听套接字 A 。 当然还没完, socket__select 还会获得套接字 A ,在经历前两次的 read 和 write 后,这次 socket__read 取得的信息会是空值。
顺便一提,在 ie 下服务端第一次执行 socket__write 的返回值是 int(10),这是正常的,而第二次执行 write 会返回 int(32),因为是在 cmd 下运行 php 文件的, socket__read 取得的信息显示为乱码(握手协议倒是显示正常),所以我不知道第二次 socket__write 返回的信息是什么。
为什么会这样?明明握手都可以成功来着, onopen 事件已经触发了,为什么到 onmessage 的时候就出现问题!
如果单凭以上的信息无法找到问题的话,下面是我的代码:
html:
test
php:
$master=socket_create(AF_INET,SOCK_STREAM,SOL_TCP);
socket_set_option($master,SOL_SOCKET,SO_REUSEADDR,1);
socket_bind($master,"localhost",1199);
socket_listen($master,5);
$sockets[]=$master;$w=NULL;$r=NULL;
for($i=0;;$i++){
$sockets_copy=$sockets;echo"select_bf: ";var_dump($sockets_copy);echo"\n";
socket_select($sockets_copy,$r,$w,NULL);
foreach($sockets_copy as $socket){
if($socket==$master){echo"true\n";$client=socket_accept($socket);array_push($sockets,$client);}
else{echo"false: ";var_dump($socket);echo"\n";
$buffer=socket_read($socket,1024);echo"buffer:".$buffer."\n";
if($buffer==""){echo"true_1\n";sort($sockets);$num=array_keys($sockets,$socket);array_splice($sockets,$num[0],1);socket_close($socket);}
else{echo"false_1\n";
if(preg_match("/(?<=Sec-WebSocket-Key:).*/",$buffer,$match)){
echo"true_2\n";
$str="HTTP/1.1 101 Switching Protocols\r\n"."Upgrade: websocket\r\n"."Connection: Upgrade\r\n"."Sec-WebSocket-Accept: ".base64_encode(sha1(trim($match[0]).'258EAFA5-E914-47DA-95CA-C5AB0DC85B11',true))."\r\n\r\n";
echo"str:".$str."\n";socket_write($socket,$str);
}
else{echo"false_2: ";$s_w=socket_write($socket,$buffer);var_dump($s_w);echo"\n";}
}
}
}
}
?>
我用 php 写了个 socket 服务端,然后在火狐运行客户端握手成功后,
1.用 send()函数发送信息给服务端
2.服务端 socket__read 提取信息
3.再用 socket__write 返回信息可以触发客户端的 onmessage 事件。
而在 ie 和 chrome 下却触发不了 onmessage 事件,
1.首先 send()发送信息到服务端
2.socket__select 获得套接字 A , socket__read 取得信息
3.再将同样的信息用 socket__write 返回给套接字 A ,之后再监听套接字 A ,在火狐下这样就会结束
但是在 ie 下 socket__select 会再次获得套接字 A ,接着重复取得以及返回信息最后监听套接字 A 。 当然还没完, socket__select 还会获得套接字 A ,在经历前两次的 read 和 write 后,这次 socket__read 取得的信息会是空值。
顺便一提,在 ie 下服务端第一次执行 socket__write 的返回值是 int(10),这是正常的,而第二次执行 write 会返回 int(32),因为是在 cmd 下运行 php 文件的, socket__read 取得的信息显示为乱码(握手协议倒是显示正常),所以我不知道第二次 socket__write 返回的信息是什么。
为什么会这样?明明握手都可以成功来着, onopen 事件已经触发了,为什么到 onmessage 的时候就出现问题!
如果单凭以上的信息无法找到问题的话,下面是我的代码:
html:
test
php:
$master=socket_create(AF_INET,SOCK_STREAM,SOL_TCP);
socket_set_option($master,SOL_SOCKET,SO_REUSEADDR,1);
socket_bind($master,"localhost",1199);
socket_listen($master,5);
$sockets[]=$master;$w=NULL;$r=NULL;
for($i=0;;$i++){
$sockets_copy=$sockets;echo"select_bf: ";var_dump($sockets_copy);echo"\n";
socket_select($sockets_copy,$r,$w,NULL);
foreach($sockets_copy as $socket){
if($socket==$master){echo"true\n";$client=socket_accept($socket);array_push($sockets,$client);}
else{echo"false: ";var_dump($socket);echo"\n";
$buffer=socket_read($socket,1024);echo"buffer:".$buffer."\n";
if($buffer==""){echo"true_1\n";sort($sockets);$num=array_keys($sockets,$socket);array_splice($sockets,$num[0],1);socket_close($socket);}
else{echo"false_1\n";
if(preg_match("/(?<=Sec-WebSocket-Key:).*/",$buffer,$match)){
echo"true_2\n";
$str="HTTP/1.1 101 Switching Protocols\r\n"."Upgrade: websocket\r\n"."Connection: Upgrade\r\n"."Sec-WebSocket-Accept: ".base64_encode(sha1(trim($match[0]).'258EAFA5-E914-47DA-95CA-C5AB0DC85B11',true))."\r\n\r\n";
echo"str:".$str."\n";socket_write($socket,$str);
}
else{echo"false_2: ";$s_w=socket_write($socket,$buffer);var_dump($s_w);echo"\n";}
}
}
}
}
?>
参考:https://segmentfault.com/q/1010000004859...