PHP WebSocketServer не может подключиться к WebKit (Safari) - PullRequest
2 голосов
/ 27 марта 2012

Я написал сервер WebSocket на PHP, который хорошо подключается к Firefox, но не к Safari. Я думаю, что с рукопожатием что-то не так. Safari нужна старая версия hybi00 ... но я не могу найти ошибку: /

Соединение закрывается в Safari сразу после попытки подключения. Заранее спасибо за помощь!

<code><?php
error_reporting(E_ALL);
set_time_limit(0);
date_default_timezone_set("Europe/Berlin");
ob_implicit_flush(true);

function debug($text)
{
    $file = "log.html";
    file_put_contents($file,
    "<pre>".$text."
"." Ende der Information

", 8); } // Socket initialisieren $ master = socket_create (AF_INET, SOCK_STREAM, SOL_TCP); socket_set_option ($ master, SOL_SOCKET, SO_REUSEADDR, 1); // Diesen Computer binden socket_bind ($ master, "localhost", 10000) или die (); // Maximale Verbindungsanforderungen: 5 socket_listen ($ master, 5); делать { $ client = socket_accept ($ master); echo "Neuer Client! \ n"; новый клиент ($ клиент); } while (true); выход(); // Clientklasse Класс Клиента { частное $ соединение; private $ header = array (); частный $ crypt; // BOOL, hybi00 не нуждается в расшифровке, но hybi06 + функция __construct (& $ socket) { $ this-> connection = $ socket; $ This-> SetWebSecKey (); в то время как (истина) { $ q = socket_read ($ this-> connection, 1024); если (Исеть ($ д)) { echo $ this-> unmask ($ q); } $ welcome = "\ x81 \ x8c \ xff \ xb8 \ xbd \ xbd \ xb7 \ xdd \ xd1 \ xd1 \ x90 \ x98 \ xea \ xd2 \ x8d \ xd4 \ xd9 \ x9c"; } } / ** * Снятие маски с полученного полезного груза. * @param $ payload * * http://srchea.com/blog/2011/12/build-a-real-time-application-using-html5-websockets/ * / частная функция unmask ($ payload) { $ length = ord ($ payload [1]) & 127; if ($ length == 126) { $ masks = substr ($ payload, 4, 4); $ data = substr ($ payload, 8); } elseif ($ length == 127) { $ masks = substr ($ payload, 10, 4); $ data = substr ($ payload, 14); } еще { $ masks = substr ($ payload, 2, 4); $ data = substr ($ payload, 6); } $ text = ''; для ($ i = 0; $ i 125 && $ length <65536) $ header = pack ('CCS', $ b1, 126, $ length); elseif ($ length> = 65536) $ header = pack ('CCN', $ b1, 127, $ length); вернуть заголовок $. $ текст; } приватная функция SetWebSecKey () { // Заголовок запроса в массиве тейлен $ request = socket_read ($ this-> connection, 1024); $ request = explode ("\ n", $ request); foreach ($ request as $ key => $ head) { $ header = explode (":", $ head, 2); $ header [0] = trim ($ header [0]); // Параметр $ header [1] = trim ($ header [1]); // Верт $ this-> header [$ header [0]] = $ header [1]; } $ handshake = new Handshake ($ this-> header); $ Handshake-> Отправить (соединение $ this->); } приватная функция SendPlain ($ text) { socket_write ($ this-> connection, $ text, strlen ($ text)); } } класс Рукопожатие { закрытый заголовок $; личное $ hybi00; private $ secKey; публичная функция __construct ($ headerArray) { echo "\ nHandshake wird ausgeführt:"; // Einfacher или двойник SecWebKey? // Einfach: Hybi06 + // Doppelt: Hybi00 + $ this-> header = $ headerArray; если (Исеть ($ this-> заголовок [ "Sec-WebSocket-Key"])) { эхо "Hybi06 + \ n"; // Moderner Hybi06 + $ this-> secKey = $ this-> InitHybi06 (); } elseif (isset ($ this-> header ["Sec-WebSocket-Key1"])) { // Эльтерьер Hybi00 + эхо "Hybi00 + \ n"; $ this-> secKey = $ this-> InitHybi00 (); } еще {echo "Fehler - Unbekanntes WebSocket-Protokoll \ n"; вернуть; } } приватная функция InitHybi06 () { $ this-> hybi00 = false; $ key = $ this-> header ["Sec-WebSocket-Key"]; $ GUID = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11'; $ key. = $ GUID; вернуть base64_encode (sha1 ($ key, true)); } частная функция InitHybi00 () { $ this-> hybi00 = true; $ key1 = $ this-> header ["Sec-WebSocket-Key1"]; $ key2 = $ this-> header ["Sec-WebSocket-Key2"]; $ key1 = $ this-> Hybi00NumSpace ($ key1); $ key2 = $ this-> Hybi00NumSpace ($ key2); $ data = array_keys ($ this-> header); $ data = $ data [count ($ this-> header) -1]; $ ctx = hash_init ('md5'); hash_update ($ ctx, pack ("N", $ key1)); hash_update ($ ctx, pack ("N", $ key2)); hash_update ($ ctx, $ data); $ hash_data = hash_final ($ ctx, true); вернуть $ hash_data; } приватная функция Hybi00NumSpace ($ key) { $ numbrs = preg_replace ('/ [^ \ d] * /', '', $ key); $ space = strlen (preg_replace ('/ [^ \ s] [^ \ s] * /', '', $ key)); вернуть $ numbrs / $ пробелы; } открытая функция Send ($ socket, $ origin = "http://localhost", $ location =" ws: // localhost ", $ return = false) { if (! isset ($ this-> header) ||! isset ($ this-> hybi00) ||! isset ($ this-> secKey)) { echo "Fehler: Handshake nicht vollständig! \ n"; вернуть; } $ header = $ this-> CreateHeader ($ origin, $ location); отладки ($ заголовка); $ header = Explode ("\ n", $ header); если ($ возврата) вернуть заголовок $; foreach ($ header как $ line) { $ line. = "\ n"; socket_write ($ socket, $ line, strlen ($ line)); } } приватная функция CreateHeader ($ origin, $ location) { $ header = "HTTP / 1.1 101 WebSocket Protocol Handshake \ r \ n". Msgstr "Обновить: WebSocket \ r \ n". Msgstr "Подключение: обновить \ r \ n". "Sec-WebSocket-Origin: $ origin \ r \ n"; если ($ this-> hybi00) { $ header. = "Sec-WebSocket-Location: $ location \ r \ n"; $ header. = "\ r \ n". $ this-> secKey.chr (0); } еще { $ header. = "Sec-WebSocket-Accept:". $ this-> secKey. "\ r \ n \ r \ n"; } вернуть заголовок $; } }

1 Ответ

0 голосов
/ 07 сентября 2012

Я не знаю, как это сделать в вашем коде, вы можете посмотреть на PHPDaemon - его неблокирующая запись сервера на php с поддержкой websocket.

...