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.
Related
Here’s our architecture:
JIRA webhook sends messages to a Java Jersey REST service when issues are assigned.
C# client application registers the username/host machine combo with the Java web service when a user logs into the machine
When the web service receives a message from JIRA, it finds the assignee username and sends the required data to the C# client app on the host machine(s) the user is logged into.
I’ve thought of a couple approaches to solve the web service to client message.
My first is opening a TCP port on the client and having the service send each message directly to it. This is the most straight-forward approach but makes the client a little heavy in that it maintains the list of user assigned ticket data that they can then manipulate (acknowledge or remove).
The other is having the service maintain the data model and the client requests data periodically. This makes the client simpler but then I’d have to implement a polling interval to grab data, and add some POST methods for acknowledging and removing data from the user’s list.
I was looking into different ways to have the client register a channel with the service, like ServiceStackEvents, but I can’t see a way to make that work with a C# client and Java service. Something like that would be perfect. A way for the service to send callbacks or event messages to a client based on a user filter.
If someone has some suggestions or knows of an API to help with this, please post a link so I can dig into it. The POSTs are all working swimmingly, it’s just getting the data back to the clients that I’m struggling with the best approach.
Thanks!
Client polling is not a terrible solution.
But if you want a firewall and proxy friendly duplex protocol, check out WebSockets https://en.m.wikipedia.org/wiki/WebSocket.
Suppose I have a WCF service that I bind/expose using the RabbitMQ WCF interface/binding. If I have clients that make calls to my service through the RabbitMQ WCF interface then what would happen if let's say the service goes down?
Would RabbitMQ just store the requests to that service and once the service comes up it will pass those requests to the service?
Would the client get a "service not found" message or some sort of "service is disconnected" message?
How is WCF connectivity implemented within RabbitMQ? Does RabbitMQ keep a queue where the WCF service requests go and if the service goes down then the queue just keeps growing until the service comes back online?
Through some experimenting with the WCF API it doesn't appear like the client and the server are tightly coupled. I tried to bring up multiple instances of the client without the server coming up and there was no error. When I brought up the server it saw the message from the clients and responded to each client. So it looks like the client publishes a message onto the queue and when the server piece wakes up it takes the message from the queue.
I'm working on a protocol which is designed to be implemented with SOAP over HTTP.
WSDL files are provided by a third party.
I used wsdl.exe to generated a proxy class and created a Web Service Project in VS.
wsdl.exe yourFile.wsdl /l:CS
I got a cs from a unwrapping wsdl.
Snippet:
[System.Web.Services.Protocols.SoapHeaderAttribute("chargeBoxIdentity")]
[System.Web.Services.WebMethodAttribute()]
[System.Web.Services.Protocols.SoapDocumentMethodAttribute("/ClearCache", RequestElementName="clearCacheRequest", RequestNamespace="urn://Ocpp/Cp/2012/02/", ResponseElementName="clearCacheResponse", ResponseNamespace="urn://Ocpp/Cp/2012/02/", Use=System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
[return: System.Xml.Serialization.XmlElementAttribute("status")]
public abstract ClearCacheStatus ClearCache();
Implementation 1 (Server Side)
A central system (Server) connected to devices. When a device initialized, it sends an authorisation to central system.
And Server response an authorisation message back.
I have already done with Server Side which provides all clients send requests to Server. And Server response the messages.It works well.
Implementation 2 (Central system send a message to a device)
The other part of implementation is a central system need to send message to device (ex. clear devices cache, please see a snippet above). I add those methods to web service as well.
My questions are...
How can I send a message to devices through a proxy from Web Service?
It's impossible to call a method from Web Service sending requests to device? Any suggestions?
Or I need to create a project implementing a ClearCache method and format as a SOAP message to trigger?
Thanks!
I dont think it is a good idea to allow the Central system to directly communicate with the clients (Will create a huge noise in the network if the number of devices is high and the server tries to send several messages)..
A better approach will be to allow all the messages that the server intends to send to the client to be cached locally in the server machine. The clients should periodically communicate with the server using another web service and obtain the cached information that you intend to send to the clients.
you can design a method that sends the guid of the client as a parameter in the web service call.
On the server you maintain a database and keep track of the messages that needs to be sent to the clients.
use a timer object in the clients. On elapse of the timer define a method that communicates with the server by sending its guid. On the server side use this guid as a Primary Key to identify wat messages need to be sent to the client and then reply that while returning from the message.
The client then uses this return value to decide how to respond.
I am creating a WCF service where multiple users connect to it. On my WCF I implement callback contracts so that if a user makes a specific action it can notify other computers that are connected to the same WCF service. So if Company A creates an action on the WCF service then the WCF service will make a callback to all Company A machines that are connected to it. Company B will receive no notifications for example.
Anyways so far everything works great NOW. what about in the future where there are more connections at the same time? will that cause a problem?
To avoid that problem will it be better to create a web service where connections are not held open? The problem with this approach is the callback mechanism where the web service needs to send a notification to multiple computers In order to resolve the callback problem I am going to have all machines sending a UDP packet every 10 seconds to the web server. (this will make the router open a port so that the web server can reply in case it needs to) If the web service needs to send a notification to all computers on Company A for instance then it will Send multiple UDP packets. If a computer receives a UDP packet from the web service then it knows it has to make a request to perform the callback. Should I use this approach?
I am currently developing a C# Windows Form Application that I intend to let it interact with a server. The server will receive posting from a mobile application that I have developed and whenever a posting is received, my Windows Form Application should be notified and give me a notification. In order to do this, I intend to use WCF duplex service for it.
E.g. My mobile application sends an posting over to my server. Once my server reads and receives the new posting, the service should send a message over to my winform app to alert me that a posting is received. And the UI of the winform app should update accordingly to what I want to updated. (e.g. adding new panels)
This is basically how I wish for it to work
They way this would work is
WCF Service in running on my server
Windows Form connects to my server's WCF service using Duplex Contract
Mobile app posts to a webpage
Once the webpage receives the posting, the asp.net will invoke the WCF service
WCF duplex service receives the posting and sends the information to the winform app
My winform Application aka WCF Client updates UI with this new message received
My question is, how does step 4 proceed to step 5? To be specific, how does the service sends the information over to the winform app upon receiving the posting.
To be even more specific, once the posting is received from the webpage, the service contract is invoked and the information is sent and received by the service, how does the service make use of the call back channel to send the information over to the winform app and update the UI accordingly?
The answer to this question depends on how your WCF service is hosted and how "big" the service will eventually be (in terms of number of simultaneous clients).
The simplest scenario is a self-hosted WCF service (meaning hosted in a Windows Service or as a desktop application--not in IIS). In this case, you can use InstancePerSession mode and make your service use sessions. In this case, you'll have a 1:1 correspondence between clients and instances of your service class. When a client connects, retrieve the callback reference and store it in a static list outside of the service class. When you need to send a message to one or more clients, simply iterate over (or find the desired client in) your list and call the appropriate function on the callback contract
If you need to host your service in IIS, then the situation is trickier because you have the possibility of multiple processes hosting your service, so your list can potentially get fragmented (or blown away in the event of an app pool recycle). In this case, you'll have to use something external to your service (MSMQ, perhaps) to notify other application pool processes that a message needs to be sent.
In terms of a duplex connection, you are really just able to communicate two way over that one connection, not with all connections of the service without doing some tricky thread stuff and shutting the door on any scalability (or using something outside the service to handle to pub/sub).
One solution though that may work a lot more along the lines of what you want to do would be SignalR. It allows a single client to make a request and then you can broadcast data from that request to other clients (or target it). Take a look at its info, its sole purpose is real time communication in .NET with multiple clients.
Also another note, is that you will want to use some sort of BackgroundWorker or something for your listening thread in WinForms so that the UI is not locked while the background operations are running.