соединение SSL websocket храповика php?

у меня есть файл сервера храповика чата

use RatchetServerIoServer;
use RatchetWebSocketWsServer;
use MyAppChatChat;
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-соединением

есть идеи?

7 ответов


Если вы используете веб-сервер Apache (2.4 или выше), включите эти модули в httpd.файл conf :

  1. mod_proxy.так что ...
  2. mod_proxy_wstunnel.так что ...

добавьте этот параметр в httpd.файл conf

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

используйте этот URL в вызове JavaSscript, когда вы хотите соединение WSS:

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

перезапустите веб-сервер Apache и убедитесь, что ваш храповик (подключение к веб-сокету) откройте перед применением настроек (порт имени хоста telnet).


проблема в том, что React (на котором построен храповик) не поддерживает прямые SSL-соединения. Смотрите это вопрос.

существует простой обходной путь. Использовать stunnel с конфигурацией типа:

[websockets]
accept = 8443
connect = 8888

Stunnel будет обрабатывать трафик SSL на порту 8443 и переносить их на ваш сервер websocket.


Я нашел этот ответ на Ratchet в Google-группе by Крис Боден:

лучшим решением было бы использовать Nginx в качестве веб-сервера. Есть Nginx слушайте порт 80 для входящих подключений и обрабатывайте его использование SSL. Nginx будет пересылать входящие соединения на PHP-FPM для вашего обычный сайт, и если он обнаруживает соединение, это WebSocket подключение имеет прокси-сервер к запущенному приложению Ratchet на порту на ваш выбор. Ваш затем 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/(.*) / 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/ расположение

wss://127.0.0.1/wss/

Если вы используете Windows IIS, убедитесь, что вы настроили его для HTTPS (я использую самозаверяющий сертификат), а затем установите обратный прокси:

переписать URL: https://www.iis.net/downloads/microsoft/url-rewrite и ARR 3.0: https://www.iis.net/downloads/microsoft/application-request-routing

вам также необходимо включить поддержку websockets в IIS:enter image description here

создать папку (например, myproxyfolder) для URL переписать, на этой папке создать web.конфигурационный файл с содержимым:

<?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 (я использую Ratched для PHP на WIN).

на стороне клиента в javascript используйте защищенные websockets WSS: / / протокол, например:

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

несколько дней назад я искал ответ на этот вопрос, и я нашел это в проблемах храповика Github:https://github.com/ratchetphp/Ratchet/issues/489

последний ответ, Ответ heidji, говорит:

Я только добавил этот комментарий для новичков, таких как я, которым нужна быстрая инструкция по внедрению SSL: Через документы ReactPHP вам нужно только построить 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, как упоминалось cboden выше

таким образом, кажется, что теперь есть способ реализовать безопасный сервер websocket с храповиком без необходимости прокси HTTPS.

здесь у вас есть документация класса SecureServer:https://github.com/reactphp/socket#secureserver