Any recommendations to host a WCF service? - wcf

Have a winform application and want to host a WCF service inside it. Do I need to host it in a seperate appdomain? Any recommendations?

You don't need to host it in separate domain but you must decide if you want service request to be processed by UI thread or different thread. It depends on the way you create ServiceHost instance or on ServiceBehavior applied to your service class.
When service is hosted in UI thread it can directly interact with UI but request processing is part of message loop and all service requests are processed by single thread (sequentially). When request is processed no other windows event (including UI events) can be processed = application freezes.
When service is hosted in different thread it behaves as in any other hosting environment but it can't directly interact with UI - you must use delegate invocation.
Ways to enforce service to run in own threads:
Create and open ServiceHost instance before you call Application.Run (start of Windows message loop)
Create and open ServiceHost instance in separate thread
Use [ServiceBehavior(UseSynchronizationContext = false)] on your service implementation

No, you don't have to host it in a separate AppDomain. Just host it. There's nothing terribly special about WinForms in this regard.

What's your app do? Is the service a part of the apps regular functions or a completly seperate logical entity?
If you want to be loading and unload resources (such as assemblies) related to your service without shutting your app down a seperate app domain would make this much easier, but otherwise I don't see much of a reason to complicate things.
Just my 2c. :-)

You can host in Win form but you have to keep it running throughout.
Also suggest you to host in IIS so any type of client avail your service.

Related

Should I Open and Close my WCF client after each service call?

I have developed a WCF service for consumption within the organization's Ethernet.
The service is currently hosted on a windows-service and is using net.tcp binding.
There are 2 operation contracts defined in the service.
The client connecting to this service is a long running windows desktop application.
Employees(>30,000) usually have this client running throughout the week from Monday morning to Friday evening straight.
During this lifetime there might be a number of calls to the wcf service in question depending on a certain user action on the main desktop client.
Let us just say 1 in every 3 actions on the main desktop application would
trigger a call to our service.
Now we are planning to deploy this window service on each employee's desktop
I am also using `autofac` as the dependency resolver container.
My WCF service instance context is `PerSession`, but ideally speaking we have both the client and service running in the same desktop (for now) so I am planning to inject the same service instance for each new session using `autofac` container.
Now am not changing the `InstanceContext` attribute on the service implementation
because in future I might deploy the same service in a different hosting environment where I would like to have a new service object instance for each session.
Like mentioned earlier the client is a long running desktop application and I have read that it is a good practise to `Open` and `Close` the proxy for each call but if I leave the service to be PerSession it will create a new service instance for each call, which might not be required given the service and client have a 1-1 mapping. Another argument is that I am planning to inject the same instance for each session in this environment, so Open & Close for each service call shouldn't matter ?
So which approach should I take, make the service `Singleton` and Open Close for each call or
Open the client-side proxy when the desktop application loads/first service call and then Close it only when the desktop application is closed ?
My WCF service instance context is PerSession, but ideally speaking we have both the client and service running in the same desktop (for now) so I am planning to inject the same service instance for each new session using autofac container
Generally you want to avoid sharing a WCF client proxy because if it faults it becomes difficult to push (or in your case reinject) a new WCF to those parts of the code sharing the proxy. It is better to create a proxy per actor.
Now am not changing the InstanceContext attribute on the service implementation because in future I might deploy the same service in a different hosting environment where I would like to have a new service object instance for each session
I think there may be some confusion here. The InstanceContext.PerSession means that a server instance is created per WCF client proxy. That means one service instance each time you new MyClientProxy() even if you share it with 10 other objects being injected with the proxy singleton. This is irrespective of how you host it.
Like mentioned earlier the client is a long running desktop application and I have read that it is a good practise to Open and Close the proxy for each call
Incorrect. For a PerSession service that is very expensive. There is measurable cost in establishing the link to the service not to mention the overhead of creating the factories. PerSession services are per-session for a reason, it implies that the service is to maintain state between calls. For example in my PerSession services, I like to establish an expensive DB connection in the constructor that can then be utilised very quickly in later service calls. Opening/closing in this example essentially means that a new service instance is created together with a new DB connection. Slow!
Plus sharing a client proxy that is injected elsewhere sort of defeats the purpose of an injected proxy anyway. Not to mention closing it in one thread will cause a potential fault in another thread. Again note that I dislike the idea of shared proxies.
Another argument is that I am planning to inject the same instance for each session in this environment, so Open & Close for each service call shouldn't matter ?
Yes, like I said if you are going to inject then you should not call open/close. Then again you should not share in a multi-threaded environment.
So which approach should I take
Follow these guidelines
Singleton? PerCall? PerSession? That entirely depends on the nature of your service. Does it share state between method calls? Make it PerSession otherwise you could use PerCall. Don't want to create a new service instance more than once and you want to optionally share globals/singletons between method calls? Make it a Singleton
Rather than inject a shared concrete instance of the WCF client proxy, instead inject a mechanism (a factory) that when called allows each recipient to create their own WCF client proxy when required.
Do not call open/close after each call, that will hurt performance regardless of service instance mode. Even if your service is essentially compute only, repeated open/close for each method call on a Singleton service is still slow due to the start-up costs of the client proxy
Dispose the client proxy ASAP when no longer required. PerSession service instances remain on the server eating up valuable resources throughout the lifetime of the client proxy or until timeout (whichever occurs sooner).
If your service is localmachine, then you consider the NetNamedPipeBinding for it runs in Kernel mode; does not use the Network Redirector and is faster than TCP. Later when you deploy a remote service, add the TCP binding
I recommend this awesome WCF tome

Running multiple instances of the same XPC service (NSXPCConnection)

Is it possible to run multiple instances of the same XPC service using the XPC APIs found in Foundation.framework (NSXPCConnection, etc.)? The docs don't provide much insight on this matter.
EDIT: Did a quick test, and it seems like only one instance of the service is running even though I created two XPC connections. Is there any way to have it run another instance?
A bit late, but the definitive answer to this question is provided in the xpcservice.plist manpage:
ServiceType (default: Application)
The type of the XPC Service specifies how the service is instantiated.
The values are:
• Application: Each application will have a unique instance of this service.
• User: There is one instance of the service process created for each user.
• System: There is one instance of the service process for the whole system. System XPC Services are restricted to reside in system frameworks and must be owned by root.
Bottom line: In most cases there is a single instance of an XPC Service and only in the case where different applications can connect to the same service (not even possible when the service is bundled with an app), will there be multiple instances (one-instance-per-app).
I believe XPC services designed for one instance per multiple connections. Probably, it is more convenient to manage named pipes with one running executable. So, the most likely it is impossible to create multiple instances simultaneously.
Since XPC services should have no state, it should not matter, whether one ore more instances are running:
XPC services are managed by launchd, which launches them on demand, restarts them if they crash, and terminates them (by sending SIGKILL) when they are idle. This is transparent to the application using the service, except for the case of a service that crashes while processing a message that requires a response. In that case, the application can see that its XPC connection has become invalid until the service is restarted by launchd. Because an XPC service can be terminated suddenly at any time, it must be designed to hold on to minimal state—ideally, your service should be completely stateless, although this is not always possible.
–– Creating XPC Services
Put all neccessary state information into the xpc call and deliver it back to the client, if it has to persist.
https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man5/xpcservice.plist.5.html
ServiceType key in XPCService dictionary: Application or User or System
But this ‘ServiceType’ is irrelevant… IF Service is embedded in an application bundle then it will only be visible to the containing application and will be, by definition, Applicaton-type services. A subsequent connection request from an application to a service will result in a new connection to an existing service.
I know I'm late to the party, but while you can't do this with plain XPC,
there's library (a component of OpenEmu) that should be able to do what you're asking: OpenEmuXPCCommunicator

How to make WCF Service with a background worker thread?

I have a WCF service that all clients connect to in order to get notifications \ reminders (using a CALLBACK interface they implement). Currently the WCF service is self-hosted, but the plan is to have it hosted in a Windows Service.
The WCF service has a 'Publish', 'Subscribe' and 'Unsubscribe' operations.
I need to have a background worker thread of some sort poll an SQL server database table constantly [every XXX minutes], and look for certain 'reminder' rows. Once it finds them - it should notify all the connected clients.
I thought of 2 ways of achieving this.
.
METHOD A :
Have a separate EXE project (don't want it to be a console, so what should it be - a Windows Service ?) that will start and run a background thread. The background thread will connect to the 'Reminder' service as one of its clients. The background thread will poll the database, and once it finds something - it will send a 'Publish' message to the WCF service, that will make the WCF service send the reminder to all the subscribed clients.
.
METHOD B :
Somehow make the background thread run within the WCF service project, and when it detects a new reminder row in the database, somehow make it 'signal' the WCF service with the info, and the WCF service will then send this info to all subscribed clients.
.
Which method is better ? Any other suggestions ?
If this is a long running process, a windows service is the perfect solution.
Your main Win Service thread will be polling the DB, queuing the results into some kind of supplier/consumer thread safe collection.
You can host a WCF service within the win service, which can then consume (remove) any results from the queue and pass them back to the client as requested (calls into the WCF will come in on their own thread)
This is a pretty common architecture, and not difficult to implement.
Method A:
If you were to create two separate hosts (i.e. one for the WCF service and one for the "Polling" service) then you really have only one option to make it all work nicely.
Windows Service communication is very limited (without the help of a service endpoint, e.g. WCF). Therefor, if you were to host your "Polling" service in a Windows Service, you must couple it with a WCF service anyway.
It is then feasible to host both services together in one Windows Service and by manually instantiating the WCF host and passing into the constructor a "Polling" service.
protected override void OnStart(string[] args)
{
//...
// This would be you "polling" service that would start a background thread to poll the db.
var notificationHost = new PollingService();
// This is your WCF service which you will be "self hosted".
var serviceHost = new WcfService(notificationHost);
new ServiceHost(serviceHost).Open();
//...
}
This is far from ideal because you need to communicate via events between the two services, plus your WCF service must run on singleton mode for manual instantiation to work... So this leaves you with...
Method B:
If you were to host the "Polling" services inside your WCF service, you are going to run into a number of issues.
You need to be aware of the number of instances of the "Polling" services that gets created. If your WCF service has been configured to be instantiated for every session, you could end up with too many "Polling" services and that may end up killing your db/servers.
To avoid the first issue, you may need to set a singleton WCF service, which may lead to a scaling issue in the near future where one WCF service instance is not enough to handle the number of connection requests.
Method C:
Given the drawbacks in Method A and B, the best solution would be to host two independent WCF services.
This is your regular service where you have subscriber/unsubscribe/publish.
This is your polling singleton service with subscribe/unsubscribe.
The idea is that your regular service, upon receiving a subscriber will open a new connection to your polling service or use an existing one (depending on how you configure your session) and wait for a reply. Your polling service is a long running WCF service that polls your db and publish the notification to its subscribers (i.e. the other WCF host).
Pros:
You are assured that there will be only one polling service.
You could scale your solution to host the regular service in IIS and the polling service in Windows Service.
Communication limitations is minimal between the two services and no need for events.
Test each service interdependently through their interfaces.
Low coupling and high cohesion between the services (this is what we want!).
Cons:
More services means more interfaces and contracts to maintain.
Higher complexity.

wcf services for interprocess communication

I have put together a .net winform application which consumes a wcf service exposed by another .net application running as a windows service.
Since the communication is within the same machine, I chose the NetNamedPipe as the communication channel, as it is the best choice suited for inter process communication in the same machine.
I want to know if I am using the correct property choices when defining the wcf service in the .net windows service.
The WCF service behaviour is defined as:
[ServiceBehavior(
ConcurrencyMode = ConcurrencyMode.Single,
InstanceContextMode = InstanceContextMode.Single)]
I chose the "InstanceContextMode" as Single so that I know objects in the wcf service are not recreated each time a wcf service method is called by the UI client.
However, while reading up the ConcurrencyMode property to choose on MSDN, I did get a little confused. At the basic level, I understand the ConcurrencyMode property dictates whether the wcf service supports a single, multiple or reentrant calls.
Does this mean, that if my UI client application is multithreaded and I call into the wcf service methods from those threads, I should choose "Concurrency" mode as "multiple" and if my UI client is not multi threaded, I should choose "Concurrency" mode as "single"? My UI client application is not running multiple threads. All operations are performed on the main UI thread through event handlers (through button clicks, combo box selections, etc...)
I am having situations where, after installing the application on a windows test machine, my UI client is sometimes not able to connect to the wcf service. It just keeps waiting on the call to the Connect method of the wcf client object and then eventually times out. I want to know if its related to the "ConcurrencyMode" choice I made. Or is this a "NetNamedPipe" communication channel problem?
Please advice.
Thanks in advance.
Subbu
Choose concurency mode as multiple only if your host object is thread safe i.e you have manually implemented locking on shared resource or your host object dont have any shared or class level objects at all. If host object is not thread safe use concurency mode as single as in this case wcf will automatically implement lock for you, only one request will be processed at a time on a context, parallel will be queued. So here decision should really depend on if your host object is thread safe or not.

Find Endpoint addresses for a service implementation without OperationContext.Current

I have a WCF service in which I would like to do some initialization-type operations based on the configured EndpointAddresses for a few different contracts implemented by the service.
The service can be (and is) hosted from within a few different Service Hosts. There is a console application which creates a service host, a windows service which creates a service host, it lives in an IIS host and I would also really like to be able to use the Visual Studio service host for debugging.
Is there any way to get a reference to the ServiceHostBase which created the instance of the service without being inside a service operation? Or maybe a better (read: trickier) way of figuring out what endpoints the service is servicing?
Let me see if I have this straight: You have a single Service implementation that is exposed from multiple ServiceHosts, and you want to do some different initialization for each servicehost? Or is it for each endpoint exposed?
It sounds to me like there are a few options here, but it depends on exactly what you want to do. If the intialization is per-host, then why not just use your own ServiceHost implementation and do the initialization there instead of the service?.
I ask this particularly because it is not clear from your description what the instance mode of your service is or when you want to run the initialization code itself.
If for whatever reason you can't do that, another option worth exploring could be to do the initialization in a custom IServiceBehavior during ApplyDispatchBehavior(), where you've got access to the service host and the service description.