Соединения websockets завершаются с Apache и Ratchet - PullRequest
3 голосов
/ 15 октября 2019

Я написал сервер php websockets, используя библиотеку Ratchet , которую я вызываю с помощью javascript, используя объект websocket .

Все работало идеально локально, но было невозможноЗапустите мой проект на моем сервере Debian под apache.

Чтобы включить соединения через веб-сокеты, я прочитал, что должен использовать модуль mod_proxy_wstunnel . Поэтому я переписываю свой apache conf для моего субдомена api.domain.com следующим образом:

<VirtualHost *:80>
        ServerAdmin admin@admin.admin
        DocumentRoot /var/www/api.domain.com
        ServerName api.domain.com

        # Enable Websocket connections on port 8888
        ProxyPass "/wss/homews/" "ws://api.domain.com:8888/"

        <Directory /var/www/api.domain.com>
                Options FollowSymLinks
                AllowOverride All
                Order allow,deny
                Allow from all
                Satisfy all
        </Directory>
</VirtualHost>

Затем я вызываю свой php-скрипт с таким пониманием кода, которое запускает сервер веб-сокетов Ratchet:

// ...
// Some code ...
$app = new Ratchet\App('localhost', 8888);
$app->route('/wss/homews/', $myClass, array('*'));
$app->run();

Затемкогда я пытаюсь подключиться к нему на стороне клиента javascript с помощью URL ws://api.domain.com:8888/wss/homews/, я всегда получаю Error in connection establishment: net::ERR_CONNECTION_TIMED_OUT.

У вас есть какие-либо идеи, как я мог бы отладить этот тип ошибки? Есть ли какие-либо журналы на Apache, показывающие неверную конфигурацию?

Ответы [ 2 ]

1 голос
/ 03 ноября 2019

Ваша конфигурация должна быть изменена, по крайней мере, на:

<VirtualHost *:80>
        ServerAdmin admin@admin.admin
        DocumentRoot /var/www/api.domain.com
        ServerName api.domain.com

        # Enable Websocket connections on port 8888
        ProxyPass "/wss/homews/" "ws://localhost:8888/wss/homews/"

        <Directory /var/www/api.domain.com>
                Options FollowSymLinks
                AllowOverride All
                Order allow,deny
                Allow from all
                Satisfy all
        </Directory>
</VirtualHost>

И на стороне клиента javascript на URL ws://api.domain.com:80/wss/homews/.

В противном случае, возможно (или, допустим, мы надеемся, для настройки сервера), цель из конфигурации веб-сервера api.domain.com:8888 пытается достичь восходящей веб-сокета по общедоступному IP-адресу сервера, пока веб-сокет привязан к локальному хосту. Восемь раз он просто не слушает (что хорошо, так как обычно вы просто хотите открывать порты своих веб-серверов для общего доступа, а не непосредственно для портов своего приложения), или, что еще хуже, он пытается достичь общедоступного IP-адреса NAT, который включает в себя переход к брандмауэру, гдепорт 8888 должен быть заблокирован, что может не допустить этого, может быть дорогим (например, AWS EC2) и по крайней мере неэффективным.

С другой стороны, вы захотите направить код клиента на веб-сервер через порт 80, который выполняет туннелирование к вашему приложению websocket, чтобы ваш клиент не мог напрямую получить доступ к порту 8888 вашего сервера (он заблокирован в общедоступном брандмауэре). надеюсь - и вы слушаете только на localhost).

Попробуйте выполнить исходную настройку и расскажите, как изменились результаты. Возможно, возникла дополнительная проблема (но Вы не должны больше получать время ожидания сокета и соединение клиента с приложением websocket).

1 голос
/ 02 ноября 2019

Прежде всего, попробуйте упростить вещи, НЕ редактировать и не трогать какие-либо файлы конфигурации с сервера, оставить его по умолчанию, как есть, что будет делать

Я опубликую все меры предосторожностиДля того, чтобы настроить и запустить сокет, выполните следующие действия:

  1. Проверьте, поддерживает ли ваш сервер веб-сокет на виртуальном хостинге, в противном случае вам может понадобитьсяперейти на выделенный хостинг или виртуальный частный сервер (VPS), например: AWS, GCP. Если ваш сервер поддерживает запуск сценариев веб-службы, таких как phpwebsocket, внутри веб-службы, выполните следующие действия

  2. На терминале обновите композитор до последней версии, а затем попробуйте выполнить $composer require cboden/ratchet Так что требуемая зависимость будет загружаться эффективно и не пытаться загружать какие-либо заархивированные зависимости. В моем случае "cboden/ratchet": "^0.4.3" был загружен на localhost, но на производственном сайте он был "cboden/ratchet": "^0.4.1" при сравнении как из composer.json файла

  3. Попробуйте подключиться к порту 8282, ВВ большинстве случаев трафик сервера, как от входящего, так и от исходящего, остается открытым по умолчанию, в случае, если порт 8080 не может привязаться к TCP

  4. Наконец, попробуйтеперезагрузите свой экземпляр сервера, размещенного в облаке, и выполните сценарий websocket $php <yourWebSocketScript.php>

Я использовал mod_proxy_wstunnel, чтобы убедиться, что связь зашифрована, кроме этого, я смогбез проблем запустите Websocket socketo.me на AWS и на нашем частном выделенном сервере

Спасибо за обращение, я ценю ваши усилия, кроме вашего заинтересованного комментария, чтобы ответить через johannchopin @ protonmaildotcom, это не моя частьделовой этики


Редактировать

$app = new Ratchet\App('localhost', 8888);
$app->route('/wss/homews/', $myClass, array('*'));
$app->run();

Попробуйте изменить назначенное вручную localhost с вашего <yourWebSocketScript.php> из приведенного выше фрагмента на

$app = IoServer::factory(
    new HttpServer(new WsServer(new Chat())),
    8282
);
$app->run();

Попробуйте связать с HttpServer, по умолчанию это localhost или 0.0.0.0 и запустите (при необходимости исключите $app->route())

В вашем коде вам нужно изменить

  1. Номер порта в yourWebSocketScript.php

  2. Изменение с localhost на IP-адрес сервера или DNS в someChatFilexyz.php

    Eg:
    let websocket_server = new WebSocket("ws://my.domain.com:8282");
    or
    let websocket_server = new WebSocket("ws://xxx.xxx.xxx.xxx:8282");
Убить все ранее установленные сокеты, относящиеся к порту 8282, а затем запустить yourWebSocketScript.php

Вот частичный код someChatFilexyz.php

jQuery(function($){
// Websocket_Controller
var websocket_server = new WebSocket("ws://xxx.xxx.xxx.xxx:8282");
websocket_server.onopen = function(e) {
websocket_server.send(
...
);
};

websocket_server.onerror = function(e) {
// Errorhandling
...
}

websocket_server.onmessage = function(e) {

...
}
}

Настройка вышеКонфигурацию я смог запустить на веб-службе Amazon с настроенным мной стеком LAMP и с частным выделенным сервером с легкостью.

Примечание. При любых незначительных изменениях в коде необходимо перезапустить работающий скрипт websocket $php <yourWebSocketScript.php> т. Е. Либо путем завершения запущенного процесса, либо уничтожения процесса, определенного для назначенного номера порта

...