fast-je
@fast-je
Пишу на php.

Как создать подключение через websocket ratchet с SSL NGINX?

Я пытаюсь сделать реал тайм нотификации на сайте с помощью либы ratchet.
Структура
5e19ff9ea5fae410550691.png
Файл chat-server.php
<?php
require dirname(__DIR__) . '/vendor/autoload.php';

use Ratchet\Server\IoServer;
use Ratchet\Http\HttpServer;
use Ratchet\WebSocket\WsServer;
use React\EventLoop\Factory;
use React\Socket\SecureServer;
use React\Socket\Server;
use MyApp\Chat;


$server = IoServer::factory(
    new HttpServer(
        new WsServer(
            new Chat()
        )
    ),
    8777
);

$server->run();


Файл Chat.php

<?php
namespace MyApp;
use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;

class Chat implements MessageComponentInterface {
    protected $clients;

    public function __construct() {
        $this->clients = new \SplObjectStorage;
    }

    public function onOpen(ConnectionInterface $conn) {
        // Store the new connection to send messages to later
        $this->clients->attach($conn);

        echo "New connection! ({$conn->resourceId})\n";
    }

    public function onMessage(ConnectionInterface $from, $msg) {
        $numRecv = count($this->clients) - 1;
        echo sprintf('Connection %d sending message "%s" to %d other connection%s' . "\n"
            , $from->resourceId, $msg, $numRecv, $numRecv == 1 ? '' : 's');

        foreach ($this->clients as $client) {
            if ($from !== $client) {
                // The sender is not the receiver, send to each client connected
                $client->send($msg);
            }
        }
    }

    public function onClose(ConnectionInterface $conn) {
        // The connection is closed, remove it, as we can no longer send it messages
        $this->clients->detach($conn);

        echo "Connection {$conn->resourceId} has disconnected\n";
    }

    public function onError(ConnectionInterface $conn, \Exception $e) {
        echo "An error has occurred: {$e->getMessage()}\n";

        $conn->close();
    }
}


Далее я запустил скрипт chat-server.php, запустился без ошибок.
Пытаюсь подключиться на клиенте.

var conn = new WebSocket('ws://site.com:8777');
conn.onopen = function(e) {
console.log("Connection established!");
};

conn.onmessage = function(e) {
console.log(e.data);
};

выдают ошибку

VM862:1 Mixed Content: The page at 'https://site.com/' was loaded over HTTPS, but attempted to connect to the insecure WebSocket endpoint 'ws://site.com:8777/'. This request has been blocked; this endpoint must be available over WSS.
(anonymous) @ VM862:1
VM862:1 Uncaught DOMException: Failed to construct 'WebSocket': An insecure WebSocket connection may not be initiated from a page loaded over HTTPS.

У меня сайт работает на https и он просто блокирует подключение, сам сервер стартовал нормально, я так понял надо юзать wss

var conn = new WebSocket('wss://site.com:8777');
conn.onopen = function(e) {
console.log("Connection established!");
};

conn.onmessage = function(e) {
console.log(e.data);
};
ƒ (e) {
console.log(e.data);
}
conn.send('Hello World!');
VM891:1 Uncaught DOMException: Failed to execute 'send' on 'WebSocket': Still in CONNECTING state.
at :1:6

получаю такую ошибку.

Крч, не получается вообще никак подключится, гуглил, говорят надо через nginx делал проксирование.
Также подумал может я просто неверное подключение делаю может нужно безопасное подключение делать при создании сервера chat-server.php

Вообщем вообще по пойму как решить проблему. Если nginx проксирование, то как, у меня весь сайт работает на https.
Заранее всем очень благодарен.
  • Вопрос задан
  • 2003 просмотра
Пригласить эксперта
Ответы на вопрос 1
fzfx
@fzfx
18,5 дм
юзаете wss в .js - не забудьте озаботиться тем, чтобы php-сервер тоже слушал это дело как wss, а не ws:
- либо соответствующим (см. доку по ratchet) образом создавайте сокет в коде;
- либо проксируйте через nginx примерно следующим образом (тогда на https://site.com/ будет сайт, на wss://site.com/websocket будет вебсокет):

server {
        listen 443 ssl;
        listen [::]:443 ssl;

        server_name site.com;

        ssl_certificate /var/lib/dehydrated/certs/site.com/fullchain.pem;
        ssl_certificate_key /var/lib/dehydrated/certs/site.com/privkey.pem;

        location /websocket {
                proxy_pass                              http://127.0.0.1:8777;
                proxy_pass_header                       Server;
                proxy_http_version                      1.1;
                proxy_set_header Upgrade                $http_upgrade;
                proxy_set_header Connection             "upgrade";
                proxy_read_timeout                      86400;
                proxy_set_header Host                   $host;
                proxy_set_header X-Forwarded-For        $proxy_add_x_forwarded_for;
                proxy_set_header X-Real-IP              $remote_addr;
        }

        location / {
                proxy_pass                              http://127.0.0.1:80;
                proxy_pass_header                       Server;
                proxy_set_header Host                   $host;
                proxy_set_header X-Forwarded-For        $proxy_add_x_forwarded_for;
                proxy_set_header X-Real-IP              $remote_addr;
        }
}
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы