Using Redis with SignalR - c#

I have an ASP.NET MVC application that runs on server A and some web services that run on server B. I have implemented real-time notifications for which I have used SignalR on server A. But now I need server B to also be able to send messages to a View served from server A (the main web application). Hence, I am trying the tutorial here to involve Redis backplane.
In my startup in server A, I have added the following:
GlobalHost.DependencyResolver.UseRedis("localhost", 6379, string.Empty, "abc");
app.MapHubs();
Here, I assume that "myApp" indicates the channel and when I run publish abc "hello world" on the Redis console, I can see the subscriber count returned as 1, but I am not able to figure out how a SignalR hub interacts with the channel. Where do I receive the message on the server/view? Can we subscribe to only one redis channel? Can't we dynamically configure to subscribe to a particular channel?
EDIT: I can see messages sent from chat Application implemented using SignalR on redis console if I subscribe to abc.
Also for now I have implemented my own redis listener on server A which in receiving a message from redis channel, calls the signalR hub function. I am sure there must be a different way to do this and I am hoping redis backplane can help me but unsure how it works.

Backplane distributes messages between servers.
GlobalHost.DependencyResolver.UseRedis("localhost", 6379, string.Empty, "abc");
Here, abc is the redis channel, that means whichever server is connected to redis server with this channel, they will share messages. SignalR channel (group) is different than Redis channel. You can share also SignalR channel (group) messages.
Then just install the Microsoft.AspNet.SignalR.Redis NuGet to your servers.
Connect your servers to Redis like this:
GlobalHost.DependencyResolver.UseRedis("server", port, "password", "AppName");
app.MapSignalR();
Then, use your signalr as before. You don't have to do anything else.
When Server A sends a message to the clients, it will send the message first to Redis. Then Redis will share the message with all subscribers (servers A and B). Then, A and B will send the message to their clients. (Also viceversa is true, it will be same for if B sends a message).
Let's say A sends a message to the clients. _context.Clients.All.TestMessage("Hello");
This will go first to redis and redis will share this with A and B.
Then both A an B will send this message to their clients.
_context.Clients.All.TestMessage("Hello");
But you don't have to worry about these kind of things. I said before. Install package, conntect your servers to redis and use signalr as before.
If we come in your question. The answer is Yes. Server B can send messages to server A clients by Signalr Backplane.
This image summarizes what I told:

Related

Full Duplex Communication with RabbitMQ

We have a messaging application that uses SignalR on a .NET Framework service to connect to clients of various kinds (native mobile + web in the browser). We're looking at potentially replacing SignalR with RabbitMQ to be able to facilitate communication back and forth between the service and various clients in a full duplex fashion. Would this be a viable usecase for RabbitMQ? In the RabbitMQ tutorials I didn't see a specific example that matched. the RPC example is close but it looks like the client initiates the connection, the server gets it, processes it and sends a reply. The connection is blocking from the server side. Is a usecase possible where both the client and the server are producers as well as consumers and they can asynchronously send/receive messages via the queues that they are subscribed to?
I'm not really sure where to ask this, if it's better asked on a different stack exchange please let me know.

Grpc - send message from one client to another client that is connected to the same server

Is it possible to send message from one client to another client that is connected to the same server?
I want send data from one client to server Then send to specific client. I think I need to get client ID but I dont know how to get this id and how to send this message to that client from server.
I have a sample here. This is a chat server-client application. Multiple clients can connect to the server. When a client writes a message, the server simply broadcasts it for all clients who are receiving server stream RPC.
https://github.com/cactuaroid/GrpcWpfSample
See these server side implementation. When a client calls Subscribe(), it awaits m_chatService.Added event. When a client calls Write(), it raises the event and event args ChatLog is written on responseStream.
https://github.com/cactuaroid/GrpcWpfSample/blob/f6e8c4b2493c23cdcbaffeca29b5bb6705fbe95c/GrpcWpfSample.Server/Grpc/ChatServiceGrpcServer.cs
https://github.com/cactuaroid/GrpcWpfSample/blob/f6e8c4b2493c23cdcbaffeca29b5bb6705fbe95c/GrpcWpfSample.Server/Model/ChatService.cs
You can add your logic such as specifying channel name to subscribe/write, or define OpenChannel(string password) to be called by client at the first time so that server can bind the client IP address to the channel, whatever as you like.
There's no special gRPC feature that would allow you to do this (all RPC are between a server and a client, there's no "broadcast" or "selective broadcast" feature to reach out to other clients connected to the same server.
The logic you want is something that can definitely be implemented and but details of such solution depend on your need. A naive approach that might work is e.g. this:
each client opens a bidi-streaming call to the server
server keeps a directory of connected clients
once server receives a message from a client, it selects which client it should forward to based on the directory.
server forwards the message to a client.
Needless to say this setup feels a bit complicated (you're basically implementing your own network protocol on top of gRPC), so even though it might be just the right thing for you to do, it would make sense to think about how to simplify the protocol so that you can use features directly supported by gRPC.

Can a WCF service use SignalR to notify clients of a change?

I have a mature client/service project that uses WCF services for the data access. These are called from a WPF client.
We now want to add notifications to the project, so have been looking at SignalR to push those notifications to the clients. This all works fine when it's SignalR itself that's initiating the push, say a client sends a SignalR notification to the server, the server can then notify all other clients.
However, as all of our data access is done via the WCF services, I want to be able to send out a SignalR notification in response to a WCF service call. For example, a client calls the UpdateCustomer() service call, which saves the modified customer data to the database. I then want to notify all other clients of the change. However, at this stage I'm in the WCF service code, not the SignalR code.
How do I tell SignalR to send out a notification?
Ah, found it just after posting!
Predictably, it was in the SignalR docs, How to call client methods and manage groups from outside the Hub class.

Broadcasting message from web api to UWP app

The server will be a web API in .Net and client is UWP app.There are some messages stored in the database along with the expiry time and deviceId.Each message should be broadcasted to the device on the expiration of time.How can we keep a persistent connection from web API to UWP and how can we broadcast the message to a particular device.Thanks in advance for all suggestion!
In the case you will you signalR (which will be a good solution) I suggest you to read:
https://learn.microsoft.com/en-us/aspnet/signalr/overview/guide-to-the-api/hubs-api-guide-server
Simple create a hub on server. Each client then should connect to this hub. After the connection is established you can send messages in both directions.
Here are some possibilities for sending messages from server to client:
Send message to all connected clients:
Clients.All.addNewMessageToPage(name, message);
To specific client:
Clients.Client(Context.ConnectionId).addContosoChatMessageToPage(name,
message);
There are a lot other possibilities like groups.
The best solution for your scenario would be WebSockets. These allow you to implement a lightweight two way connection between your app and the API and send data between them. Info on UWP implementation of WebSockets is here in documentation and for server side you can use ASP.NET SignalR for example.

Use signalR websockets to listen to a non signalR server?

I have a websocket connection where I want to constantly listen and receive events on that websocket's URL. It's a status watcher, and I will be returned a json on a regular basis. I have a signalR client that is listening to a server/hub on one point. There is also a third device, not the signalR server or the battery, that has a websocket connection.
Is it possible to setup a SignalR client, point it to a websocket server that is not signalR, and just listen to all the traffic that way? I have a listener already in the SignalR client built in, could I make a "second hub" and have it listen also to the other websocket on the other device? It's not one I have control over, and is not a SignalR server, but since it's a websocket connection, shouldn't I be able to read off of it?
Here is a high tech diagram to help.
SignalR client cannot connect to any websocket. First, websocket is just one transport that SignalR uses but not the only one. If the client cannot connect to the server it will by default automatically switch to a different transport (e.g. server sent events or long polling). Second, SignalR uses a protocol to talk to the server (if you are interested you can find the protocol description here) - if the protocol is not followed the client won't be able to connect to the server. Hence the SignalR client can only work with a SignalR server.

Categories

Resources