Autor Zpráva
Nickname
Profil *
Dobrý deň, mám taký špecifický problém. Mám v PHP naprogramovaný WebSocket server, ktorý súčasne počúva aj na UDP... ak prídu dáta z UDP, chcem ich hneď poslať klientom pripojeným na web socket... Avšak vyzerá to momentálne tak, že v jednej nekonečnej slučke viem zachytiť len jednu konekciu a to buď UDP alebo buď Web Socket...súčasne nejdú zachytiť obe. Myslím si, že je to z toho dôvodu, že ak mám v kóde $buf = socket_read($socketD,1024); tak tu slučka zastane a čaká na údaje z UDP (ďalej cyklus nepokračuje až kým nemá dáta) avšak ak mám predtým v kóde
$a = socket_select($changed, $write, $except,NULL) ; čaká zase na údaje z web socketov a cyklus až na socket_read nepríde kým nepridu dáta z web socketov... Keď tam mám len jeden zo spomínaných príkazov, to čo má robiť konkrétny príkaz funguje (ak je socket_read tak číta dáta z UDP ak socket_select tak čita z web socketov).

    public function run() {
        // main run loop        
                $socketD = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
                if($socketD === FALSE) { //omg, something went wrong
                        echo 'socket_create failed: '.socket_strerror(socket_last_error())."\n";
                        exit(1);
                }

                if(!socket_bind($socketD, "0.0.0.0", 1234)) {
                        //socket_close($socketD);
                        echo 'socket_bind failed: '.socket_strerror(socket_last_error())."\n";
                        exit(1);
                }
                
        while(true){
            $changed = $this->sockets;
                        $write = array();
                        $except = array();
                        
                        $buf = socket_read($socketD,1024);
                        $a = socket_select($changed, $write, $except,NULL) ;
            if (false === $a) {
                die("socket_select() failed: ". socket_strerror(socket_last_error()));
                        }
                        echo $a."->".$buf;
                        
            foreach($changed as $socket){
                if ($socket == $this->master) {
                    // new incoming connection, time to accept
                    $this->log("Incoming connection request");
                    $client = socket_accept($this->master);
                    if($client === false){ $this->log("socket_accept() failed: ". socket_strerror(socket_last_error())); continue; }
                    else{ $this->connect($client); }
                } else {
                    // existing connection has data to read
                    $bytes = @socket_recv($socket, $buffer, 2048, 0);
                    // close the connection if there was an error or no data to read
                    if($bytes == 0) {
                        $this->disconnect($socket);
                    } else {
                        $user = $this->getUserBySocket($socket);
                        // perform the WebSocket upgrade HTTP handshake if needed
                        if(! $user->handshake) {
                            $this->doHandshake($buffer, $socket);
                            $user->handshake = true;
                        } else {
                                                        
                            //$this->log("< ". $buffer);
                            $user->lastAction = time();
                            // call the callback function
                                                        //$this->logFile("log.dat","run", "Got message - ready for handling", $buffer);
                                                        $msg = $this->handleMessage($buffer);
                                                                                    $this->log("< ". $msg);
                                                        $this->send($user->socket,"$msg");                            
                        }
                    }
                }
            }
        }
    }

Naozaj som už zúfalý v tom, ako spraviť aby nečakali ak sa to vôbec dá...
Za odpoveď ďakujem
Igor R.
Profil *
Tohle je ztráta času, čeho tím chceš docílit? Z kodu mám pocit, že používáš jakousi knihovnu, které nerozumíš. Po letmém přelítnutí mi není jasné, kde si to uchovává aktivní připojené uživatele, tj. odkud se bere hodnota $this->sockets. PHP je bezstavové, tj. jak dokončí požadavek ukončí se a vše vyprázdní, tj. i otevřené sockety zabije. Chyba je možná jen v tom, že si to nepamatuje připojené uživatele.

Jinak doporučuji, otoč se a jdi jinou cestou, tohle bude vždy pomalé a těžko laditelné, php je mocné, ale má pevně dané hranice. Nedávno bylo experimentálně uvolněno rozšíření php o websocket http://socketo.me , v porovnání ale s pythonem nebo javou je to stonásobně pomalejší.

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm:

0