Currently I am using SignalR for push notification, but due to cost constrain looking for the new alternative. When I read about gRPC its mostly used for microservice communication. Will this gRPC is suitable for web push notification? is there any example I can find. Thanks.
Related
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.
I’m currently working on bidirectional communication between some IoT sensors and a mobile app using Pusher channels.
I have been able to get Pusher working on the IoT nodes using the Arduino library and also in my React Native app.
However, I’ve hit a bit of a roadblock. My IoT sensors aren’t capable of producing JSON payloads and arrays (they broadcast batches of 30 readings at 30 second intervals) due to memory constraints. Each reading can be up to 60 characters in length unprocessed and a full payload being sent every 30s would be at least 1800 bytes, then there’s the header data (Auth token and session data for the sensor’s context).
I do not want to parse this hex data on my React Native app (as some comes from proprietary sensors where the protocol cannot be risked being divulged) so need it to happen on my ExpressJS API (currently handles the authentication and historic data retrieval) before it enters Pusher and pings the React Native app.
My questions:
If the sensor made a POST request to my Express API in which the route performed the processing from hex into nice JSON (with full text values!) - can I use the Pusher client to get this data into the correct channel? Instead of having the sensor talk straight to Pusher?
Is there a way to bridge the Pusher service through my API so that the React Native app “points” to my API for the updates instead of directly to Pusher?
Here is the architecture that I’m trying to achieve - hoping those of you who have experience with Pusher can tell me if this is possible:
I’ve seen the “pusher-http-node” server library but there’s no tangible description of why this would be used.
Really hoping I don’t need to go down the MQTT route and have my own micro service (something I’ve wanted to avoid given the costs and scalability concerns).
DevRel at Pusher here.
To answer your questions:
That setup makes sense. Your Express API can preprocess each sensor event before sending them to the Channels service - you'd use the Node SDK on the server. That preprocessing can include putting it in the correct format, and sending to the correct channel.
For the difference between SDKs:
The pusher-http-node SDK is designed to run on servers, and can send messages to any channels you want.
It also holds your private keys - something that your React
Native client SDK doesn't.
Server SDK doesn't implement subscriptions.
The pusher-js client SDK that you use in the React Native apps on the other hand can only subscribe or send client events.
Your client applications should connect to Pusher Channels service so they can receive realtime updates. Channels serves as the transport here. Your Express API should use pusher-http-node to send these events to Pusher Channels.
So, to summarise:
Have your IOT sensors communicate raw data to your Express API
In your Express API do the preprocessing of these raw events, turning them into something your React Native apps can understand and use
In your Express API use the pusher-http-node library (server SDK) to send these processed events to Pusher Channels service
In your React Native apps use the pusher-js library (client SDK) to connect to Channels service and subscribe to the events your Express API is sending.
I hope this clarifies it a bit!
I am using signalR with ASP.NET Core 2.1 to send and receive messages from server-to-client or client-to-server even I also used streaming channel to send long message in chunks greater than 30kb from client to server.
But now I am wondering is it possible that I can make communication between server and client using voice or video?
I checked WebRTC is giving the solution for my requirement but as I am already using SignalR so I am looking for the solutions using SignalR for the websocket transport.
Adding answer to my old question as nobody added any response to it.
Yes, it is possible to use signalR core with WebRTC as a signaling server.
Here is the sample project that I created for .NET Core 3.1. Feel free to ask me question related to my approach.
I want to create my own video chat application. I use the WebRTC framework. I read a few tutorials and each of theme assumes that signalling channel exists. How to implement my own signalling channel?
Since signalling is not defined for the WebRTC standard at the moment, it leaves you a few options. Check out this article for more info the following articles:
Signalling Options for WebRTC Applications
Choosing your signalling protocol
1.SIP over WebSockets
Companies like JSSIP offer a SIP signalling framework over Javascript. The advantage here is that it's interoperable with the usual VoIP structures.
JSSIP
SIPJS
SIPML5
2.The WebRTC Data Channel
Uncharted territory but viable!
Tutorial by Pusher
3.XMPP
If you take this route, it is probably either because you have an existing XMPP installation
Jingle
4.JSON over COMET or WebSockets
My favourite! WebRTC signalling shouldn't be done any other way than the Web way.
Matrix
Firebase
I hope this helps!
You can make a Node.js WebSocket server or other WebSocket server to broker the connection. Here is a simple guide that gets the first client talking to the server. An alternative is PeerJS, which can handle the signaling and alleviate most of the complexity of setting up the WebRTC call.
With serverless options available, vanilla HTTP AJAX options may not be bad for scalability and costs.
Create a plain HTTP(s) API exchanging information using JSON.
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.