Ratchet: Unable to run WebSocket and HTTP Server on same port

Created on 28 Dec 2019  路  8Comments  路  Source: ratchetphp/Ratchet

I've the following code:

use Ratchet\Http\HttpServer;
use Ratchet\WebSocket\WsServer;

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

$socketServer = new \React\Socket\Server('127.0.0.1:8080', $loop);

$httpServer = new \React\Http\Server(function(\Psr\Http\Message\ServerRequestInterface $request) {
  return new \React\Http\Response(200, [
      'Content-Type' => 'text/plain'
    ],
    'Hello, World'
  );
});

$httpServer->listen($socketServer);

$rrServer = new RRServer(); // Implements MessageComponentInterface

$webSocketServer = new IoServer(
  new HttpServer(
    new WsServer(
      $rrServer
    )
  ),
  $socketServer,
  $loop
);

$webSocketServer->run();

The code works, but I'm only able to access it using http://localhost:8080, and when I try to connect using WebSocket, the connection is opened, and then it immediately closes. Also, When I create a new socket with different port then I'm able to access both using http:// and ws://

Is it possible to run HTTP Server and WebSockets on the same port, and if yes, how to implement it?

Thanks.

question

All 8 comments

You can not host two different applications on the same port. This is an operating system level restriction. I would recommend continuing to run your WebSocket server on 127.0.0.1:8080 which restricts connections on that server to connect then proxy all incoming port 80 connections through your web server, such as Nginx, and redirect traffic based on HTTP headers, route, or sub-domain.

@cboden There is no way we can run WebSocket and HTTP Server on same port using ReactPHP and Ratchet??

If they're both run by the same EventLoop that would be possible.

I've used the same EventLoop in my code but still it is not working.

Can you please provide me a solution for this?

Thanks in advance.

Your code is trying to attach two SocketServer's to the same port. You need to attach a single SocketServer to one port, then re-route traffic based on a condition of your choosing (HTTP header, endpoint, or sub-domain for example).

See Ratchet's App class or some of React's examples for some inspiration.

I'm unable to handle WebSocket and HTTP requests on one socket so I ended up creating two sockets running on different ports as the temporary solution.

<?php

use Ratchet\Http\HttpServer;
use Ratchet\WebSocket\WsServer;

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

$webSocketServer = new \React\Socket\Server('127.0.0.1:8080', $loop);
$httpSocketServer = new \React\Socket\Server('127.0.0.1:8081', $loop);

$httpServer = new \React\Http\Server(function(\Psr\Http\Message\ServerRequestInterface $request) {
  return new \React\Http\Response(200, [
      'Content-Type' => 'text/plain'
    ],
    'Hello, World'
  );
});

$httpServer->listen($httpSocketServer);

$rrServer = new RRServer(); // Implements MessageComponentInterface

$webSocketServer = new IoServer(
  new HttpServer(
    new WsServer(
      $rrServer
    )
  ),
  $webSocketServer,
  $loop
);

$loop->run();

Was this page helpful?
0 / 5 - 0 ratings

Related issues

harveyslash picture harveyslash  路  6Comments

Hemant3105 picture Hemant3105  路  6Comments

nazar-pc picture nazar-pc  路  8Comments

clarkk picture clarkk  路  6Comments

Erseni picture Erseni  路  5Comments