I have an ASP.NET Web API server, that have to communicate with different applications on different platforms. And now I want to create a method that would be something like a callback: client application subscribes to it and waits until server fires a message.
Example:
Many users are waiting until new product will be available in store - they subscribe to this "event". When product arrives in store - every customer receives a message, which have to be handled in some case.
Users send a request "Subscribe"
Server receive a request "Product available!"
Server sends every user a message with product details.
User's application processes the message
I tried to find some information about callbacks or duplex in ASP.NET Web API, but the one advice - it's better to use WCF for this approach.
Solutions
In every client application create something like timer, that every N seconds sends a request "Is product available?" until gets "false". When the response will be true - send a message "Get product details". It's causes a lot of traffic and if there will be many clients with these timers - it would be something bad, isn't it?
Create a small callbacks-server (maybe WCF). But in this case would be a lot of problems with communication between this server and apps on different platforms.
Maybe there are some solution in ASP.NET Web API, that i missed.
If you have some ideas how i can solve this problem, please give me an advice.
Thanks for help.
Looks like you want push notifications from your server - which, in this case, can be achieved by combining SignalR with Web API.
Brad Wilson has a great example on this:
code here - https://github.com/bradwilson/WebstackOfLove
NDC Oslo talk explaining all this - http://vimeo.com/43603472
In short, whenever you add new item to the Web API, you can notify all the connected (subscribed) clients:
public void PostNewItem(ToDoItem item)
{
lock (db)
{
// Add item to the database
db.Add(item);
// Notify the connected clients
Hub.Clients.processItem(item);
}
}
SignalR will invoke the processItem function on the client.
Alternatively, you might want to look into JavaScript SSE and Web API PushStreamContent but that is much more low level and SignalR abstracts a lot of this type of stuff for you so it might be more complicated to deal with.
I blogged about this approach here http://www.strathweb.com/2012/05/native-html5-push-notifications-with-asp-net-web-api-and-knockout-js/
Related
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.
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/
I'm trying to figure out how Websockets works. I read some articles, tutorials, etc and I have a pretty basic understanding of how it works, but there is one element that I can't understand how to implement.
My idea is the following : One user will load a "customer" page containing all informations of that customer + a discussion thread. If an other user load that same page, they will be able to discuss in real time and if one user update the data of the customer, the second one will see the update.
The thing that is bugging me, is how can I allow users to access a customer data, but by checking that they can access it (for example, users can access the customer of their group, not all customers)
How can I be sure that the current user will access a customer he has the right (in the websocket)?
Thank you for your help!
Think of the websocket connection itself as a separate thing. A socket used by a client can subscribe to many different events.
What you're describing is topics. When the websocket connection is established, you send a message using whatever socket framework you're using to subscribe to a topic. For example, it could be a topic called customer-123. (A analogy for a topic, is a chat room)
Your application logic (server side) will verify that the currently logged in user has permission to access customer 123, and if so, permits them to join this topic. If you don't do this, it would be trivial for users to listen to any messages relating to any data.
Whenever a user updates any data that is relevant to customer 123, a message is posted to that topic. And thus, any user who is in that topic will receive the message.
An socket might subscribe to many many topics for each customer they open in your app. And topics can be combined and managed in groups depending on how you want to send messages.
In a typical large app, it's common to have a websocket subscribe to topics like user-123, team-456 by default so the server can send messages to them individually or to the entire team to which they are a member of.
For example, if a user updates customer-123, I might send a full data object to the customer-123 topic, and if customer 123 belongs to team-456, I would also send a small notification object like 'User 789 has updated customer 123' to the entire team (which is what powers Facebooks feed like system).
As your app grows, you'll use services like notification hubs to manage the fact that there could be thousands of topics each with thousands of subscribers.
The best thing to do is share a session ID and set up authentication token policies between your web application and your socket session. You could set up your own policy middleware to check the session ID.
You aren't really clear about how you're trying to accomplish this. If you're using express/socket.io, you can use this module: https://www.npmjs.com/package/express-socket.io-session
Hope this helps!
Like any other production application, you need authentication (who is allowed to use the app) and authorization (what functionality can a authenticated user perform). Authorization (ie, access control - ACL) is probably more precisely what you are looking for. Your app has to consult an authorization subsystem to see if the current user has access permission to edit/view another user's information.
This is not a trivial concern for many applications; security and privacy are important aspects of any web-based (distributed) application.
I am quite new with Spring MVC and Web technologies.
I need "real time" interactions between the server side and the client side of my web application.
When a user click on a button, I want to execute server side code, create a message and send it to every client.
I think Web Sockets are the solution. I can add methods on the controller part of my application.
When a user click on a button, the Controller method is called. I can execute code and send back a message for every clients.
But now, I can receive messages coming from another website. Let's say that I am using a MessageListener.
How am I supposed to notify my clients? The server side of WebSockets is in the controller. I don't think i am supposed to call this method from the server.
I can create some kind of weird adapter capable to
- Establish WebSocket channel with server (a local channel)
- Receive messages from another website using a broker
- Send the message to the controller
I don't feel like this is an unusual need and my solution looks tricky.
I am sure there is an easier way to do it, but I am not able to find it.
So, am I doing it right? Do you have any idea, any suggestion?
Thank you for your help.
Ben
I have an infrastructure, bussiness rules and other logic, that I use in a WPF application, in it I have a messaging service that implements an message service interface, this service is register in a Container, I use Castle Windsor.
Every time that the infrastructure needs to show any kind of messages it uses this service and shows a message and waits for the reply, with this I don't have to a request to the GUI/WPF to show a message.
My problem is that I'm using this same infrastructure for a ASP.NET MVC site and I having some problems in find a solution where I can use this same interface. Basically if the message service has to show a messages it should be able to post a message box in the browser, preferably via AJAX and wait for the reply of the user and then continue the execution according to the answer.
I don't know if I'm made my self clear enough on the problem.
Any hints on how to implement such a service would be much appreciated.
Thanks.
The problem is the server knows nothing about open browsers, therefore it can't signal the broswer to show the message.
The solution would appear to be to queue messages from the service, have some script on the page that checks (using ajax) for items in the queue, and display messages as appropriate.