PHP的棘轮websocket SSL连接?

我有一个棘轮聊天服务器文件

use Ratchet\Server\IoServer; use Ratchet\WebSocket\WsServer; use MyAppChat\Chat; require dirname(__DIR__) . '/vendor/autoload.php'; $server = IoServer::factory( new WsServer( new Chat() ) , 26666 ); $server->run(); 

我使用Websocket连接ws ,它工作正常

 if ("WebSocket" in window) { var ws = new WebSocket("ws://ratchet.mydomain.org:8888"); ws.onopen = function() { // Web Socket is connected. You can send data by send() method. ws.send("message to send"); }; ws.onmessage = function (evt) { var received_msg = evt.data; }; ws.onclose = function() { // websocket is closed. }; } else { // the browser doesn't support WebSocket. } 

我想要安全的连接,所以我尝试与SSL连接,但不工作。

 if ("WebSocket" in window) { var ws = new WebSocket("wss://ratchet.mydomain.org:8888"); ws.onopen = function() { // Web Socket is connected. You can send data by send() method. ws.send("message to send"); }; ws.onmessage = function (evt) { var received_msg = evt.data; }; ws.onclose = function() { // websocket is closed. }; } else { // the browser doesn't support WebSocket. } 

我的问题是如何连接websocket与SSL连接

任何想法?

如果您使用Apache Web服务器(2.4或更高版本),请在httpd.conf文件中启用这些模块:

  1. mod_proxy.so
  2. mod_proxy_wstunnel.so

将此设置添加到您的httpd.conf文件

 ProxyPass /wss2/ ws://ratchet.mydomain.org:8888/ 

需要WSS连接时,在JavaSscript调用中使用此URL:

 var ws = new WebSocket("wss://ratchet.mydomain.org/wss2/NNN"); 

重新启动Apache Web服务器并确保在应用设置(telnet主机名端口)之前,您的Ratchet工作(Web套接字连接)已打开。

问题在于React(其中构build了棘轮)不支持直接的SSL连接。 看到这个问题 。

有一个简单的解决方法。 使用像以下configuration的stunnel :

 [websockets] accept = 8443 connect = 8888 

Stunnel将处理端口8443上的SSLstream量并将它们移植到您的websocket服务器。

我在Chris Boden的 Ratchet的google小组上find了这个答案:

最好的解决scheme是使用Nginx作为您的Web服务器。 让Nginx监听端口80上的传入连接,并让它处理您的SSL。 Nginx将传入的连接转发到PHP-FPM为您的常规网站,如果它检测到连接是一个WebSocket连接,它将代理到您select的端口上运行的棘轮应用程序。 您的JavaScript可以通过wss://mydomain.org进行连接

这是一个使用stunnel的替代方法,如果你的应用程序将使用nginx来提供服务。

如果您使用的是Nginx,只需在您的SSL服务器块中写入:

 location /services/myservice { # switch off logging access_log off; # redirect all HTTP traffic to localhost proxy_pass http://localhost:1234; proxy_set_header X-Real-IP $remote_addr; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # WebSocket support (nginx 1.4) proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; # Path rewriting rewrite /services/myservice/(.*) /$1 break; proxy_redirect off; # timeout extension, possibly keep this short if using a ping strategy proxy_read_timeout 99999s; } 

这将升级任何wss://yoursite.com/services/myservice调用到端口1234上运行的套接字。只要确保你记得不要离开端口1234开放的世界。

Apache也为我工作,只需添加在域conf:

 ProxyPass /wss/ wss://127.0.0.1:8888/ 

重新加载apache,然后导入到客户端设置wss以包含/ wss / location

 wss://127.0.0.1/wss/ 

如果您使用的是Windows IIS,请确保您已将其configuration为HTTPS(我正在使用自签名证书),然后安装反向代理:

URL重写: https : //www.iis.net/downloads/microsoft/url-rewrite和ARR 3.0: https : //www.iis.net/downloads/microsoft/application-request-routing

您还需要在IIS中启用Websockets支持: 在这里输入图像描述

创build用于URL重写的文件夹(例如myproxyfolder),在该文件夹中创build包含以下内容的web.config文件:

 <?xml version="1.0" encoding="UTF-8"?> <configuration> <system.webServer> <rewrite> <rules> <rule name="WebSocketProxy" stopProcessing="true"> <match url="(.*)" /> <action type="Rewrite" url="http://127.0.0.1:8080" /> </rule> </rules> </rewrite> </system.webServer> </configuration> 

并将“ http://127.0.0.1:8080 ”更改为您的websocket服务(我在WIN上使用Ratched for PHP)。

在JavaScript的客户端,使用安全的websockets wss://协议,如:

  mysock = new WebSocket('wss://127.0.0.1/myproxyfolder'); ... 

前几天我正在寻找这个问题的答案,我发现在Github棘轮问题: https : //github.com/ratchetphp/Ratchet/issues/489

heidji回答的最后一个答案是这样说的:

我只为像我这样的新手添加了这个评论,他们需要一个快速的指导如何实现SSL:通过ReactPHP文档,你只需要构build这样提到的SecureServer:
$webSock = new React\Socket\Server('0.0.0.0:8443', $loop);
$webSock = new React\Socket\SecureServer($webSock, $loop, ['local_cert' => '/etc/ssl/key.pem', 'allow_self_signed' => true, 'verify_peer' => false]);
然后像上面提到的那样注入到IoServer中

所以现在似乎有一种方法来实现一个棘轮安全websocket服务器,而不需要HTTPS代理。

这里有SecureServer类文档: https : //github.com/reactphp/socket#secureserver