Server-Sent Events queries - server-sent-events

We have a requirement wherein the server needs to push the data to various clients. So we went ahead with SSE (Server-Sent events). I went through the documentation but am still not clear with the concept. I have following queries :
Scenario 1. Suppose there are 10 clients. So all the 10 clients will send the initial request to server. 10 connections are established. When the data enters the server, a message is pushed from server to client.
Query 1 : Will the server maintain the IP address of all the client? If yes is there an API to check it?
Query 2: What will happen if all the 10 client windows are closed? Will the server abort all connections after a period of time?
Query 3: What will happen if the Server is unable to send messages to client due to unavailability of client like machine shutdown. Will the server abort all connections after a period of time for those client for whom they are unable to send the message?
Please clarify?

This depends on how you implement the server.
If using PHP, as an Apache module, then each SSE connection creates a new PHP instance running in memory. Each "server" is only serving one client at a time. Q1: yes, but not your problem: you just echo messages to stdout. Q2/Q3: If the client closes the connection, for any reason, the PHP process will shutdown when it detects this.
If you are using a multi-threaded server, e.g. using http in node.js. Q1: the client IP is part of the socket abstraction, and you just send messages to the response object. Q2/Q3: as each client connection closes the socket, the request process that was handling it will end. Once all 10 have closed your server will still be running, but not sending data to any clients.
One key idea to realize with SSE is that each client is a dedicated socket. It is not a broadcast protocol, where you push out one message and all clients get exactly the same message. Instead, you have to send the data to each client, individually. But that also means you are free to send customized data to each client.

Related

Track State changes in Corda

I am planning to use vaultTrack method to track the changes in state object.Once I capture the events at client level am planning to store those data in offline DB or invoke another API. Will there will be any challenge in this implementation. As per my understanding RPC client library will be listening all the time for state changes and also it handles the incoming RPC calls from external parties . Will it slow down the performance. How exactly vaultTrack method working internally .
Hi I don’t see any challenge in your implementation.
In Corda we use Apache Artemis for RPC communication. The Corda-RPC library must be included on the client side in order to connect to the server.
Internally this works like this -
At startup Artemis will be created on the RPC client(client side) and RPC server (within the corda node), client and server queues are created, and sessions are enabled/established between client and server. The Corda-RPC library contains a client proxy, which translates RPC client calls to low-level Artemis messages and sends them to the server Artemis instance. These RPC requests are stored on the server side in Artemis queues. The server side consumer retrieves these messages, approprite RPC calls are made, and an acknowledgement is sent to the client. Once the method completes, a reply is sent back to the client. The reply is wrapped in an Artemis message and sent across by server Artemis to the client Artemis. The client then consumes the reply from client Artemis queue.
The client proxy within the the Corda-RPC library abstracts the above processes. From a client perspective you should only create the proxy instance and make the RPC calls.
I would urge you to use the Reconnecting Client. You can read more about this in a blog which I have written.
Also please read the last part in the blog which talks about how to handle reconnection/failover scenarios.

signalr scaleout sending message to only particular client

As I went through the documentaion of signalr scaleout options having a backpane, i see the backpane job is to send the message from one server to all signalr servers. If so, if Server 1 wants to send message to particular client, the message goes to backpane and from there to all other servers(ex. server 2,3)..where the client 1 is connected with Server 1. So can we restrict this to send only from server1 to client 1. Also the other question, are the events like connected, reconnected also will be routed to backpane and to all other servers ?
thanks
If you are using a SignalR backplane, all messages will be sent to all servers. There is no way to configure a SignalR scaleout provider to only send messages to specific servers. It's all or nothing.
If you choose to forgo a backplane, you could of course configure SignalR to use its default in-memory message store and then manually send inter-server messages.
Events like connected/reconnected/disconnected do not involve publishing messages so no messages will be routed to all other servers.

Are all clients in a group assured to receive signalR calls when SignalR is scaled out behind load balancer?

I've been looking into SignalR implementation incorporated with a load balancer
and have a few basic (if not simple sounding) questions.
I must preface this by saying I've got zero (0) experience with load balancers.
We will have 2 servers sitting behind a load balancer.
The client is an ASP .Net application.
We've been told that the load balancer maintains session affinity.
Consider the following scenario:
Client1 & Client2 -- connect to GroupA--> Server1
Client3 & Client4 -- connect to GroupA--> Server2
1) Server1 makes a client call to GroupA - this assumes that
Clients 1-4 will get the notification, correct?
2) How does the processing occur on this?
3) Is it a function of SignalR itself, or the load balancer?
4) When sending messages at the group level, do messages only get delivered to the client
apps associated with the group on that specific server, or will messages get forwarded
to all clients of that group?
Does anyone have any thoughts on this?
Thanks,
JB
I believe the scenario you're looking at requires a SignalR Backplane to be setup.
Here's a relevant selection from the article but you'll want to read the full thing to answer your specific questions:
Each server instance connects to the backplane through the bus. When a
message is sent, it goes to the backplane, and the backplane sends it
to every server. When a server gets a message from the backplane, it
puts the message in its local cache. The server then delivers messages
to clients from its local cache.

SignalR not invoking result with DNS alias on client

I connect to my server, which is load balanced for an alias to point to 2 servers, 01 & 02 and it round-robins connections for arguments sake. I can connect to the hub without a problem, and I can even send stuff to the server, but when it goes to return it to the client, I never get my methods invoked. If I bypass the load balancer and use the server name explicitly, it always works just fine.
I'm even tracing it, and I send back the message from the exact originating server with the Clients.Client(clientId).completeJob(stuff), and that executes fine on the server, but if I ContinueWith, it never gets finished.
Oh, and it's connected with server sent events. Am I missing something or is this just not supported?
Server-sent events establishes a long running connection, but unlike WebSockets, it isn't bidirectional. The connection can only be used to push data to the client.
SignalR uses regular XHRs to send data from clients when the WebSocket transport is unavailable. This means that the load balancer will likely route client-to-server hub method invocations to a server different than the one the client originally established a server-sent event connection with.
The server executing Clients.Client(clientId).completeJob(stuff) likely doesn't own the connection that would allow it to push a message to the specified client. (Though returning a value from a hub method on the server will send data back to the client via the same connection that invoked the method.)
SignalR can work behind a load balancer. It just requires a little more setup so all the SignalR servers can communicate with each other via a backplane such as Service Bus or Redis. This allows messages to get dispatched to the server that owns the server-to-client connection.
https://github.com/SignalR/SignalR/wiki/Azure-service-bus details how you can setup a Service Bus backplane on Azure.

Chat Application in ASP.NET

I've to write an Ajax chat web application in ASP.NET for a friend, and I've a question: if client1 sends a message to client2, how should the application send the message to client2? Is there a better way than sending requests to the server, "asking" if there are new messages? Is it possible to directly send the message to the client?
Best thing you can do is use a Persistent HTTP Connection. The way google does with Google Talk on their GMAIL website.
Remember that HTTP is a stateless protocol and that each transaction is made from the client to the server.
The server can use sessions to determine if this client is "known" but as for sending information back to the client using plain old HTTP I think that is impossible (I mean from a server initiated connection, not a response to the client)
You would need to use Javascript to poll the server for information.
If you want it the other way around, you could possibly use Java or Flash but then you also need to think about NAT tunneling, proxy servers and any other weird setups that the clients could be using.
No. I don't think the server can send message to client's browser.
Here is how I implement chat application:
client1 post message via Ajax to server
server save it to repository (I'm using singleton object for this case)
client2 get the message from repository
mark the message as read
I will save chat logs to database once the chat session closed or expired.

Resources