나는 websocket을 처음 사용했습니다. PHP에서 간단한 websocket 구현을 만들었습니다. 내 서버가 클라이언트로부터 메시지를받을 수 있기 때문에 핸드 셰이 킹이 제대로 작동하고 연결이 확실히 켜져 있습니다.WebSocket : 클라이언트가 서버에 응답하지 않습니다
그러나 일단 클라이언트에 메시지를 보내려고하면 클라이언트는 전혀 응답하지 않습니다.
다음은 메시지를 마스크하여 클라이언트로 다시 보내는 코드입니다.
function myProcess($user,$buffer)
{
//$buffer=unwrap($buffer);
console("Request Caught.");
console("Content Length: ".strlen($buffer));
console("Content: ".unmask($buffer));
console("First 8 bits: ".ord($buffer[0]));
console("Opcode: ".opcode($buffer,true));
//console("Full Text: ".$buffer);
//socket_write($user->socket,mask(unmask($buffer)));
console("Masking: ");
$tmp=unmask($buffer);
console($tmp);
$masked=mask($tmp);
opcode($masked);
for($i=0;$i<strlen($masked);$i++)
{
console($i.": ".ord($masked[$i]));
}
console("length: ".strlen($masked));
console("Sending Response: ");
console(socket_write($user->socket,$masked,strlen($masked)));
}
function mask($text)
{
$first8bit=0x81;
$header;
console("mask: payload length:".strlen($text));
if(strlen($text)<=125)
{
$header=pack("CC",$first8bit,strlen($text));
}
else if(strlen($text)<65536)
{
$header=pack("CCS",$first8bit,126,strlen($text));
}
else
{
$header=pack("CCN",$first8bit,127,strlen($text));
}
return $header.$text;
}
클라이언트가 서버에 "hi"를 보내면 서버는 단순히 "hi"로 응답합니다. 그리고 wireshark를 가진 캡쳐 된 패킷은 81 02 68 69입니다. 프로토콜상의 것과 같이 전선의 비트가있는 것처럼 보입니다. 서버가 "hi from server"와 같이 더 긴 문자열을 보내려고하면 클라이언트 응답에 undefined가 표시됩니다.
아무도 도와 줄 수 있습니까? 고마워.
이function dohandshake($user,$buffer){
console("\nRequesting handshake...");
console($buffer);
list($resource,$host,$origin,$strkey,$data) = getheaders($buffer);
console("Handshaking...");
$upgrade="HTTP/1.1 101 Switching Protocols\r\n".
"Upgrade: websocket\r\n".
"Connection: Upgrade\r\n".
"Sec-WebSocket-Accept: ".calc_accept($strkey)."\r\n\r\n";
socket_write($user->socket,$upgrade.chr(0),strlen($upgrade.chr(0)));
$user->handshake=true;
console($upgrade);
console("Done handshaking...");
return true;
}
이 두 기능은 가져옵니다
function calc_accept($key)
{
$tmp=$key."258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
$tmp=sha1($tmp,true);
//console($tmp);
$tmp=base64_encode($tmp);
//console($tmp);
return $tmp;
}
이것은 악수 수행합니다
while(true){
$changed = $sockets;
socket_select($changed,$write=NULL,$except=NULL,NULL);
foreach($changed as $socket){
if($socket==$master){
console("Master Socket Changed.");
$client=socket_accept($master);
if($client<0){ console("socket_accept() failed"); continue; }
else{ connect($client); }
}
else{
console($socket." Socket Changed.");
$str=socket_read($socket,2048);
$user=getuserbysocket($socket);
if(strlen($str)==0) disconnect($socket);
else if(!$user->handshake){ dohandshake($user,$str); }
else
{
myProcess($socket,$str);
}
console("Comunication Ends Here.");
}
}
}
이 섹션 동의의 계산은 다음과 같습니다
이
서버의 코드 클라이언트 핸드 셰이크 및 소켓에 의한 사용자 객체 얻기 :function getheaders($req){
$r=$h=$o=null;
if(preg_match("/GET (.*) HTTP/" ,$req,$match)){ $r=$match[1]; }
if(preg_match("/Host: (.*)\r\n/" ,$req,$match)){ $h=$match[1]; }
if(preg_match("/Origin: (.*)\r\n/",$req,$match)){ $o=$match[1]; }
if(preg_match("/Sec-WebSocket-Key: (.*)\r\n/",$req,$match)){ $key=$match[1]; }
if(preg_match("/\r\n(.*?)\$/",$req,$match)){ $data=$match[1]; }
return array($r,$h,$o,$key,$data);
}
function getuserbysocket($socket){
global $users;
$found=null;
foreach($users as $user){
if($user->socket==$socket){ $found=$user; break; }
}
return $found;
}
올바른 소켓으로 클라이언트에 쓰고 있습니까? 클라이언트에게 메시지를 보내는 것은 소켓이 메시지를 수신하는 것과 별개입니다. – Stevko
예, 새로 들어오는 소켓을 받아들이고 나중에 사용할 수 있도록 사용자 개체에 저장했습니다. 긴 문자열을 보낼 때 클라이언트에 오류가 발생하면 클라이언트가 바이트를 가져 오는 것으로 나타납니다. – Velissel