2011-08-17 13 views
7

Così Chrome 14 ha implementato la versione hybi10 di websockets. Ho un programma in-house che la nostra azienda utilizza tramite chrome che utilizza web socket che è rotto con questo cambiamento.Server Websocket PHP hybi10

Qualcuno ha avuto successo nel framing dei dati utilizzando un server php? Sono in grado di far funzionare la nuova stretta di mano ma non riesco a capire l'inquadratura. C'è un esempio python qui https://github.com/kanaka/websockify/blob/master/websocket.py#L233 ma sto avendo difficoltà a convertirlo in php, qualcuno ha un suggerimento?

Devo dire che la funzione in questione nell'esempio python è decode_hybi().

+1

Forse questa domanda è interessante per te: http://stackoverflow.com/questions/7040078/not-sure-how-to-frame-data-in -websockets-draft-08. Ho cercato di spiegare come funziona la nuova inquadratura; forse aiuta. – pimvdb

+0

Questo è stato utile grazie! Pubblicherò la soluzione in PHP per gli altri. – jivetek

risposta

6

Ho appena completato un wich di classe rende il PHP-websocket-Server di Nico Kaiser (https://github.com/nicokaiser/php-websocket) in grado di gestire hybi-10 telai e la stretta di mano. Puoi scaricare la nuova classe qui: http://lemmingzshadow.net/386/php-websocket-serverclient-nach-draft-hybi-10/ (Connection.php)

+0

Grazie per questo. Inizialmente utilizzavo anche questa implementazione. Hai decisamente migliorato il mio codice e mi hai risparmiato tempo nell'implementare una soluzione completa! – jivetek

3

Questo codice non presuppone errori o frame non validi e si basa su questa risposta - How to (de)construct data frames in WebSockets hybi 08+?.

Questo codice è molto semplice ed è lontano da una soluzione completa. Funziona per i miei scopi (che sono piuttosto semplici). Spero che sia utile per gli altri.

function handle_data($data){ 
    $bytes = $data; 
    $data_length = ""; 
    $mask = ""; 
    $coded_data = "" ; 
    $decoded_data = "";   
    $data_length = $bytes[1] & 127; 
    if($data_length === 126){ 
     $mask = substr($bytes, 4, 8); 
     $coded_data = substr($bytes, 8); 
    }else if($data_length === 127){ 
     $mask = substr($bytes, 10, 14); 
     $coded_data = substr($bytes, 14); 
    }else{ 
     $mask = substr($bytes, 2, 6); 
     $coded_data = substr($bytes, 6); 
    } 
    for($i=0;$i<strlen($coded_data);$i++){ 
     $decoded_data .= $coded_data[$i]^$mask[$i%4]; 
    } 
    $this->log("Server Received->".$decoded_data); 
    return true; 
} 

Ecco il codice per inviare i dati indietro. Ancora una volta questo è piuttosto semplice, si presuppone che si sta inviando una singola cornice di testo. Nessun frame di continuazione, ecc. Nessun controllo degli errori. Spero che gli altri lo trovino utile.

public function send($data) 
{ 
    $frame = Array(); 
    $encoded = ""; 
    $frame[0] = 0x81; 
    $data_length = strlen($data); 

    if($data_length <= 125){ 
     $frame[1] = $data_length;  
    }else{ 
     $frame[1] = 126; 
     $frame[2] = $data_length >> 8; 
     $frame[3] = $data_length & 0xFF; 
    } 

    for($i=0;$i<sizeof($frame);$i++){ 
     $encoded .= chr($frame[$i]); 
    } 

    $encoded .= $data; 
    write_to_socket($this->socket, $encoded); 
    return true;  
} 
+1

Ottimo sei riuscito a farlo funzionare. È possibile scegliere se si desidera codificare i dati da server a client. Ciononostante dovresti ricominciare con '1000 0001' e poi un altro byte che inizia con' 0' (se non lo mascheriamo), e usa lo stesso formato per la lunghezza (questo è obbligatorio, il mascheramento non è conforme al Specifiche). – pimvdb

+1

grazie ancora per il tuo aiuto! Sono riuscito a far funzionare anche questa parte. Copierò di nuovo il mio codice in modo che altri possano usarlo. – jivetek

+0

Grazie per aver pubblicato la tua soluzione; questo è certamente utile per gli altri! – pimvdb