I have below requirements:
(1) Perform 'action A' when user requests for it.
(2) We also want to perform the same 'Action A' twice in a day even if users don't request for it.
I have a WCF web service which has method XYZ that performs action A. The method XYZ will be called when user requests for it.
Now question is, can I schedule this action without creating window service (which can host this service) or creating proxy?
Is there a way to perform an action by user request and schedule that same action, using only one application?
No, WCF cannot be auto-scheduled. You need to implement a Scheduled Task (see Scheduling jobs on windows), a Windows Service with a timer (which you've said you don't want to do, if I understand correctly) or some other application with a timer.
You could start a thread as per the other answer but this relies on your service calling itself - I'd prefer to call it externally, from another process.
A scheduled task can run an executable. You could write a console application that calls your WCF service, logs any result (if necessary) and then completes.
I normally prefer to implement this type of timer through a Windows Service, simply because the Windows Service can be monitored, can log, and can auto-start / auto-restart - install it and it 'just works'. If I didn't want to use a Windows Service then I'd schedule a task.
I typically do this by just calling the WCF service method from some kind of task scheduler. In a really simple form, you could just spawn a Thread from your service, that runs the WCF method periodically. Again this isnt the best solution, but its easiest to demonstrate. You could use some other scheduler library to do this too...
[ServiceContract]
public class SomeClass
{
[ServiceOperation]
public void SomeServiceMethod() { ... }
Then somewhere in the application startup:
Thread t = new Thread(new ThreadStart(CallService));
t.Start();
...
// this will call the WCF service method once every hour
public void CallService()
{
Thread.Sleep(3600000); // sleep 1 hour
new SomeClass().SomeServiceMethod();
}
This is one way to do it, although not the best way, but basically you can just call the WCF service method just like any other method in the application.
Related
We have a WCF service called service1 hosted in IIS.
We are creating another WCF service, say, service2, which will always be running in the background and will monitor if a file, say, X, is having enough data that has to be consumed by Service1.
If the file X is not having enough data then service2 will call another component which will load the data to the file.
So please suggest a hosting technique for service2 which fulfils all the above requirements and should be independent, i.e if the service2 is down, it should not impact service1 or vice versa. Both these services are a part of the same app-domain.
We have one scenario where we hosted the same as a window service. Now we are looking to try something else.
Please provide your valuable suggestions.
You're looking for the right kind of screwdriver to hammer a nail. 8-)
WCF services run on demand, based on network activity (a request comes in, the service runs and handles the request). However after a defined period with no activity the service shuts down and the resources are released, and the server waits for the next request, however the existence of a file containing the data you want does not create this type of request.
What you need is a Windows Service (the things that you see in the Services Control Panel). These run continuously and are appropriate for tasks that don't produce network requests, like monitoring to see if you have the data you need.
We have one scenario where we hosted the same as a window service. Now we are looking to try something else.
There really isn't anything else suitable for unattended operation. Windows Services are designed exactly for this type of task, while WCF Services aren't.
Apart from your hosting requirement you should also consider using a FileSystemWatcher if you haven't done so already. You would obviously have to add your own logic to meet your requirements.
Basic example:
protected override void OnStart(string[] args)
{
FileSystemWatcher Watcher = new FileSystemWatcher("some file path");
Watcher.EnableRaisingEvents = true;
Watcher.Changed += new FileSystemEventHandler(Watcher_Changed);
}
// This event is raised when a file is changed
private void Watcher_Changed(object sender, FileSystemEventArgs e)
{
// your code here
}
More complete example:
http://www.rhyous.com/2012/11/27/c-creating-a-service-to-monitor-a-directory/
I have 2 WCF services implemented in C# that test a client-server interaction of a 3-rd party application. Let's say I have a server-side tester interface for WCF test service (I skipped the attributes ans simplified the interfaces)
interface IServerTester
{
bool Start();
}
And a client side one:
interface IClientTester
{
bool Start();
}
The purpose of those methods is merely to start the server and to start the client of the 3-rd party application. I am using NUnit to test it. On the upper level it looks like a C# transaction script, where I first start a server, then a client and lastly verify that they are communicating.
Later, I want to easily add more clients (start more than one), thus I need to add more WCF calls to IClientTester in my transaction script.
I can do something like this, with each client has its own endpoint
//Start server
//start client 1
//start client 2
//...
//start client N
I will need to reuse the code in many other tests.But it seems to be a rather long solution. Is there any better idea, or perhaps a pattern that I can adopt? Many thanks!
I'm not sure I completely followed your question, but it sounds to me like a need for Pub/Sub. It sounds like when the server starts, you want 1:M clients to be notified and also start, correct? If so, then the server could publish a message or event that the "clients" all subscribe to. You would not need to modify anything to add new clients, simply subscribe to the message or event in the new client implementation.
From a little bit of reading around, it is my understanding that the only way to detect that a client has connected to my service is through writing my own code. I am using a Singleton service. I would like to display a message every time a client connects to my service that client x with ip xxx has connected. There is no built-in event that is generated? Am I correct?
No, I don't think there's any support in WCF for your requirement.
Not sure what you want to achieve with this, either. Your service class (in your case, just a single instance) really doesn't have any business putting up messages (on screen, I presume) - that really not it's job. The service class is used to handle a request and deliver a response - nothing more.
The ServiceHost class might be more of a candidate for this feature - but again, it's job really is to host the service, spin up the WCF runtime etc. - and it's really not a UI component, either.
What you could possibly do is this
have an Admin UI (a Winforms, console, or WPF app) running on your server alongside your service, providing an admin service to call
define a fast connection between the two services (using e.g. netNamedPipe binding which is perfect for intra-application messaging)
when your "real" service gets a call, the first thing it does is send out a message to the admin UI which can then pick up that message and handle it
That way, you could cleanly separate your real service and it's job (to provide that service) and the Admin UI stuff you want to do and build a cleanly separated system.
I have actually implemented my own connect, disconnect and ping service methods which I manually call from my client once the channel has been created. By using them as a kind of header section in all of my ServiceContract interface definitions (and their implementations, of course), they form an makeshift "base service definition" that only requires a bit of cut-n-paste.
The string-based parameters of connect and disconnect will be used to send client info to the server and return server info and (perhaps a unique connection id) to the client. In addition a set of timing reference points may make its way in also.
Note how SessionMode is required and the individual OperationContract properties IsInitiating and IsTerminating are explicitly specified for each method, the end result being what I would call a "single-session" service in that it defines connect and disconnect as the sole session bookends.
Note also that the ping command will be used as the target of a timer-based "heartbeat" call that tests the service connection state and defeats ALL connection timeouts without a single config file :-)
Note also that I haven't determined my fault-handling structure yet which may very well add a method or more and/or require other kinds of changes.
[ServiceContract( SessionMode = SessionMode.Required )]
public interface IRePropDalSvr {
[OperationContract( IsInitiating=true, IsTerminating=false )]
string connect (string pClientInfo);
[OperationContract( IsInitiating=false, IsTerminating=true, IsOneWay=true )]
void disconnect (string pClientInfo);
// ------------------------------------------------------------------------------------------
[OperationContract( IsInitiating=false, IsTerminating=false )]
string ping (string pInp);
// ------------------------------------------------------------------------------------------
// REST OF ServiceContract DEFINITION GOES HERE
One caveat: while I am currently using this code and its implemention in my service classes, I have not verified the code yet.
I'd like to know if it's possible to call a method on a WCF windows service while another one is executing ? I need this so I can call my Terminate method that sets a static variable shared by my threads that tells them to stop. But when I call the method on the service, it waits till the first one (Execute) is over before he takes the call...
You need to set the concurrency mode of the service behavior to ConcurrencyMode.Multiple like this:
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)]
class MyService : IMyContract
{
// ...
}
In this situation the framework will not try to synchronize access to the service instance allowing to execute multiple operations at the same time.
I have a WCF service setup to control a USB fingerprint reader from our .Net applications. This works fine and I can ask it to enroll users and so on.
The reader allows identification (it tells you that a particular user has presented their finger, as opposed to asking it to verify that a particular user's finger is present), but the device must be constantly polled while in identification mode for its status - when a user is detected the status changes.
What I want is for an interested application to notify the service that it wants to know when a user is identified, and provide a callback that gets triggered when this happens. The WCF service will return immediately and spawn a thread in the background to continuously poll the device. This polling could go on for hours at a time if no one tries to log in.
What's the best way to acheive this? My service contract is currently defined as follows:
[ServiceContract (CallbackContract=typeof(IBiometricCallback))]
public interface IBiometricWcfService
{
...
[OperationContract (IsOneWay = true)]
void BeginIdentification();
...
}
public interface IBiometricCallback
{
...
[OperationContract(IsOneWay = true)]
void IdentificationFinished(int aUserId, string aMessage, bool aSuccess);
...
}
In my BeginIdentification() method can I easily spawn a worker thread to poll the device, or is it easier to make the WCF service asynchronous?
I think it is much better to make the WCF service operation asynchronously. This MSDN article shows how to do it:http://msdn.microsoft.com/en-us/library/ms730059.aspx.