walkor / phpsocket.io

A server side alternative implementation of socket.io in PHP based on workerman.
2.29k stars 508 forks source link

How to use this with Slim3 ? #187

Open mridah opened 5 years ago

mridah commented 5 years ago

I tried the following code but it doesn't work:

<?php
    require 'vendor/autoload.php';
    use Workerman\Worker;
    use PHPSocketIO\SocketIO;

    $container = new \Slim\Container;

    $app = new \Slim\App($container);
    $container = $app->getContainer();
    $container['IO'] = function ($container) {
        $IO = new SocketIO(1234);
        return $IO;
    };

    $app->get('/update', function ($request, $response, $args) {
        $IO = $this->get('IO');
        $IO->emit('dvdt', 'aaaa');

       return $response->withStatus(200)
        ->withHeader('Content-Type', 'application/json')
        ->write(json_encode(['success' => true]));
   });

  $app->run();
  Worker::runAll();

How to use this with slim framework ??? @Buri @tautrimas @utan @stalinone

LuckyCyborg commented 5 years ago

Of course it does not work.

Basically, the PHPSocketIO is a console application made on PHP, which happens to interact with the network in its own ways.

Slim3 is a WEB application made on PHP, made for running on top of a webserver.

Long story short, they are completely different things, which happens to need complete different infrastructure.

So, your Slim3 routes have as much chance to run like the script is run by the console PHP program.

True, you may manage to modify Slim3 to integrate with the Workerman HTTP server features, BUT that will be a fork of Slim3, and honestly I do not think that is a task for an ordinary user.

As example, you can see https://github.com/nova-framework/quasar for a PHPSocketIO server which include as WEB feature a small custom MVC framework able to show a website. However, bear in mind that that thing runs stand-alone, without a need for Apache or NGINX.

stalinone commented 5 years ago

Not sure what you're trying to achieve, but you could/should treat your slim-based application & PHPSocketIO-based application as different services. Your socket-io app could just issue web request to slim-based app if the former need any resources from the latter. And if you need to have both app on the same machine/container for some reason, you should config a nginx in front of them.

LuckyCyborg commented 5 years ago

Looking to his code, I believe that he tries to make a Push server.

You know, the idea which appears many times, to send a POST request to a server, then it to distribute the message via WebSockets to many clients.

Could be done (also myself I made that) but it is not as simple as many thinks.

As example, there is the relevant code about integration between a webserver and PHPSocketIO, as I used in Quasar, which is a Pusher like feature for Nova Framework and doing exactly that pushing of messages to clients via WebSockets.

// When $socketIo is started, it listens on an HTTP port, through which data can be pushed to any channel.
$socketIo->on('workerStart', function () use ($app)
{
    $router = $app['router'];

    // Bootstrap the Router instance.
    require QUASAR_PATH .'Http' .DS .'Bootstrap.php';

    // Listen on a HTTP port.
    $innerHttpWorker = new Worker('http://' .SERVER_HOST .':' .SERVER_PORT);

    // Triggered when HTTP client sends data.
    $innerHttpWorker->onMessage = function ($connection) use ($router)
    {
        ob_start();

        // Dispatch the HTTP request.
        $request = Request::createFromGlobals();

        $response = $router->handle($request);

        $response->send($connection);
    };

    // Perform the monitoring.
    $innerHttpWorker->listen();
});

In theory, we have a Router class which do a request handling for every call, where there are some Request and Response classes specially made to integrate with the Workerman API. However, to note that our Router is specially made to be ran multiple times, as is needed.

If someone tries to run a Slim3 application over a HTTP server on top of Workerman, probably he needs to build every time a Request instance compatible with the Symfony thing, to dispatch it, then to grab the Symfony Response and to convert in a way compatible with sending over a Workerman TcpConnection instance.

stalinone commented 5 years ago

If so I think the document has discussed about how to do it in here.

The author also provided an example in this repo. The description is in Chinese but I think the code is fairly simple to understand.

LuckyCyborg commented 5 years ago

Yes, the basics are pretty simple, but the bad news comes when someone tries to run a "standard" MVC framework together with the PHPSocketIO.

Because the CodeIgniter, Laravel or even Nova are supposed to run on top of Apache, NGINX or a similar webserver, and they run their entire life-cycle per request. That's completely different from the console environment where Workerman runs forever.

Even us, insisting to taste that MVC on the HTTP side, we arrived to made a custom MVC mini-framework for it, which mini-framework certainly isn't Nova.

alikenski commented 5 years ago

Hello my friend. I have connected the SLIM and PHPSocket.io. In the root folder you should open new folder for example "api" and install in this folder the SLIM. In this folder create index.php file where will be your SLIM code. Also in this folder near index.php create htaccess file and redirect all requests to the index.php file.

index.php (in api folder)

<?php
    use \Psr\Http\Message\ServerRequestInterface as Request;
    use \Psr\Http\Message\ResponseInterface as Response;

    require 'vendor/autoload.php';
    $app = new \Slim\App();

    // ИНФОРМАЦИЯ О ПОЛЬЗОВАТЕЛЕ
    $app->get('/hello', function ($req, $res, $args) {
       return 'success'
    });

    // Run application
    $app->run();
?>

All your request will have this url: /api/hello

.htaccess (in api folder)

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ index.php [QSA,L]

For the PHPSOCKET.io create other folder for example "socket" and install PHPSOCKET.io in this folder. create server.php file for the socket. server.php

<?php
    use Workerman\Worker;
    use PHPSocketIO\SocketIO;

    require_once __DIR__ . '/vendor/autoload.php';

    $io = new SocketIO(3001);
    $io->on('connection', function($socket)use($io){
        /* 

            TASK 

        */
        $socket->on('task_started', function($data)use($io){
            $io->emit('task_started', $data);
        });

    });

    Worker::runAll();
?>

For starting PHPsocket.io in your console go to the "socket" folder directory and write

php server.php start

jupitern commented 4 years ago

take a look at how to integrate console commands in slim3 here => https://github.com/jupitern/slim3-skeleton then just add a console command that runs socketio