whatsmyname Posted November 8, 2019 Share Posted November 8, 2019 (edited) I've finally got the time to learn web sockets and have choosen to use: http://socketo.me/docs/push to do so. It all works perfectly fine without SSL. The moment it's enabled the client javascript will not connect and will output "WebSocket opening handshake timed out". I've tried the server with and without the TLS options. client.html, post.php, server.php <script type="text/javascript" src="autobahn.js"></script> <script> var conn = new ab.Session('wss://domain.com:8443', function() { console.log('Connected'); conn.subscribe('kittensCategory', function(topic, data) { // This is where you would add the new article to the DOM (beyond the scope of this tutorial) console.log('New article published to category "' + topic + '" : ' + data.title); }); }, function() { console.warn('WebSocket connection closed'); }, {'skipSubprotocolCheck': true} ); </script> <?php require dirname(__DIR__) . '/socket/vendor/autoload.php'; // post.php ??? // This all was here before ;) $entryData = array( 'category' => 'kittensCategory' , 'title' => 'My Impressive Title' , 'article' => 'Just me the best, nothing new!' , 'when' => time() ); // This is our new stuff $context = new ZMQContext(); $socket = $context->getSocket(ZMQ::SOCKET_PUSH, 'my pusher'); $socket->connect("tcp://localhost:5555"); $socket->send(json_encode($entryData)); echo 'All Sent!'; <?php require dirname(__DIR__) . '/socket/vendor/autoload.php'; use Ratchet\ConnectionInterface; use Ratchet\Wamp\WampServerInterface; class Pusher implements WampServerInterface { /** * A lookup of all the topics clients have subscribed to */ protected $subscribedTopics = array(); public function onSubscribe(ConnectionInterface $conn, $topic) { echo 'Subbed'; $this->subscribedTopics[$topic->getId()] = $topic; } /** * @param string JSON'ified string we'll receive from ZeroMQ */ public function onBlogEntry($entry) { echo 'Hello!'; $entryData = json_decode($entry, true); // If the lookup topic object isn't set there is no one to publish to if (!array_key_exists($entryData['category'], $this->subscribedTopics)) { return; } $topic = $this->subscribedTopics[$entryData['category']]; // re-send the data to all the clients subscribed to that category $topic->broadcast($entryData); } /* The rest of our methods were as they were, omitted from docs to save space */ //public function onSubscribe(ConnectionInterface $conn, $topic) { // } public function onUnSubscribe(ConnectionInterface $conn, $topic) { } public function onOpen(ConnectionInterface $conn) { } public function onClose(ConnectionInterface $conn) { } public function onCall(ConnectionInterface $conn, $id, $topic, array $params) { // In this application if clients send data it's because the user hacked around in console $conn->callError($id, $topic, 'You are not allowed to make calls')->close(); } public function onPublish(ConnectionInterface $conn, $topic, $event, array $exclude, array $eligible) { // In this application if clients send data it's because the user hacked around in console $conn->close(); } public function onError(ConnectionInterface $conn, \Exception $e) { } } $loop = React\EventLoop\Factory::create(); $pusher = new Pusher; // Listen for the web server to make a ZeroMQ push after an ajax request $context = new React\ZMQ\Context($loop); $pull = $context->getSocket(ZMQ::SOCKET_PULL); $pull->bind('tcp://127.0.0.1:5555'); // Binding to 127.0.0.1 means the only client that can connect is itself $pull->on('message', array($pusher, 'onBlogEntry')); // Set up our WebSocket server for clients wanting real-time updates $webSock = new React\Socket\Server('0.0.0.0:8443', $loop, array( 'tls' => array( 'local_cert' => 'cert.pem', 'local_pk' => 'private.key', // path to your server private key, 'verify_peer' => FALSE ))); // Binding to 0.0.0.0 means remotes can connect $webServer = new Ratchet\Server\IoServer( new Ratchet\Http\HttpServer( new Ratchet\WebSocket\WsServer( new Ratchet\Wamp\WampServer( $pusher ) ) ), $webSock ); $loop->run(); Edited November 8, 2019 by whatsmyname Quote Link to comment Share on other sites More sharing options...
requinix Posted November 8, 2019 Share Posted November 8, 2019 Do you have a WebSocket-enabled server ready on port 8443? Quote Link to comment Share on other sites More sharing options...
whatsmyname Posted November 8, 2019 Author Share Posted November 8, 2019 2 hours ago, requinix said: Do you have a WebSocket-enabled server ready on port 8443? Hello. Yes, the server is started via command line e.g. 'php server.php' The server is working as 'post.php' is sending messages but the client.html JavaScript is not. Quote Link to comment Share on other sites More sharing options...
requinix Posted November 8, 2019 Share Posted November 8, 2019 3 minutes ago, whatsmyname said: The server is working as 'post.php' is sending messages but the client.html JavaScript is not. I may be misreading, but isn't post.php is connecting to port 5555? And over TCP without the SSL layer? Quote Link to comment Share on other sites More sharing options...
whatsmyname Posted November 8, 2019 Author Share Posted November 8, 2019 Your not misreading it indeed is. I'm using a library called ZMQ which posts to the server side ZMQ this then sends the data to the actual socket server. It allows for things like subscribe to notifications. If you stripped all this back and used the most basic "Hello World" located here "http://socketo.me/docs/hello-world" - This is what it looks like without ZMQ. This also does not like to run over TLS/SSL. My scripts above are from here: "http://socketo.me/docs/push" I'm so stumbled right now, I really am. "WebSocket opening handshake timed out" I've even posted on stack overflow: https://stackoverflow.com/questions/58762640/websockets-will-not-work-over-tls-ssl-but-will-work-without Quote Link to comment Share on other sites More sharing options...
whatsmyname Posted November 8, 2019 Author Share Posted November 8, 2019 Sorry, just to touch up. The client.html is the issue. Quote Link to comment Share on other sites More sharing options...
requinix Posted November 8, 2019 Share Posted November 8, 2019 Are you running all this on your local server, or is any part of it deployed remotely? Quote Link to comment Share on other sites More sharing options...
whatsmyname Posted November 8, 2019 Author Share Posted November 8, 2019 I've ran this on XAMPP locally and on Centos 7 remotely deployed both of which the javascript will timeout on handshake. The remote has a valid SSL certificate and domain name. I've also gone as far as disabling the firewall to make sure this was not an issue. I take it you have experience in websockets? Quote Link to comment Share on other sites More sharing options...
requinix Posted November 8, 2019 Share Posted November 8, 2019 For the most part. The timeout is happening for one of two reasons: it can't connect at all, or it can connect but the server was there but somehow able to complete the handshake. The latter is unlikely. - Can you manually telnet to the port? To test whether you can connect at all. Run post.php and confirm the server received the message, telnet, and run post.php again. - What does the browser show for the WSS connection in its networking request monitoring thing? Quote Link to comment Share on other sites More sharing options...
whatsmyname Posted November 8, 2019 Author Share Posted November 8, 2019 Thanks for sticking around @requinix Running post.php does trigger (onBlogEntry) which outputs "Hello!" Tried to telnet into the remote deployed version and telnet outputted "Connecting To host...Could not open connection to the host, on port x.x.x.x:8443: Connect failed" I then tried it locally (Windows): Connecting To host...Could not open connection to the host, on port 127.0.0.1:8443: Connect failed I then tried to telnet into their basic hello world example as follows: Connecting To host...Could not open connection to the host, on port 127.0.0.1:8080: Connect failed. Just to confirm, both servers was running at the time of telnet and the firewall was disabled. <?php require dirname(__DIR__) . '/socket/vendor/autoload.php'; 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(); } } use Ratchet\Server\IoServer; use Ratchet\Http\HttpServer; use Ratchet\WebSocket\WsServer; $server = IoServer::factory( new HttpServer( new WsServer( new Chat() ) ), 8080 ); $server->run(); Quote Link to comment Share on other sites More sharing options...
whatsmyname Posted November 8, 2019 Author Share Posted November 8, 2019 The browser shows "pending" at which point eventually times out with "WebSocket opening handshake timed out" Quote Link to comment Share on other sites More sharing options...
requinix Posted November 8, 2019 Share Posted November 8, 2019 Have you tried running post.php twice? Does the second time work? If you restart the server and then don't do anything else, can you connect with telnet then? Quote Link to comment Share on other sites More sharing options...
whatsmyname Posted November 8, 2019 Author Share Posted November 8, 2019 Just a quick update! telnet is working and does connect to both deployment and local. - I didn't write the host name and port correctly. HOWEVER both of which eventually times out also: HTTP/1.1 500 Internal Server Error X-Powered-By: Ratchet/0.4.1 Connection to host lost. - Will check logs now. Quote Link to comment Share on other sites More sharing options...
whatsmyname Posted November 8, 2019 Author Share Posted November 8, 2019 Nothing in logs. Literally nothing. Quote Link to comment Share on other sites More sharing options...
whatsmyname Posted November 8, 2019 Author Share Posted November 8, 2019 On the deployment server Centos 7, telnet connects "Connected to 127.0.0.1" Quote Link to comment Share on other sites More sharing options...
whatsmyname Posted November 8, 2019 Author Share Posted November 8, 2019 As soon as anything is posted: HTTP/1.1 500 Internal Server Error X-Powered-By: Ratchet/0.4.1 Quote Link to comment Share on other sites More sharing options...
requinix Posted November 8, 2019 Share Posted November 8, 2019 Make sure you have something set up to handle errors on the server side of things. Like your Pusher::onError is empty. Quote Link to comment Share on other sites More sharing options...
whatsmyname Posted November 8, 2019 Author Share Posted November 8, 2019 Yup, echoed out any messages on the deployed version. I have nothing. https://github.com/ratchetphp/Ratchet/issues/764 Quote Link to comment Share on other sites More sharing options...
whatsmyname Posted November 9, 2019 Author Share Posted November 9, 2019 (edited) SOLUTION: In order for the client to work over SSL you need to set the server certificate and private key and start a secure server as follows. Quote $loop = React\EventLoop\Factory::create(); $pusher = new MyApp\Pusher; // Listen for the web server to make a ZeroMQ push after an ajax request $context = new React\ZMQ\Context($loop); $pull = $context->getSocket(ZMQ::SOCKET_PULL); $pull->bind('tcp://127.0.0.1:5555'); // Binding to 127.0.0.1 means the only client that can connect is itself $pull->on('message', [$pusher, 'onUpdate']); // Set up our WebSocket server for clients wanting real-time updates $webSock = new React\Socket\Server('0.0.0.0:8443', $loop); $webSock = new React\Socket\SecureServer($webSock, $loop, [ 'local_cert' => 'C:/xampp/apache/conf/ssl.crt/server.crt', // path to your cert 'local_pk' => 'C:/xampp/apache/conf/ssl.key/server.key', // path to your server private key 'allow_self_signed' => TRUE, // Allow self signed certs (should be false in production) 'verify_peer' => FALSE ]); //$webSock->listen(8443, '0.0.0.0'); // Binding to 0.0.0.0 means remotes can connect $webServer = new Ratchet\Server\IoServer( new Ratchet\Http\HttpServer( new Ratchet\WebSocket\WsServer( new Ratchet\Wamp\WampServer( $pusher ) ) ), $webSock ); $loop->run(); Please see here:https://github.com/ratchetphp/Ratchet/issues/609#issuecomment-363743604 Edited November 9, 2019 by whatsmyname 1 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.