Skip to content

Instantly share code, notes, and snippets.

@Milek7
Created April 8, 2019 19:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Milek7/b921ec9f8d875fe2d5a8b06bfd533834 to your computer and use it in GitHub Desktop.
Save Milek7/b921ec9f8d875fe2d5a8b06bfd533834 to your computer and use it in GitHub Desktop.
<?php
require __DIR__ . '/vendor/autoload.php';
use Ratchet\Http\HttpServer;
use Ratchet\Server\IoServer;
use Ratchet\ConnectionInterface;
use Ratchet\WebSocket\WsServer;
class ConnInfo {
public $inited = false;
public $udp_client;
public $tcp_client;
public $tcp_buf;
}
class WsInterface implements \Ratchet\WebSocket\MessageComponentInterface, \Ratchet\WebSocket\WsServerInterface {
private $udp_factory;
private $tcp_factory;
private $clients;
private $target;
public function __construct(\React\Datagram\Factory $udp_factory, \React\Socket\ConnectorInterface $tcp_factory, $target) {
$this->udp_factory = $udp_factory;
$this->tcp_factory = $tcp_factory;
$this->target = $target;
$this->clients = new \SplObjectStorage();
}
public function onOpen(ConnectionInterface $conn) {
$this->clients->attach($conn, new ConnInfo());
}
public function onMessage(ConnectionInterface $from, \Ratchet\RFC6455\Messaging\MessageInterface $msg) {
$info = $this->clients->offsetGet($from);
$payload = $msg->getPayload();
if (!$info->inited) {
echo "connected\n";
if ($msg->getPayloadLength() == 10 && $payload[0] == "\xff") {
$this->udp_factory->createClient($this->target)->then(function (React\Datagram\Socket $client) use ($info, $from) {
$info->udp_client = $client;
$client->on('message', function($message, $serverAddress, $client) use ($from) {
$frame = new \Ratchet\RFC6455\Messaging\Frame($message, true, \Ratchet\RFC6455\Messaging\Frame::OP_BINARY);
$msg = new \Ratchet\RFC6455\Messaging\Message();
$msg->addFrame($frame);
$from->send($msg);
});
});
}
else {
$info->tcp_buf = $payload;
$this->tcp_factory->connect($this->target)->then(function (React\Socket\ConnectionInterface $client) use ($info, $from) {
$client->write($info->tcp_buf);
$info->tcp_buf = NULL;
$info->tcp_client = $client;
$client->on('data', function($data) use ($from) {
$frame = new \Ratchet\RFC6455\Messaging\Frame($data, true, \Ratchet\RFC6455\Messaging\Frame::OP_BINARY);
$msg = new \Ratchet\RFC6455\Messaging\Message();
$msg->addFrame($frame);
$from->send($msg);
});
});
}
$info->inited = true;
} else if ($info->udp_client) {
$info->udp_client->send($payload);
} else if ($info->tcp_client) {
$info->tcp_client->write($payload);
} else if ($info->tcp_buf) {
$info->tcp_buf .= $payload;
}
}
public function onClose(ConnectionInterface $conn) {
$info = $this->clients->offsetGet($conn);
if ($info->udp_client)
$info->udp_client->close();
if ($info->tcp_client)
$info->tcp_client->end();
$this->clients->detach($conn);
}
public function onError(ConnectionInterface $conn, \Exception $e) {
$info = $this->clients->offsetGet($conn);
if ($info->udp_client)
$info->udp_client->close();
if ($info->tcp_client)
$info->tcp_client->end();
$this->clients->detach($conn);
$conn->close();
}
public function getSubProtocols()
{
return array('binary');
}
}
$tls_conf = array(
'local_cert' => '/etc/certs/fullchain.pem',
'local_pk' => '/etc/certs/privkey.pem',
'verify_peer' => false);
$tcp_conf = array('tcp' => array('tcp_nodelay' => true));
$loop = React\EventLoop\Factory::create();
$udp_factory = new React\Datagram\Factory($loop);
$tcp_factory = new React\Socket\TcpConnector($loop);
$tls_content = new \React\Socket\SecureServer(new React\Socket\Server('0.0.0.0:3978', $loop, $tcp_conf), $loop, $tls_conf);
$tls_server = new \React\Socket\SecureServer(new React\Socket\Server('0.0.0.0:3979', $loop, $tcp_conf), $loop, $tls_conf);
$content = new IoServer(new HttpServer(new WsServer(new WsInterface($udp_factory, $tcp_factory, '94.23.161.41:3978'))), $tls_content, $loop);
$server = new IoServer(new HttpServer(new WsServer(new WsInterface($udp_factory, $tcp_factory, '127.0.0.1:9900'))), $tls_server, $loop);
$loop->run();
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment