Ratchet: WSS Websocket not working in HTTPS

Created on 29 Dec 2017  路  6Comments  路  Source: ratchetphp/Ratchet

I have a ratchet chat server file

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

using Websocket to connect with ws and it works fine

if ("WebSocket" in window) {
    var ws = new WebSocket("ws://testing.domain.com:8081");
    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.
}

I want secure connection, so I try to connect with SSL but is not work.

if ("WebSocket" in window) {
    var ws = new WebSocket("wss://testing.domain.com:8081");
    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.
}

My question is how to connect websocket with SSL connection

Any idea?

Most helpful comment

Change in class "Ratchet\Server\IoServer" method "factory". Or create yourself clas, extends "Ratchet\Server\IoServer" and method "factory".
My example:
`
use Ratchet\Server\IoServer;
use Ratchet\MessageComponentInterface;
use React\EventLoop\LoopInterface;
use React\Socket\ServerInterface;
use React\EventLoop\Factory as LoopFactory;
use React\Socket\Server as Reactor;
use React\Socket\SecureServer as SecureReactor;

class IoSecureServer extends IoServer
{
public static function factory(MessageComponentInterface $component, $port = 80, $address = '0.0.0.0', $secureOptions = []) {
$loop = LoopFactory::create();
$socket = new Reactor($address . ':' . $port, $loop);

    if (!empty($secureOptions) && is_array($secureOptions)) {
        $socket = new SecureReactor($socket, $loop, $secureOptions);
    }

    return new static($component, $socket, $loop);
}

}
$secureOptions is array and looks as : [
'local_cert' => 'path to file',
'local_pk' => 'path to file',
'allow_self_signed' => true,
'verify_peer' => false
]`
or other parameters http://php.net/manual/en/context.ssl.php

All 6 comments

Change in class "Ratchet\Server\IoServer" method "factory". Or create yourself clas, extends "Ratchet\Server\IoServer" and method "factory".
My example:
`
use Ratchet\Server\IoServer;
use Ratchet\MessageComponentInterface;
use React\EventLoop\LoopInterface;
use React\Socket\ServerInterface;
use React\EventLoop\Factory as LoopFactory;
use React\Socket\Server as Reactor;
use React\Socket\SecureServer as SecureReactor;

class IoSecureServer extends IoServer
{
public static function factory(MessageComponentInterface $component, $port = 80, $address = '0.0.0.0', $secureOptions = []) {
$loop = LoopFactory::create();
$socket = new Reactor($address . ':' . $port, $loop);

    if (!empty($secureOptions) && is_array($secureOptions)) {
        $socket = new SecureReactor($socket, $loop, $secureOptions);
    }

    return new static($component, $socket, $loop);
}

}
$secureOptions is array and looks as : [
'local_cert' => 'path to file',
'local_pk' => 'path to file',
'allow_self_signed' => true,
'verify_peer' => false
]`
or other parameters http://php.net/manual/en/context.ssl.php

Hi, on my laravel webapp, the https socket does not work, do you know which certificates I need to pass to the array? those that I received from digicert? I tried to pass them but it still does not work, after I changed the "factory" method ..

Closed for inactivity.

if you are using laravel library cboden/ratchet for socket then go to app/Console/Commands/WebSocketServer.php Replace handle function with these lines of code and use your certification file path 'local_cert' and 'local_pk'

public function handle()
{

    $loop   = Factory::create();
    $webSock = new SecureServer(
        new Server('0.0.0.0:8090', $loop),
        $loop,
        array(
            'local_cert'        => '/opt/ssl/chamberstock_com.crt', // path to your cert
            'local_pk'          => '/opt/ssl/server.key', // path to your server private key
            'allow_self_signed' => TRUE, // Allow self signed certs (should be false in production)
            'verify_peer' => FALSE
        )
    );
    // Ratchet magic
    $webServer = new IoServer(
        new HttpServer(
            new WsServer(
                new WebSocketController()
            )
        ),
        $webSock
    );
    $loop->run();

}

Hello there, I guess i am late posting this one, but I have here a working example with routing also. the code is working well as per the latest ratchet version.

<?php
use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;
require __DIR__ . '/vendor/autoload.php';

use Ratchet\Server\IoServer;
use Ratchet\Http\HttpServer;
use Ratchet\WebSocket\WsServer;
use Psr\Http\Message\RequestInterface;
use Ratchet\Http\Router;
use Ratchet\Http\HttpServerInterface;
use Symfony\Component\Routing\RequestContext;
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Route;
use Symfony\Component\Routing\Matcher\UrlMatcher;
use Symfony\Component\HttpFoundation\Request;

$routes = new RouteCollection;
$loop = React\EventLoop\Factory::create();

$decorated = new WsServer(new ChatRoom);
$decorated->enableKeepAlive($loop);
$routes->add('chat-room', new Route('/chat-room', array('_controller' => $decorated), array('Origin' => $GLOBALS['Address']), 
    array(), $GLOBALS['Address'], array(), array('GET')));

$decorated = new WsServer(new SingleChat);
$decorated->enableKeepAlive($loop);
$routes->add('single-chat', new Route('/single-chat', array('_controller' => $decorated), array('Origin' => $GLOBALS['Address']), 
    array(), $GLOBALS['Address'], array(), array('GET')));

$decorated = new WsServer(new Ratchet\Server\EchoServer);
$decorated->enableKeepAlive($loop);
$routes->add('echo', new Route('/echo', array('_controller' => $decorated), array('Origin' => $GLOBALS['Address']), 
    array(), $GLOBALS['Address'], array(), array('GET')));


$app = new HttpServer(new Router(new UrlMatcher($routes, new RequestContext)));

$secure_websockets = new \React\Socket\Server('0.0.0.0:8091', $loop);
$secure_websockets = new \React\Socket\SecureServer($secure_websockets, $loop, [
    'local_cert' => 'path/to/certificate.crt',
    'local_pk' => '/path/to/your-key.key',
    'verify_peer' => false
]);

$secure_websockets_server = new \Ratchet\Server\IoServer($app, $secure_websockets, $loop);
$secure_websockets_server->run();

Regards

if you are using laravel library cboden/ratchet for socket then go to app/Console/Commands/WebSocketServer.php Replace handle function with these lines of code and use your certification file path 'local_cert' and 'local_pk'

public function handle()
{

    $loop   = Factory::create();
    $webSock = new SecureServer(
        new Server('0.0.0.0:8090', $loop),
        $loop,
        array(
            'local_cert'        => '/opt/ssl/chamberstock_com.crt', // path to your cert
            'local_pk'          => '/opt/ssl/server.key', // path to your server private key
            'allow_self_signed' => TRUE, // Allow self signed certs (should be false in production)
            'verify_peer' => FALSE
        )
    );
    // Ratchet magic
    $webServer = new IoServer(
        new HttpServer(
            new WsServer(
                new WebSocketController()
            )
        ),
        $webSock
    );
    $loop->run();

}

Can you please mention where to place the .crt and .key file on cPanel, as my hosting i shared so they asked me to copy the content from SS/TLS from cpanel and create .key and crt file to place in cpanel then access it. so plz let me know where can i place the files, right now i have placed the files in the public_html and outside of the public_html directory and its not working. can you guide me. thnx.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

nazar-pc picture nazar-pc  路  8Comments

piotrchludzinski picture piotrchludzinski  路  5Comments

harveyslash picture harveyslash  路  6Comments

sebinator picture sebinator  路  9Comments

tasaif picture tasaif  路  6Comments