Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Simple websocket implementation in laravel 5

I need to implement very simple and very basic websocket in Laravel to implement data synchronization process between my phonegap app as client and my Laravel Website as server. I followed this tutorial http://www.binarytides.com/websockets-php-tutorial/ to implement and test websocket and it works. Like this one i need very simple laravel implementation where i can call my controller method from js client. Client will be my phonegap application. I found some packages for websocket in laravel with tutorials, but i found difficult to implement them. No one was interacting with controllers, they were listening to events and creating classes here and there but not in controllers. I have written all my logic in Controller and tested it with ajax request but now i will implement it by websocket because i need bidirectional communication to implement Synchronization process. I am new to Laravel so please provide me some help. Also it will be so great if somebody can tell me how to integrate the about tutorial in laravel to so that client can directly call controller to send data.

like image 217
Hassan Dad Khan Avatar asked Nov 02 '15 06:11

Hassan Dad Khan


People also ask

Does Laravel support WebSockets?

The laravel-websockets and soketi packages provide Pusher compatible WebSocket servers for Laravel. These packages allow you to leverage the full power of Laravel broadcasting without a commercial WebSocket provider.

How configure WebSocket in PHP?

To implement WebSocket with PHP, you have to install an additional module like Swoole. You have more than one module that allows you to implement WebSocket service in PHP, in this tutorial I'm going to use Open Swoole implementation by SwooleLabs considering that Open Swoole includes support for WebSocket.


1 Answers

I ended up using brainboxlabs's brainsocket (https://github.com/BrainBoxLabs/brain-socket) . As its document says its laravel 4 package but it also works with laravel 5 without any issue.

To install this package with laravel 5. Follow the documentation on the above github link. Where it says to create an event.php file in app folder and some events related code. Instead of this step simply add that event related code in app/Providers/EventServiceProvider.php file. In its boot method, add that code which is

Event::listen('generic.event',function($client_data){
    return BrainSocket::message('generic.event',array('message'=>'A message from a generic event fired in Laravel!'));
});

Event::listen('app.success',function($client_data){
    return BrainSocket::success(array('There was a Laravel App Success Event!'));
});

Event::listen('app.error',function($client_data){
    return BrainSocket::error(array('There was a Laravel App Error!'));
});

After this step there was a step of adding

require app_path().'/filters.php';
require app_path().'/events.php';

in app/start/global.php . You can leave this step for laravel 5.

Ok so Web socket has been implemented. You can test by starting the websocket server using cmd by running the command artisan brainsocket:start. You can optionally provide it the port artisan brainsocket:start 9000

Another requirement was to call controller to to perform rest of the task. For this i directly edited into to provider package. I do not recommend this as it is not a good way. When you will update your package using composer your changes will be lost. So you have to find a better option. But its just a one line change.

In vendor\brainboxlabs\brain-socket\src\BrainSocket\BrainSocketServer.php i edited code in method "start" and replace

$this->server = IoServer::factory(
            new HttpServer(
                new WsServer(
                    new BrainSocketEventListener(
                        new BrainSocketResponse(new LaravelEventPublisher())
                    )
                )
            )
            , $port
        );

with

$this->server = IoServer::factory(
            new HttpServer(
                new WsServer(
               new \FMIS\Http\Controllers\SynchronizationController(
                  new BrainSocketResponse(new LaravelEventPublisher())
                                            )
                )
            )
            , $port
        );

And in my SynchronizationController file.

I added this on top

use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;
use BrainSocket\BrainSocketResponseInterface;

Implemented interface like this.

class SynchronizationController extends Controller implements MessageComponentInterface{

and implemented the methods of this interface.

public function __construct(BrainSocketResponseInterface $response) {
        $this->clients = new \SplObjectStorage;
        $this->response = $response;
}

public function onOpen(ConnectionInterface $conn) {
        echo "Connection Established! \n";
}


public function onMessage(ConnectionInterface $conn, $msg){
 echo "this messge gets called whenever there is a messge sent from js client";
}

public function onClose(ConnectionInterface $conn) {
    echo "Connection {$conn->resourceId} has disconnected\n";
}

public function onError(ConnectionInterface $conn, \Exception $e) {
        $msg = "An error has occurred: {$e->getMessage()}\n";
        echo $msg;
        $conn->close();
}

You have to change in these methods to implement your functionality. After this you can call from your js client. And you are not required to use its js library as well. You simply send data using js client describe in this tutorial http://www.binarytides.com/websockets-php-tutorial/ .

Let me know if somebody need any more help regarding its implementation.

like image 174
Hassan Dad Khan Avatar answered Sep 16 '22 14:09

Hassan Dad Khan