ServiceStack Messaging API: Can it make a broadcast? - redis

As I have previously mentioned, I am using ServiceStack Messaging API (IMessageQueueClient.Publish) as well as the more low-level IRedisClient.PublishMessage.
I use the Messaging API when I need a specific message/request to be processed by only one instance of a module/service, so even though I might have several modules running that all listens for MyRequest, only one service receives the message and processes it.
I use the IRedisClient.PublishMessage when I do a broadcast, a pub/sub situation, sending a request that everyone should receive that listens on that specific Redis channel.
However, I am in a situation where it would be useful to use the Messaging API, but do a broadcast, so that all instances that are listening to a specific message type, gets the message, not just the one.
(The reason for this is to streamline our usage of Redis and how we subscribe to events/request, but I will not get into details about this now. A little more background on this is here.)
Is there a "broadcast way" for the Messaging API?

No, the purpose of ServiceStack Messaging is simply to invoke ServiceStack Services via MQ. Any other MQ features is outside the purpose & scope of ServiceStack MQ, you'd need to instead develop against the MQ Provider APIs directly to access their broadcast features.
Server Events is a ServiceStack feature that supports broadcasting messages to subscribers of user-defined channels, but its a completely different implementation that serves a different use-case for sending "server push" real-time events over HTTP or gRPC, e.g. it doesn't use MQ brokers and pub/sub messages aren't persistent (i.e. only subscribers at time messages are sent will receive them).

Related

Which option is more suitable for microservice? GRPC or Message Brokers like RabbitMQ

I want develop a project in microservice structure.
I have to use php/laravel and nodejs/nestjs
What is the best connection method between my microservices. I read about RabbitMQ and NATS messaging
and also GRPC
Which option is more suitable for microservice?
and why?
Thanks in advance
The technologies address different needs.
gRPC is a mechanism by which a client invokes methods on remote (although they needn't be) server. The client is tightly-coupled (often through load-balancers) with servers that implement the methods.
E.g. I (client) call Starbucks (service) and order (method) a coffee.
gRPC is an alternative to REST, GraphQL, and other mechanisms used to connect clients with servers though some form of API.
Message brokers (e g NATS, Rabbit) provide a higher-level abstraction in which a client sends messages to an intermediate service called a broker (this could be done using gRPC) and the broker may queue messages and either ship them directly to services (push) or wait for a service to check its subscription (pull).
E.g. I (client) post a classified ad on some site (broker). Multiple people may see my ad (subscriber) and offer to buy (method) the items from me. Some software robot may subscribe too and contact me offering to transport or insure the things I'm selling. Someone else may be monitoring sales of widgets on the site in order to determine whether there's a market for opening a store to sell these widgets etc.
With the broker, the client may never know which servers implement the functionality (and vice versa). This is a loosely-coupled mechanism in which services may be added and removed independently of the client.
If you need a synchronous response on 1:1 service call use gRPC
If you don't care which service will consume messages (asynchronous & no tight coupling between services) use RabbitMQ
If you need distributed system to keep events history and reuse later on another service use Kafka
Basically, it comes down to whether you want an Async communication between services or not.
That is when you can decide between real-time communication services (Sync) such as gRPC or RPC & Message Queueing ones (Async) such as RabbitMQ, Kafka or Amazon SQS.
Here are also some good answers by other users:
https://dev.to/hypedvibe_7/what-is-the-purpose-of-using-grpc-and-rabbitmq-in-microservices-c4i#comment-1d43
https://stackoverflow.com/a/63420930/9403963

REST API with active push notifications from server to client

Problem description
i am working on a Xamarin application that consumes a REST API written in Python flask.
The Xamarin application offers virtual shopping lists where user can collaborate on buying stuff they have on a shared list.
To improve the user experience, i want to be able to actively notify the user about finished items on the list.
Possible solutions:
Synchronous API polling from client side
Notifications are stored by the API in a relational database and have a flag indicating if the user received the notification already.
The API has an endpoint GET /users/:user_id/notifications/ that queries the database for notifications and returns a JSON response with those.
Advantages
fairly simple to implement
Problems
synchronous polling creates a huge amount of http requests
API service remains stateless, making a horizontal scaling with a loadbalancer easier
Websocket endpoint on the API
The API has an endpoint POST /users/:user_id/notifications/register which creates a websocket connection between client and API.
The connection is stored to a global array in which each entry maps a client id to a websocket connection.
When a new notification is created, the endpoint makes a lookup in the connection dictionary by comparing the owner id of the notification with the dictionary entries. The notification is sent to appropriate user through the websocket.
Notifications are stored in the database like in the first approach.
When a user calls the endpoint, a new websocket connection will be established first and upon success the API sends all unseen notifications from the database to the user.
Advantages
API can push notifications to clients asynchronously
Problems
When a user terminates the websocket connection his dictionary entry will persis
Retaining one websocket connection per user permanently adds additional overhead to the API
Horizontal scalability of the API is more difficult because the service is not stateless anymore (Websocket connection information saved in
RabbitMQ
The API uses a RabbitMQ service to send notifications to the client. Every client uses subscribes to his own notification queue to prevent the broadcasting of messages.
Advantages
API remains stateless
Problems
Notifications needs to be resend to the exchange when a user is offline
Amount of queues grows drastically
Additional costs for RabbitMQ service
High temporary load on the RabbitMQ service when many users come online in the same time
Final words
It would be interesting to hear the opinion of others.
I believe the active distribution of notifications from backen services to clients i a very common use case.
best,
D
I would use RabbitMQ and consume events forwarding them as push notifications. This will work while the user is not actively connected to the website and enhance the engagement with each user experience that will return to the website when notified for more information see How to setup basic web push notification functionality using a Flask backend or How to send push notifications to a browser in ASP.NET Core or Sending Notifications with Spring Boot, Angular, and Firebase Cloud Messaging this way the RabbitMQ will not wait until the user is back online. If the user is online you can forward the notification directly to the Xamarin application via WebSockets and a load balancer like NGINX that can handle many WebSockets in an optimized way.
Synchronous API polling from the client-side is the less preferred way since it overloads the webserver with requests while nothing was changed.
I don't think the scalability of WebSocket is a problem. You can scale up easily with pub/sub. The hotspot of long connections is a kind of serious problem.
For one-way communication, I would suggest Server sent event. In the end, it usually depends on what your team is confident with.
I can recommend on a different approach for API that provides JSON which is called GraphQL
It supports subscriptions capabilities that are pushed by the GraphQL API Server (using web sockets)
GraphQL is considered today to be better than RESTful API since its very flexible and you can get exactly the data you need with one query.

WCF duplex channel for inter-process communication

I have system like this:
Windows service (WCF, data/events) <-> Web app <-> Web client
I need simultaneous response for clients requests. I have some events from service for clients too. So duplex channel is the way to go. But I need high throughput, because clients calls simultaneously.
Request/reply approach
In order not to serialize channel requests I need more channels for parallel calls, right? But how to handle callback channel then? Ho to keep it still open for receiving events, even on channel errors?
OneWay approach
On channel should be enough (no waiting for data preparation), but how to link data sent to callback with original request, to be able to compose response for client?
What is the way to go? Thank you.
In a simple case, when a web client sends a request to the web app, and web app (possibly) sends a request(s) to WCF service, there's no need in duplex binding at all.
As for events, raised by the service to be fired in Web client, I'd suggest to use a message broker which supports WebSockets - for example RabbitMQ. It has a plugin compatible with WebSockets and WCF binding.
Putting things together, one can create a RabbitMQ server, which accepts messages from WCF service and sends it to Web client, which subscribes to the event feed from Javascript.

How to properly implement SignalR in a distributed, SOA environment?

I have a good understanding SignalR Hubs in a client/server scenario, where both the client and server are tightly coupled.
Let's say I have a WCF service that receives an update from some external resource. That service could update the database with a new value. However the client would need to be notified that an update has occurred. This could be handled through a service proxy that notifies the client (sounds a bit like polling) or some cache resource.
I could create C#-based clients and connect all the nodes via SignalR hubs, but this creates a closed, non-distributed system.
A SignaR hub that attaches to a WCF service could use the .Net 4.5 could implement a WCF asynchronous service operation, where a hub client would be notified with any service data changes.
I saw something similar in Push Notifications with NServiceBus and SignaR, but not sure if this is an optimal production-level solution.
What other methods could be used in this scenario and how would they be implemented?
If you are not using push notifications directly to the client or some kind of long polling then it is pretty typical to communicate with clients on another channel altogether. Not knowing the business case, it is hard to tell what would be feasible. Usually this manifests itself in the form of SMS, push notifications to mobile, email, etc. This does not answer your question directly, but you may find that there is another way to achieve your goal.

Is NServiceBus suitable for general as well specific client notifications

I am looking at various options for a WCF based publish subscribe framework. Say I have one WCF web service that will be the publisher and 1000 clients registered as subscriber. For some published messages all clients will be interested but at the same time I wish the ability to notify a single client with a specific message. On receiving notification the client will call other web service methods on the web service.
Is NServiceBus suitable for this kind of scenario ?
If I use MSMQ for transport does it mean that every PC where the client is installed requires a queue to be created ?
Some of the challenges include how you want the publisher to behave when a given subscribing client is down - do you want that message to be available when the subscriber comes back up? If so, then some kind of durable messaging is needed between them - like MSMQ.
Your question about notifying a single client, is that as a result of a request sent by that client? If so, then standard NServiceBus calls in the form of Bus.Reply will do it for you. When using WCF, if the response is to be asynchronous you'll need to use callback contracts.
NServiceBus can do all the things you described, and has the ability to automatically install MSMQ and create queues so that greatly simplifies client-side deployments.
You also have the ability with NServiceBus to expose messages over WCF so you can support non-NServiceBus clients if you need to as well. It also has its own http gateway and XSD schemas which can allow clients on non-Windows platforms to interoperate even without using WCF.
Hope that answers your questions.