I am building my application on a microservice model.
Lets says
There is one database on server D1
There is a user service hosted on server U1
There is a notification service on server N1
There is a rabbitmq service on server R1
The notification service publishes a message to the rabbitmq service, which then dispatches the message to the user service, the user service that listens to the rabbitmq service, receives the message and writes some data to the database.
This works perfectly!
The problem is if I scale the user service to another server say U2, meaning the user service is now running on both servers i.e. U1 and U2 (backed by an nginx load balancer) and both the user service now listening to the rabbitmq service, will receive the message dispatched from the notification service and both will write to the database (which I don't want). I want only one of the user service i.e. either U1 or U2 to write the data to the database.
So, i was wondering if rabbitmq can dispatch the message to any one user service instead of both? or am I using a wrong approach altogether?
I think you can use Single Active Consumer option
"Single active consumer allows to have only one consumer at a time consuming from a queue and to fail over to another registered consumer in case the active one is cancelled or dies."
Register U1 and U2 on the same queue
U1 will be registered as Single Active Consumer
If U1 dies/canceled, it will be replaced by U2 as Single Active Consumer, and vice versa
To use this option pass x-single-active-consumer argument when declaring the queue
Please read the documentation for more information.
Reference: RabbitMQ Consumers Single Active Consumer
Related
I want to authenticate all MQTT subscribers on a topic with Solace using Basic Auth . (Username and password) . But want publishers to send to that topic without authentication.
I configured basic auth. and ACL's on a VPN but that wants my both subscribers and publisher to use username/password. Can this be possible via any configuration to allow anyone to publish to a topic in solace but only authenticated users to subscribe and listen on that topic ?
Only one type of authentication is supported per Message VPN on the Solace VMR. It seems your use case requires both a basic authentication type of "None" as well as "Internal" to be supported.
One way to achieve this would be to create two Message VPNs, where the first uses a "None" type of basic authentication and allows anyone to publish a message without requiring a password and the other Message VPN uses an "Internal" type of authentication, where the user has to authenticate using a configured username and password in order to subscribe. You can set up a Message VPN bridge between the two Message VPNs which will permit messages published in one Message VPN to be delivered to the other Message VPN.
For added security, you can configure the ACL profiles in the Message VPN using "None" authentication to disallow all subscribing. This will prevent a subscribing user from connecting directly to this Message VPN without having to authenticate with a username and password.
The problem here is the difference between Authentication and Authorisation.
MQTT authenticates the user at the time the client connects before it subscribes or publishes any messages.
Authorisation to publish/subscribe to topics takes place when that client then tried to either publish or subscribe, and is based on the authenticated user.
I am building a website which receives real-time updates about soccer matches. I am using RabbitMQ to send the updates to the clients (JS website and Android/iOS apps).
The clients should only receive real-time updates. In other words, a client should only receive updates when the user is logged in. No history is kept.
To achieve this behavior, I was thinking about the following architecture:
A fanout exchange in RabbitMQ.
Each user has a dedicated queue, which is bound to the exchange. This queue is created when the user account is created.
For these queues, the queue property x-message-ttl with value of 0 is set. See below.
When the user logs in, the client consumes the queue of the corresponding user.
Messages are sent to the exchange by the backend, and forwarded to all queues. When a user is not logged in, the message will be discarded immediately, as x-message-ttl is set to 0.
Is this a correct usage of AMQP/RabbitMQ to achieve real-time notifications?
Yes and no - some of your premises are wrong.
In other words, a client should only receive updates when the user is logged in. When the user is not logged in, simply drop the connection to RMQ and that's it.
Each user has a dedicated queue, which is bound to the exchange. This queue is created when the user account is created. The queue should be created only after the connection to RMQ is established, in that way you are also covering the When a user is not logged in, the message will be discarded immediately part.
No need to set TTL to 0.
Messages are sent to the exchange by the backend, and forwarded to all queues Just to be clear, it's the RabbitMQ that does "forwarding" from exchange to queues.
Apologies, in advance, that this question is probably too vague to be admitted into the cannon of good StackOverflow questions. However it does reflect the current state of my knowledge of this domain.
Sonos provides the ability for a 3rd Party Service to offer Sonos users access to a music service. This I understand, and the documentation provided by Sonos is comprehensive.
However, we have the scenario of Service Provider A who provides users with the following services:
Access to streaming radio (for which A has the rights and can provide the stream)
Access to on demand / catch-up content (for which A has the rights and can provide the stream)
Ability to create playlists of music played within 1 & 2 (for which A does not have the rights, and instead provides the stream via one or more 3rd Party music services that the user has an account with).
This works perfectly well in the context of A's own apps - which include integrations with 3rd party music services who provide the stream for content that comes under 3 (i.e. if you are a user of A, then while you can create playlists, if you want to actually play a track from the playlist then need an account with a service provider who has the rights to that particular track).
However, I am struggling to reason about this in the context of Sonos.
If, as a user of A, I have the following container:
Container1
item1 ('podcast' belonging to Service A)
item2 (song, belonging to Service B)
I am registered with both Service A and Service B, and both Service A & Service B are available separately on Sonos and both use DeviceLink for authentication (lets for the purposes of this example assume that Service B is Spotify).
If the user requests the container, adds item1 to their queue and then presses play, the Player will request the streaming uri from Service A, and Service A will return it in the format:
http://service-a.uri/some-file
The player will then perform a GET request on this uri, and the item will start playing.
However, if the user adds item2 to their queue and then presses play, Service A will return a streaming uri belonging to Service B like this:
http://service-b.uri/some-file
In this case, how is authentication handled?
The user is authenticated as follows:
Within Service A:
To Service A
To Service B, via Service B's API.
Within Sonos:
To Service A
To Service B
However, Sonos is going to send Service A's credentials to Service B, and thus the stream will fail (because why would it know that Service A has a pre-existing relationship with Service B whereby Service A users consume content from Service B, if said user already has an account with Service B).
So there is no way to achieve what I am looking to do in the context of Sonos, or am I fundamentally misunderstanding something here?
That is a really great question.
For streaming Sonos requests the uri with the getMediaUri request. This uri is then used to stream the content. If uri returned as a result of this request is streamable then there should not be an issue. It is possible to include headers that should be sent with the uri request and that can also be used if some additional authentication is required. (For example passing an authentication token to Service B). However the requirement here is the Service A would have everything it needs to properly pass this information to Sonos so that Sonos can include it in its request to Service B.
For security reasons Sonos does not currently have a way to pass Service Bs authentication token or information to Service A; nor is there a way for the Sonos player to know that a url it is requesting which was provided by Service A is actually intended for Service B. There is also no way for the player to inform Service A that the user also has Service B installed.
This is something we have thought about and will consider providing a mechanism to support this in the future.
I have a service hosted in a Worker Role in Azure. Clients connect over NetTcp bindings using certificates for mutual client/service authentication and with a custom username password validation.
Clients also receive event notifications that are broadcast through the Azure service bus using shared secret authentication.
I want this to be secure and not allow one person to share his/her login information with friends or anyone else - their login is for their use only. Similarly, a user that forgets to log off at one machine and then logs in to the service from another machine (i.e. tablet, work computer etc.) should trigger a automatic shutdown of the application that was not logged off from.
I am using a per-call serivce, and to have implement a solution using sessions would require alot of rewiring.
I figure I need to keep track of the users' context when they make a operation call and track which IPs are currently using that login/credential. I would like to be able to have some kind of "death touch" whereby the service can send a kill command to a client when multiple logins are detected.
Any suggestions or pointers to patterns that deal with this issue would be appreciated.
Thanks.
Even if you did go with PerSession you would still need to determine if the same user was in more than one session and you have the overhead of session.
I have only tested this over WSHttpBinding and not hosted in an Azure Role so please don't vote it down if it does not work on NetTcp Azure Role - comment and I will delete it. Even with PerCall the SessionID is durable and SessionID is available on both the client and server. More than one user could have the same IP address but SessionID is unique to the session. Clearly you would need to record the userID, SessionID but table storage is cheap.
Maybe update license model for concurrent usage. By recording userID and sessionID you could write an algorithm to calculate max concurrent usage.
hello i have a desktop application that communicate with a wcf service that i building as well
i want to be able to manage the logged on users inside the server without a db (statefull server)
i also want the server to know how to handle 2 client from same computer, whats the simplest way of doing it?
i also have more than 1 service that the client work with (login service and app service)
is there any operationContext Property that can help me?
You can deffinetly manage the logged users inside the server. I have created a personal pattern for dealing with such situations, and it ussually goes like this:
create a client class inside the WCF server that will hold all the needed information about the client.
create 2 methods in the service: logIn, logOut. the login method should be able to gather all the informations about the client that you want to store. Make sure to define properties that can uniquely identify a client instance. When the client conencts to the server it calls the login method, allowing the server to gather and save the information from the client. If using callbacks, this is the place to save the CallBack context object, in the client obejt. You can now save the Client object in the WCF server instance (I use a dictioary). When the client logs out, it calls the log out method and the server removes the entry.
create a KeepAlive method in the server that regularry checks the connected clients to see if they are still connected (in case of network failure or app crash a client may not call the logout method).
I think this is the simplest way (not saying it's the best) to manage clients in the server.
There is no problem with having multiple clients from the same computer (you save the Context when a client logges in) as long as you have a way of uniquely identify clients.
As for your last question, having multiple services should not be a problem. In fact you have the same WCF server with different contracts (and endpoints) for the different services you offer. ALl the contracts reside in the same WCF server instance so they all can access the connected client list.
If you have further questions, I would be happy to answer them.