Where to subscribe for Redis Pub/Sub in Laravel? - laravel

I've been using Redis's Pub/Sub a bit in my application and so far it has been great. I am able to send out a Publish out of Laravel to a different backend process that is able to Subscribe, and eventually Publish an event back to Laravel.
The use case for the user looks like:
submit a form -> wait for a response (a few minutes) -> proceed with transaction
On the backend:
the form posts to a route, then to a controller that publishes this to a subscribed 3rd party (channel one), and eventually that 3rd party publishes back (channel two)
Main Issue: I don't know where the appropriate place to be for subscribing to the (channel two) and processing what gets published there.
Ideally, I'd be able to process Publish requests in two ways:
Letting the user know that their form has been processed and they can move onto the next step (probably with an update to a property a Vue component)
Storing information from the publish into my database.
In the docs, they have it in a Command, which if I try to use here would look like so:
public function handle()
{
Redis::subscribe('channel-two', function ($message) {
// update the client so that the user moves on
// send $message contents to the database
});
}
but that doesn't really seem ideal for me since I want this channel subscribed to 24/7, always listening. Even if it is in a Command, it is still apparent how I would best update the client.
Where in my Laravel project should I be subscribing at? Is there a best practice to respond to these events?

Redis::subscribe is used in a command like in that example for listening on a given channel continuously.
From the docs:
First, let's setup a channel listener using the subscribe method. We'll place this method call within an Artisan command since calling the subscribe method begins a long-running process:
You'll want to run the command using a process manager like supervisor or pm2, much the same as the docs describe running queue listeners.

Related

How to listen to Skype for Business call events

I need to notify a backend server about Skype for Business call events. Calling the backend is not the problem, but listening to call events is. I thought about watching and parsing skype log files, but there seems to be no call information in the log files... And it would be an ugly solution anyway.
Is it possible to somehow listen to SfB call events and trigger custom actions?
I know there are various SfB SDKs, but none of them seem to offer a way to listen to these events...
I would like to be able to do something like this (pseudo code, I don't really care what language is used, but would prefer JavaScript):
skype.onCallIncoming(callInfo => {
console.log(callInfo.user + ' is calling');
// my custom action
});
skype.onCallAccepted(callInfo => {
console.log('The call was accepted');
// my custom action
});
skype.onCallEnded(callInfo => {
console.log('The call was ended');
// my custom action
});
SfB does not provide any live "call events" that you can use in ANY SDK.
For live "calls", the best you can do (with little effort) is to subscribe to a users presence and hook off the "on a call" (on-the-phone) activity token busy status (this presence state is not guaranteed to be correct). The problem with this is you can't really get "all" call events for everyone, since you can only subscribe to endpoints that you know about. There are also problems with working with large scale subscriptions. This can be done with most of the SDK's for Skype include UCWA.
Another option is to use the CDR database, although that is not for "live" calls and the CDR database needs to be enabled for the site. Once enabled you can just use SQL queries again the DB for historical call data.
If you really need large scale call monitoring, then the only option is to create a SIP proxy application that runs on the FE machines and translates "sip" messages into call events. This is a lot of work, it seems simple to do but gets very difficult very fast. This will give you "live" call events but will take someone a long long time to get it right and you have to have a deep understanding of SIP.
If you are talking about just your local Skype desktop client calls ONLY (windows client only), you can use the client SDK to hook into the local client and you can track the call events that way.

Symfony3.4 - Send a Server-Sent Event when something happens

I'm developing a project with Symfony 3.4.
I would like to send a message to all the clients currently viewing a page when something happens. I evaluated both Server-Sent Events and Websockets, and I decided to go with the former, because the communication is unidirectional (only server to client).
For this purpose, I'm using this library: https://packagist.org/packages/tonyhhyip/sse
It seems to work, but I need to specifically send a message when something happens in the whole system. I tried with the Symfony event system (by creating a custom event), but events seem to be dispatched and captured only within the same session (i.e., the same logged user). In other words, if an action performed by a user triggers an event, it is not captured by other users and therefore a message is not sent to the browser via SSE.
Any suggestion?
Thank you

How to subscribe to a notification stream for packet_In processing?

I am writing an external application that uses REST to communicate with open-daylight. I need to get a notification whenever a new communication between two nodes is needed.
I've checked how to subscribe for event notification in the following link. But I am not sure if this is possible for a packet_in event.
Is it possible to get a notification of the new connection packet_in, with/without some information about the packet?
What would be the path used to create-data-change-event-subscription? also, how can I check all available events and paths that I can make use of?
I believe the "packet_in" event is a yang notification however the REST notification subscription mechanism is for data change notifications. Unfortunately there is no mechanism currently (that I know of) to subscribe to yang notifications over rest.

How to asynchronously push data to reactJs from Spring api web service to update a progress Bar?

I have an application which allow an user to send a lot of SMS to his contacts (like thousands).
Obviously that tasks can take a lot of time to complete.
So the idea is to display a progress bar on the client side, to indicate the user how many messages have been sent so far.
The back end of my app is a restful spring webservice.
The front end is done with ReactJS and Redux.
The question is:
Is it technically possible from the back end to periodically push data to the client, to update the progress bar, with the amount of messages already sent.
First question regarding the back end architecture:
I've seen that using JAX-RS 2 with spring, I can make asynchronous call in the back end, to execute other tasks(like querying the DB to see the messages already sent) while the other process is sending all messages. Am i looking in the right direction here ?
Second question regarding front end :
So far I use thunk functions for my requests(post/get) to the server, which returns a json response, and it works well. But in this case, the back end would periodically push data to the client side, until the main task is completed, so I don't understand how would that work out exactly ?
I guess I'm not gonna be able to achieve that using the same request ? Should I look at other technologies to achieve that ?
Please let me know, if the description of my problem is not clear.
Cheers
There are two options: you can keep track of the task on the backend and have an API endpoint to check the status and poll it every x seconds.
The other option would be to use sockets, the frontend client would listen for an event and update display onEvent. The backend would be responsible for emitting events.

How to query in a Event Driven Microservice architecture?

Let suppose the following simple UC based on a CQRS architecture:
We have a backend managing a Business Object, let says a Movie.
This backend is composed of 2 Microservices: a CommandManager (Create/Update/Delete Movie) and a QueryManager (Query Movie)
We have a frontend that offer a web page for creating a new Movie and this action lead automatically to another web page describing the Movie.
A simple way to do that is:
A web page collect movie information using a form and send them to the frontend.
The frontend make a POST request to the CommandManager
The CommandManager write the new movies to the datastore and return the movie key
The frontend make a GET using this key to the QueryManager
The QueryManager looks for the Movie in the Datastore using the key and return it.
The frontend deliver the page with the Movie Information.
Ok, now I want to transform this UC in a more Event Driven way. Here is the new flow:
A web page collect movie information using a form and send them to the frontend.
The frontend write a Message in the BUS with the new movie information
The CommandManager listen the BUS and create the new movies in the datastore. Eventually, it publish a new message in the BUS specifying that a new Movie has been created.
At this point, the frontend is no more waiting for a response due to the fact that this kind of flow is asynchronous. How could we complete this flow in order to forward the user to the Movie Information Web page? We should wait that the creation process is done before querying the QueryManager.
In a more general term, in a asynchronous architecture based on bus/event, how to execute Query used to provide information in a web page?
In addition to #VoiceOfUnreason's answer,
If the two microservices are RESTFul, the CommandManager could return a 202 Accepted with a link pointing to the resource that will be created in the future. The client could then poll that resource until the server responds with a 200 OK.
Another solution would be that the CommandManager would return a 202 Accepted with a link pointing to a command/status endpoint. The client would poll that endpoint until the status is command-processed (including the URL to the the actual resource) or command-failed (including a descriptive message for the failure).
These solutions could be augmented by sending the status of all processed commands using Server Sent Events. In this way, the client gets notified without polling.
If the client is not aware that the architecture is asynchronous, a solution is to use an API gateway that blocks the client's request until the upstream microservice processes the command and then to respond with the complete resource's data.
At this point, the frontend is no more waiting for a response due to the fact that this kind of flow is asynchronous. How could we complete this flow in order to forward the user to the Movie Information Web page? We should wait that the creation process is done before querying the QueryManager.
Short answer: make the protocol explicit.
Longer answer: a good place to look for inspiration here is HTTP.
The front end makes a POST to the origin server; as a result the origin server places a message on the queue and sends a response back.
The representation sent with this response ought to describe the request's current status and point to (or embed) a status monitor that can provide the user with an estimate of when the request will be fulfilled.
The client can then poll the endpoint to find out what progress has been made.
For instance, the endpoint might be a query into the data store, that looks for evidence that the command manager has processed the original command; or it might be an endpoint that is watching the bus for the MovieCreated message, and changes its answer based on whether or not it has seen that.
It may help clarify things to look into idempotent request handling; when the Command Manager pulls a message off of its queue, how does it know if it has previously processed a copy of that message? Your polling endpoint should be able to use the same information to let the consumer know that the message has been successfully processed.
In addition to #Constantin Galbenu's answer, I would like to put in my two cents.
I would strongly advise you to look at a microservices pattern called "BFF" (Backend-For-Frontend) pattern. Instead of having a thick API gateway doing all the work, you can have an API per use-case. For Example: In your case, you can an API called "CreateMovieBFFHandler" which would receive the POST request from front-end and then this guy would coordinate with other things in the system like message queues, events etc. to track the status of the submitted request. UI might have a protocol with this BFFhandler that if the response doesn't come back in X seconds, then the front-end would consider it as failure and if this handler is able to get a successfully processed messaged from message queue or "MovieCreated" event for this key, then it could send a 200 OK back and then you can redirect the page to call write side and then populate the UI.
Useful Link: https://samnewman.io/patterns/architectural/bff/

Resources