PHP Websocket server - Handle more frames in socket_recv -
hope wasn't solved here before, trying answer!
i have problem receiving frames via socket_recv in php server. problem appears when send more 1 messages client in 1 time (e.g. in cycle). stream length it's match frames count i'm not able unmask frames correctly , unmask function return first frame. i'm using part of php server found here , 1 message it's working properly, when receive more messages @ time, don't unmask all.
i tryed add loop go thru frames, i'm not able find end of frame , continue other.
here main while of server:
while (true) { //manage multipal connections $changed = $clients; //returns socket resources in $changed array socket_select($changed, $null, $null, 0, 10); //check new socket if (in_array($socket, $changed)) { $socket_new = socket_accept($socket); //accpet new socket $clients[] = $socket_new; //add socket client array $header = socket_read($socket_new, 10240); //read data sent socket perform_handshaking($header, $socket_new, $host, $port); //perform websocket handshake socket_getpeername($socket_new, $ip); //get ip address of connected socket $response = mask(json_encode(array('type' => 'system', 'status' => true, "id" => "srv_connected", 'message' => $ip . ' connected'))); //prepare json data send_message($response); //notify users new connection //make room new socket $found_socket = array_search($socket, $changed); unset($changed[$found_socket]); } foreach ($changed $changed_socket) { while (@socket_recv($changed_socket, $buf, 1024, 0) >= 1) { $received_text = unmask($buf); //unmask data $tst_msg = json_decode($received_text, true); //json decode $response_text = parse_msg($tst_msg, $changed_socket); break 2; //exit loop } $buf = @socket_read($changed_socket, 10240, php_normal_read); if ($buf === false) { // check disconnected client // remove client $clients array $found_socket = array_search($changed_socket, $clients); socket_getpeername($changed_socket, $ip); unset($clients[$found_socket]); //notify users disconnected connection $response = mask(json_encode(array('type' => 'system', 'message' => $ip . ' disconnected'))); send_message($response); } }
i need call parse_msg count of frames received in @socket_recv should returned unmask function.
and here unmask function:
function unmask($payload){ $decmessages = array(); { // should running until frames unmasked , added $decmessages array $length = ord($payload[1]) & 127; if($length == 126) { $masks = substr($payload, 4, 4); $data = substr($payload, 8); $len = (ord($payload[2]) << 8) + ord($payload[3]); }elseif($length == 127) { $masks = substr($payload, 10, 4); $data = substr($payload, 14); $len = (ord($payload[2]) << 56) + (ord($payload[3]) << 48) + (ord($payload[4]) << 40) + (ord($payload[5]) << 32) + (ord($payload[6]) << 24) +(ord($payload[7]) << 16) + (ord($payload[8]) << 8) + ord($payload[9]); }else { $masks = substr($payload, 2, 4); $data = substr($payload, 6); $len = $length; } $text = ''; ($i = 0; $i < $len; ++$i) { $text .= $data[$i] ^ $masks[$i%4]; } $decmessages[] = $text; // here problem. doesn't put correct substr $payload, run again on stream shorted last message $payload = substr($payload, $length, strlen($payload)); }while (($len < strlen($data)) , $countert < 10); return $decmessages; }
i think problem here: $payload = substr($payload, $length, strlen($payload)); i'm putting wrongly rest of stream?
so questions are: why @socket_recv return more 1 frame how can change unmask function go thru frames, not first one
i extremelly greatfull help, because i'm fighting more should.
thanks in advance klara!
so, found solution this. thought, problem multiple frames in 1 receive. needed edit unmask function check if there still frames in stream.
basically, had right $length in
$payload = substr($payload, $length, strlen($payload));
was wrong. instead of $length used $len + 8, 14 od 6 depend on $length. i'm not sure how describe why i'm sure will. that's all. it's working should!
thanks!
Comments
Post a Comment