Reputation: 1496
Been researching the issue with Ratchet over SSL and have been trying to get my Apache2 server configuration working by enabling proxy.load and proxy_wstunnel.load mods.
/etc/apache2/mods-enabled:
proxy.conf -> ../mods-available/proxy.conf
proxy.load -> ../mods-available/proxy.load
proxy_wstunnel.load -> ../mods-available/proxy_wstunnel.load
I've added the following line to the end of my apache2.conf:
ProxyPass /wss2/ ws://domain.com:8080
The PHP socket-server.php file:
use Ratchet\Server\IoServer;
use Ratchet\Http\HttpServer;
use Ratchet\WebSocket\WsServer;
use Websocket\SocketControl;
use Ratchet\Session\SessionProvider;
use Symfony\Component\HttpFoundation\Session\Storage\Handler;
require dirname(__DIR__) . '/vendor/autoload.php';
$memcache = new Memcache;
$memcache->connect('localhost', 11211);
$session = new SessionProvider(
new SocketControl,
new Handler\MemcacheSessionHandler($memcache)
);
$server = IoServer::factory(
new HttpServer(
new WsServer(
$session
)
),
8080
);
$server->run();
The relevant JS code that attempts to connect to the socket server:
var websocket = {
wsUri:"wss://domain.com/wss2/NNN",
socket:null,
cryptKey:null,
init:function(){
try {
if (typeof MozWebSocket == "function")
WebSocket = MozWebSocket;
if ( websocket.socket && websocket.socket.readyState == 1 )
websocket.socket.close();
websocket.socket = new WebSocket( websocket.wsUri );
websocket.socket.onopen = websocket.onopen.bind();
websocket.socket.onclose = websocket.onclose.bind();
websocket.socket.onmessage = websocket.onmessage.bind();
websocket.socket.onerror = websocket.onerror.bind();
} catch (exception) {
console.log("ERROR: " + exception);
}
},
The error I receive when attempting to connect:
WebSocket connection to 'wss://domain.com/wss2/NNN' failed: Error during WebSocket handshake: Unexpected response code: 502
Upvotes: 0
Views: 1897
Reputation: 21
I had been looking for a secure websocket application myself as well... Perhaps a cleaner setup. No need to proxy. Here's what I figured out:
<?php
require __DIR__ . '/vendor/autoload.php';
// SSL configuration
$context = array(
'tls' => array(
'local_cert' => "-path-to-ssl-certificate.crt",
'local_pk' => "-path-to-ssl-privatekeyfile.key",
'allow_self_signed' => true, // Set to false in production
'verify_peer' => false
)
);
// Set up websocket server
$loop = React\EventLoop\Factory::create();
$application = new Ratchet\App('your.domain.com', 8443, 'tls://0.0.0.0', $loop, $context);
// Set up controller component (instance of MessageComponentInterface or WsMessageComponentInterface)
$controller = new MyControllerObject();
$application->route('/any_desired_path', $controller, array('*'));
$application->run();
die('-server stopped-');
Now you can set up your client secure websocket connection, and get your application running!
var conn = new WebSocket('wss:your.domain.com:8443/any_desired_path');
Note: the SSL setup can be hard, as no error messages appear e.g. when the crt or key file are missing, or the allow_self_signed/verify_peer values are non-boolean. The client simply closes the connection, or is unable to connect.
Upvotes: 1
Reputation: 11
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
Upvotes: 1
Reputation: 800
The problem is in the URL you are using:
wsUri:"wss://domain.com/wss2/NNN",
you could try:
wsUri:"wss://domain.com/wss2",
since you link to that URL in your config
Upvotes: 0