I've followed the instructions from https://github.com/SignalR/SignalR/wiki/Hubs
entitled "Broadcasting over a Hub from outside of a Hub".
I got this method working from within an MVC Action in the same project. Requesting the Action sends the update to connected clients.
My problem is that I need to be able to send updates from another project, in particular a WCF Web Services project. My app has an API and a web component and when API users make calls that change things, these updates need to be pushed out to the Web clients via SignalR. And calling a web service with the same code as my Test Action doesn't work.
I also tried the same code inside an nunit unit test that didn't work either.
What do I need to do to make this same method described on the Wiki work for a WCF Project?
The easiest solution is probably to provide an API on your Web Application (use MVC or the new WebAPI) that broadcasts to all connected clients. Any other application (an NT Service, an NUnit test, ...) can call that API if it wants to send a message to the clients.
You can't expect SignalR to do anything if you aren't hosting a Hub either in a Web Application running under IIS, or another application hosting it directly.
If you need two-way communication from your separate application to your clients then simply make your application into a SignalR client too and have it communicate via the Web Application hosted SignalR to the clients and have it listen to messages from them too.
For example, here's how I have configured a complex Service + WebSite + Clients solution (ignore the purple for now):
The Live Web Server allows NT Services to connect and create SignalR Groups. NT Services send to those groups. Web browsers connect to a group and receive messages send to that group. In effect the middle box becomes a pubsubhub.
I cannot get exactly what you aim. But if I understood correctly you're trying to send some kind of notifications raised inside WCF services to SignalR clients.
If that's the case; I can suggest you my approach:
I have some WCF services and a SignalR hub in the same application server. IMHO, the best way to communicate WCF with SignalR hub is by using MSMQ.
When a notification occurs inside a WCF service, it puts the notification payload into MSMQ.
On the other end, SignalR hub listens the same queue. When a message put into the queue, it gets the content and broadcasts to the hub clients. Very easy and straightforward. No extra service/hub call at the server side.
SignalR hub can listen for new queue items by using System.Messaging.MessageQueue#ReceiveCompleted method. When this event raised, SignalR hub gets the queue item and broadcasts to its clients.
Related
I'm working on a prototype which uses SignalR for broadcasting messages from the server to clients. I also communicate from clients to the server. This is possible via 2 ways: via controllers or via a method call in the SignalR Hub.
Now my question:
Why would I choose either SignalR Hub Methods or the ASP.NET API Controllers as endpoints for client commands to call? (so not for events / broadcasting messages)
And to follow up: Is it recommended to use one or both?
I read that it's not recommended to call the Hub methods from the API Controllers, because they're for the clients to call, not for the server.
Both API Controller and SignalR Hub use HTTP.
I've used:
ASP.NET Core SignalR 1.1.0
Latest .NET Core version
And following link for SignalR information:
https://learn.microsoft.com/en-us/aspnet/core/signalr/introduction?view=aspnetcore-5.0
SignalR uses HTTP to establish connection with the hub (negotiation and handshake), then after connection established, it uses one of the following protocol: websockets, server sent events, long polling and forever frame. You can read more about it here.
You want to use SignalR to stream data to the client when it needs to be streamed. Most simple example would be refresh a status of something. Imagine you need to ask the server if the document was already loaded. You would call the endpoint n# of times until you get the desired answer. With the hub, the server will call the client via SignalR that the load was completed. As you can see you will save resources and drastically lower the amount of requests you make to the server.
So what you use? Hug or Controller? It really depends for the specific operation you want to do, not the general case of broadcast data.
I have 2 web apps. One web app acts as a host (lets label as Host). All Web APIs resides here. Then the other web app calls those Web APIs (lets label as Client).
What I'm trying to accomplish is this:
Client calls a Web API using Jquery Ajax in Host and host processes this. After successful process, I want to be able to send some message in the HOST's client-side so I can update some UI.
That's the part I am unsure about. To notify the client-side of the Host so I can do some changes in UI, when the caller is in another app. I can't think of a way to pass some message so I can raise some popup, change some text, etc.
What I'm trying to accomplish is this: Client calls a Web API using Jquery Ajax in Host and host processes this. After successful process, I want to be able to send some message in the HOST's client-side so I can update some UI.
To achieve the requirement, you can try to integrate SignalR functionality into Apps.
Clients can connect to hub server, and clients can be added to two different groups, which provide a method for broadcasting messages to specified subsets of connected clients.
For more information about ASP.NET Core SignalR, you can check following docs:
https://learn.microsoft.com/en-us/aspnet/core/signalr/introduction?view=aspnetcore-3.1
https://learn.microsoft.com/en-us/aspnet/core/signalr/groups?view=aspnetcore-3.1#groups-in-signalr
I have to developed one application:-
Which will have two part ADMIN and Clients
Components of application:-
1) WCF Services:-To capture the screen's images of all clients machine through some sort of UI (say button "Capture")
2) Clients: - This will be any exe run on different machine and consuming WCF services.
So as per architecture:-
1) All clients .exe will subscribe to WCF service, so that the channel is established between client and service
Using this channel service should enable callback (instruct) to all clients (.exe on different machine) to capture the desktops image
And save it in some particular location.
Thing I know:-
1) This can be achieved with Callback mechanism in wcf.
Things I am looking for:-
How and where to generate the event so that all clients are instructed to capture desktop image.i.e how to use wcf service in some sort of UI (say button)"Captureā. When admin click on capture button the event should raise to all the clients to capture the screen.
Please help how to perform this task with WCF callback
Actually, you have given the answer yourself already. The admin needs to use a UI to trigger the event. So this UI is yet another client for the WCF service. Your service needs to be configured as InstanceContextMode.Single in order to have only one instance with the shared state (i.e. the list of registered clients). You will have to think about concurrency as well when you have shared state.
The button in the admin UI can then trigger a method in the same WCF service that will use the callbacks to notify the clients.
I am currently developing a WCF duplex Service for 2 clients. The first client would be an asp.net webpage which upon receiving a posting, it will send the data over to the service. When the service receives the data, it will then AUTOMATICALLY send it to the second client which is a winform app through the callback channel...
To make it simpler.
Asp.net will invoke the wcf
The wcf will reside on the iis server, same as the asp.net
WCF will require to send a data to the windows form application that is running on a client side. Only 1 instance of this application will be run at a time.
Your service should know nothing about the clients attached to it. Doing so pretty much breaks the intention of WCF.
A better solution might be to have your clients subscribe to "events" that your service can fire off. Or maybe the client can provide some information in their requests that indicates a service and method to call back to when needed.
Here is my scenario, and it is causing us a considerable amount of grief at the moment:
We have a vendor web service which provides base level telephony functionality. This service has a SOAP api, which we are leveraging to build up a custom UI that is integrated into our in house web apps. The api functions on 2 levels. You make standard client calls into the service to initiate actions, such as Login, Place Call, Hang Up, etc. On a different thread, the service sends events back to the client to alert the user of things that are occurring on the system (agent successfully logged in, call was disconnected, etc).
I implemented a WCF service to sit between the web server and the vendor service. This WCF service operates in duplex mode, establishing a 2 way connection with the web server. The web server makes outbound calls to the WCF service, which routes them to the vendor's web service. Events are received back to the WCF service, which passes them onto the web server via a callback channel on the WCF client. As events are received on the web server, they are placed into a hash table with the user's name as the key, and a .NET queue as the value to hold the event. Each event is enqueued to the agent who owns it.
On a 2 second interval, the web page polls the web server via an ajax request to get new events for the logged in user. It hits the hash table for the user key, dequeues any events that are present, and serializes them back up to the web page. From there, they are processed in order and appropriate messages are displayed to the user.
This implementation performs well in a single user scenario. The second I put more than 1 user on the system, I start getting frequent timeouts with the following CommunicationException:
A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond
We are running Windows Server 2008 R2 both servers. Both the web app and WCF service are running on .NET 3.5. The WCF service is running under the net.tcp protocol in duplex mode. The web app is ASP.NET MVC 2.
Has anyone dealt with anything like this scenario? Is there a more efficient way (or a widely accepted pattern) to implement this?
EDIT: One thing I forgot to mention - my thought is that the increased traffic (adding additional users) with only 1 dedicated callback channel is causing locking, which then triggers the timeout. There can be up to 10 consecutive callbacks from the service within any 5 second interval.