2015-10-29 4 views
0

Я пытаюсь протестировать простой пинг & ответы на понг с помощью WebSockets с помощью Ratchet. Мой сервер WebSocket не видя любые ответы от клиента WebSocket моего веб-браузера но пакеты, отправленные сервером WebSocket, хорошо видны браузеру. Я пытаюсь найти, почему.Ratchet не принимает пакет WebSocket из браузера?

Мои текущие догадок:

  • я пропускаю некоторые HTTP заголовок (ы)
  • Я должен кодировать пакеты в браузере wsclient.send(encodeFrame("{'action': 'pong'}"));
  • CloudFlare не признающие пакет в WS потока действительными и thrashes it
  • CloudFlare или nginx в экземпляре EC2 делает какую-то странную буферизацию
  • Ratchet не распознает пакет на самом низком уровне IOServer и разбивает его
    • Но я никогда не получить какие-либо ошибки или исключения из этого уровня

Установка:

  • сервер Linux @ Amazon EC2
  • DNS @ CloudFlare со свободным планом и ускорения на + принудительное перенаправление HTTPS на
  • HTTP-сервер - nginx
  • Нет HTTPS на Nginx (Cloudflare перенаправляет HTTPS -> EC2 HTTP)
  • WebSocket сервер (трещотка) работает на 127.0.0.1:65000 на EC2
  • Nginx перенаправляет /api к 127.0.0.1:65000 (Ratchet)

Испытано с собственным клиентом WebSocket на EC2 экземпляр:

  • 127.0.0.1:65000 работает отлично
  • <Amazon NAT IP of instance>:80 работает отлично
  • <Amazon public IP of instance>:80 работает отлично
  • <CloudFlare IP of Amazon public IP>:80 Подключение к серверу WebSocket на уровне implementatuin приложений, но не видит пакет на onMessage метод на любом уровне (приложение, WsServer, HTTPServer)
  • <CloudFlare IP of Amazon public IP>:443 дает 400 Bad Request потому, что тестовый клиент просто простой TCP поток

Испытан из локальной машины:

непосредственно подключаться к узлу, предлагаемому кэшированному IP CloudFlare в. Dojox.Socket подключается к wss://host/api. Соединение снова видно на уровне реализации приложения на Ratchet (onOpen уволен). Мой браузер видит ping пакетов, поэтому отправка с Ratchet отлично работает.

Но затем я пытаюсь отправить pong ответ на ping из браузера, а метод onMessage не запускается ни на одном уровне на Ratched. Соединение остается открытым, и если я смотрю с Fiddler, оба пинга и понга постоянно отправляются, но сервер WebSocket никогда не получает этих понг (onMessage).

После потока WebSocket Fiddler показывает, что PONGS из браузера имеет «Data маскируется ключ: <some hex>», но пинги из Ratched являются не масках.

резюме

соединения:

загрузки страницы:

Локальная машина http://host/ → CloudFlare HTTPS перенаправлять https://host/http://host-with-amazon-public-ip/http://host-with-amazon-NAT-ip/ → HTML + JS страницу, которая загружает WSS WebSocket Подключение к /api

подключение WebSocket к /api :

CloudFlare HTTPS перенаправлены WSS: // хост/апи → http://host-with-amazon-public-ip/apihttp://host-with-amazon-NAT-ip/api → локальный сервер Nginx редирект/апи → → 127.0.0.1:65000 Подключение обновления → WebSocket поток → WebSocket поток для веб-браузера

nginx.conf

server { 
    listen 80; 

    server_name test.example.com; 
    root /home/raspi/test/public; 
    autoindex off; 
    index index.php; 

    access_log /home/raspi/test/http-access.log; 
    error_log /home/raspi/test/http-error.log notice; 

    location/{ 
    index index.php; 
    try_files $uri $uri/ /index.php?$args; 
    } 

location /api { 
    access_log /home/raspi/test/api-access.log; 
    error_log /home/raspi/test/api-error.log; 

    expires epoch; 

    proxy_ignore_client_abort on; 
    proxy_buffering off; 
    proxy_request_buffering off; 
    proxy_cache off; 
    proxy_pass http://127.0.0.1:65000/; 

    proxy_http_version 1.1; 

    proxy_set_header Host $host; 
    proxy_set_header Connection "keep-alive, Upgrade"; 
    proxy_set_header Upgrade "websocket"; 
    proxy_set_header Accept-Encoding "gzip, deflate"; 
    proxy_set_header Sec-WebSocket-Extensions "permessage-deflate"; 
    proxy_set_header Sec-WebSocket-Protocol "game"; 
    proxy_set_header X-Real-IP $remote_addr; 
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 
    } 

    location ^~ /js/app/ { 
    try_files $uri /; 
    expires epoch; 
    add_header Cache-Control "no-cache" always; 
    } 

    location ~* ^.+.(jpg|jpeg|gif|css|png|js|ico|html|xml|txt)$ { 
    try_files $uri /; 
    access_log off; 
    expires max; 
    } 

    location = /robots.txt { access_log off; log_not_found off; } 
    location = /favicon.ico { access_log off; log_not_found off; }  
    location ~ /\. { access_log off; log_not_found off; deny all; } 

    location ~ \.php$ { 
    try_files $uri =404; 
    fastcgi_split_path_info ^(.+\.php)(/.+)$; 
    fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock; 
    fastcgi_index index.php; 
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; 
    include fastcgi_params; 
    } 
} 
+0

Есть ли у вас * ваши учетные записи для поддержки Cloudflare? https://blog.cloudflare.com/cloudflare-now-supports-websockets/ Из-за того, что веб-сайты работают путем «обновления» HTTP-соединения, кажется возможным, что возможна односторонняя передача «от сервера к клиенту» * в определенных обстоятельствах через прокси-сервер, который не полностью поддерживает протокол и предполагает, что сервер все еще возвращает тело ответа HTTP. –

ответ

0

Веб-сокеты в настоящее время доступны только на уровне предприятий и предприятий. Вы упомянули, что находитесь в свободном плане. Это проблема.

0

Проблема заключается в том, что ваш провайдер отклоняет заголовки подключения и обновления. Вы можете перейти к Ratchet/WebSocket/версия/RFC6455/HandshakeVerifier.php и модифицировать код:

... 
    public function verifyAll(RequestInterface $request) { 
    $passes = 0; 

    $passes += (int)$this->verifyMethod($request->getMethod()); 
    $passes += (int)$this->verifyHTTPVersion($request->getProtocolVersion()); 
    $passes += (int)$this->verifyRequestURI($request->getPath()); 
    $passes += (int)$this->verifyHost((string)$request->getHeader('Host')); 
    $passes += (int)$this->verifyUpgradeRequest((string)$request->getHeader('Upgrade')); 
    $passes += (int)$this->verifyConnection((string)$request->getHeader('Connection')); 

    die((string)$request); 
    ... 

И вы увидите запрос на результат не имеет необходимых полей;

Обходное решение: переопределить функцию WsServer :: onOpen и добавить эти поля для запроса вручную. Но это небезопасно ...

 Смежные вопросы

  • Нет связанных вопросов^_^