棘轮没有从浏览器接收WebSocket数据包?
我想通过使用棘轮测试简单的ping & pong与WebSockets的响应。我的WebSocket服务器是而不是看到来自我的Web浏览器的WebSocket客户端的任何响应但由WebSocket服务器发送的数据包被浏览器看好。我试图找到原因。棘轮没有从浏览器接收WebSocket数据包?
我目前的猜测是:
- 我丢失了一些HTTP头(一个或多个)
- 我有编码
wsclient.send(encodeFrame("{'action': 'pong'}"));
- 的CloudFlare是不承认在WS流包为有效浏览器的数据包,砸它
- EC2实例中的CloudFlare或nginx正在做一些奇怪的缓冲
- 棘轮不识别最低IOServer级别上的数据包并将其抖动
- 但我从来没有从这个层面上得到任何错误或异常
设置:
- Linux服务器@亚马逊EC2
- 有免费计划,并加速对DNS @的CloudFlare +强制HTTPS重定向
- HTTP服务器是nginx
- 没有HTTPS上的nginx(CloudFlare的重定向HTTPS - > EC2 HTTP)
/api
到
127.0.0.1:65000
(救护车)
在测试了自己的WebSocket客户
127.0.0.1:65000
运行在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流
从本地机器测试:
直接连接通过CloudFlare的缓存的IP,以提供主机。 Dojox.Socket连接到wss://host/api
。在Ratchet的应用程序实现级别上再次出现连接(已启动onOpen
)。我的浏览器看到ping
包很好,所以从棘轮发送工作正常。
但后来我试着发送pong
回复到ping
从浏览器和onMessage
方法不是从来没有在任何关于Ratched的级别上被解雇。连接保持开放,如果我用Fiddler观看ping和pongs都会不断发送,但WebSocket服务器永远不会收到这些pong(onMessage
)。
继提琴手的WebSocket的流显示,从浏览器pongs具有“数据由键屏蔽:<some hex>
”,而是来自拉契特坪是不掩盖。
连接摘要:
页面加载:
本地机器http://host/ → CloudFlare的HTTPS重定向https://host/加载WSS WebSocket连接到/api
WebSocket连接到/api
→ http://host-with-amazon-public-ip/ → http://host-with-amazon-NAT-ip/ → HTML + JS网页:
CloudFlare的HTTPS重定向WSS://主机/ API → http://host-with-amazon-public-ip/api → http://host-with-amazon-NAT-ip/api →本地服务器nginx的重定向/ API → 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;
}
}
Web套接字目前仅在商业和企业级别可用。你提到你在免费计划。这是这个问题。
问题是您的提供商拒绝连接和更新标头。你可以去棘轮/的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函数并添加该字段以手动请求。但这是不安全的...
*您的* Cloudflare帐户是否支持websockets? https://blog.cloudflare.com/cloudflare-now-supports-websockets/由于websockets通过“升级”HTTP连接的方式工作,单向服务器到客户端的传输似乎是可能的在某些情况下,通过代理不完全支持协议,并假定服务器仍然返回HTTP响应主体。 –