D
D
Dmitry Tarasov2020-01-11 20:15:29
PHP
Dmitry Tarasov, 2020-01-11 20:15:29

How to create a websocket ratchet connection with SSL NGINX?

I'm trying to make real time notifications on a website using ratchet lib .
Structure
5e19ff9ea5fae410550691.png
File 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();

File 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();
    }
}

Next, I ran the chat-server.php script, it started without errors.
I'm trying to connect on a client.
var conn = new WebSocket('ws://site.com:8777');
conn.onopen = function(e) {
console.log("Connection established!");
};
conn.onmessage = function(e) {
console.log(e.data);
};
give the error
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.
My site works on https and it just blocks the connection, the server itself started normally, as I understand it, you need to use 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:
Krch, I can’t connect at all, I googled, they say it’s necessary to do proxying through nginx.
I also thought maybe I'm just making the wrong connection, maybe I need to make a secure connection when creating the chat-server.php server.
In general, I understand how to solve the problem. If nginx is proxying, then how, my whole site works on https.
Thank you very much in advance.

Answer the question

In order to leave comments, you need to log in

1 answer(s)
V
vreitech, 2020-01-11
@fzfx

use wss in .js - do not forget to make sure that the php server also listens to this case as wss, not ws:
- or in the appropriate way (see the ratchet doc) create the socket in the code;
- either proxy through nginx like this (then there https://site.com/will be a site, there wss://site.com/websocketwill be a 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;
        }
}

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question