Avoiding a single route in Laravel for events sent by the server

So, I'm trying to use Server Sent Events in my laravel application, but the problem is that in SSE you can only specify one URL as in:

var evtSource = new EventSource("sse.php"); 

The problem is that I want to send events from different parts / controllers of the entire application, for example, not only to one sse.php file. Example:

 // AuthController.php public function postLogin(Request $request) { // login logic // SEND SSE EVENT ABOUT NEW USER LOGIN } // FooController.php public function sendMessage() { // SEND SSE EVENT ABOUT NEW MESSAGE } 

The only idea that comes to my mind is that from these controllers create temporary files with event text, and then read these text files in the sse.php file, send events, and then delete the files. However, this does not seem like an ideal solution. Or maybe the sse.php hook sse.php with the Laravel event mechanism is somehow, but it seems more advanced.

I also don't mind creating multiple event source objects with different php files, such as sse.php , but the problem is that these controller methods do not necessarily just send events alone, they also do other work. For example, I cannot use the postLogin action directly in an SSE object, because it also performs a login login, not just sending an event.

Has anyone had a similar problem and how to deal with it?

+5
source share
2 answers

SSE is never used, but according to their docs, two solutions come to me:

1. Define several EventSource objects and process them differently in js:

 var loginSource = new EventSource("{!! url("/loginsse") !!}"); var messageSource = new EventSource("{!! url("/messagesse") !!}"); 

2. Inside your sse.php file sse.php check for updates from another controller:

 //sse.php called function while(1) { $login = AuthController::postLogin($request); if ($login) return $login; $msg = FooController::sendMessage(); if ($msg) return $msg; // ... } 

You will need to make the static methods sendMessage() and postLogin(Request $request) .

Consider also the adoption of some libraries for using SSE with laravel: a quick Google search provided me with several options.

+2
source

You can use Laravel events and create a listener that combines all the different events from your application into a single thread, and then you would have one controller that would dispatch this stream of events to the client. You can generate an event anywhere in your code, and it will be transmitted to the client. You will need some kind of common FIFO buffer to provide communication between the listener and the controller, the listener will write to it, and the controller will read it and send SSE. The easiest solution is to use a simple log file for this.

Laravel also has a built-in broadcast feature using Laravel Echo, so maybe this can help? I'm not sure if Echo uses SSE (has zero experience with both), but it does almost the same thing ...

Updated: Let me try adding an example:

1) First we need to create an event and a listener, for example:

 php artisan make:event SendSSE php artisan make:listener SendSSEListener --event=SendSSE 

2) An event class is just a wrapper around the data that you want to pass to the listener. Add as many properties to the SendSSE class as you need, but only pass a string message for this example:

  public function __construct($msg) { $this->message = $msg; } public function getMessage() { return $this->message; } 

3) Now you can fire this event as follows:

 event(new \App\Events\SendSSE('Hello there')); 

4) Your recipient's handle () method will receive it, and then you need to push it into the FIFO buffer, which you will use to communicate with the SSE controller. It can be as simple as writing to a file and then reading from it in your controller, or you can use the DB channel or linux fifo or shared memory or whatever. I will leave this part to you and suppose that you have a service for it:

 public function handle(\App\Events\SendSSE $event) { // let presume you have a helper method that will pass // the message to the SSE Controller FifoBufferService::write($event->getMessage()); } 

5) Finally, in your SSE controller, you must read the fifo buffer and when a new message is sent to the client:

 while(1) { // if this read doesn't block, than you'll probably need to sleep() if ($new_msg = FifoBufferService::read()) { $this->sendSSE($new_msg); } } 
+2
source

Source: https://habr.com/ru/post/1269951/


All Articles