I have WCF service using netTcpBinding (so default InstanceContextMode=PerSession).
Service is being called from ASP.Net Web Application using code similar to:
ServiceClient service = new ServiceClient();
service.ServiceMethod1();
service.Close();
So, we create a proxy instance here - call the required method and - close the service.
Query -
When do we say that a WCF Session is created?
Is it correspond to one ASP.Net Session... so suppose one user having an ASP.Net Session, whatever calls this user will make to service from his session will also mean a WCF session?
Thank you!
When do we say that a WCF Session is created?
When you first call the service from a new proxy instance.
Is it correspond to one ASP.Net Session... so suppose one user having an ASP.Net Session, whatever calls this user will make to service from his session will also mean a WCF session?
No. WCF session doesn't work in the same way as ASP.NET session. WCF session is with out of the box implementation maintained per proxy. Once you close your service client the session is gone.
Related
I'm developing a UWP client project which need to consume some services of a WCF server. I uses the "add service reference" tool of Visual Studio to auto generate service clients(proxies). The binding type is NetTcpBinding. Below is some code snippet which create the service client:
NetTcpBinding tcpBinding = new NetTcpBinding();
tcpBinding.Security.Mode = SecurityMode.None;
tcpBinding.Security.Transport.ClientCredentialType = TcpClientCredentialType.None;
tcpBinding.Security.Message.ClientCredentialType = MessageCredentialType.None;
MainServiceClient = new MainServiceClient(tcpBinding, new EndpointAddress("net.tcp://localhost:8773/MyWCF/MainService/tcp"));
The question is do I need to call OpenAsync() method of MainServiceClient? It seems the service client can be auto opened when it is first called. But I read from this article that auto-opened service client would have some performance penalty. The article was written in 2007. I just wonder if this mechanism have changed today, especially in UWP project. Can anyone share more light on this topic? Thanks!
To explain this case, you should know three ways to do WCF instance management. WCF has provided three ways by which you can control WCF service instances:Per call, Per session, Single instance.
When we configure a WCF service as per call, new service instances are created for every method call you make via a WCF proxy client.
Very often we need to maintain state between method calls or for a particular session. For those kinds of scenarios, we will need to configure the service per session. In per session, only one instance of a WCF service object is created for a session interaction.
Often we would like to create one global WCF instance for all WCF clients. To create a single instance of a WCF service, we need to configure the WCF service as Single instance mode.
And there are three ways by which you can handle concurrency for each service instance in WCF :single, multiple, and reentrant.
Single: A single request has access to the WCF service object at a given moment of time. So only one request will be processed at any given moment of time. The other requests have to wait until the request processed by the WCF service is completed.
Multiple: In this scenario, multiple requests can be handled by the WCF service object at any given moment of time. In other words, requests are processed at the same time by spawning multiple threads on the WCF server object. So you have great throughput here but you need to ensure concurrency issues related to WCF server objects.
Reentrant: A single request thread has access to the WCF service object, but the thread can exit the WCF service to call another WCF service or can also call a WCF client through callback and reenter without deadlock.
In "Instance mode = Per Session and Concurrency = Single" combination, one WCF service instance is created for every WCF client session because the WCF instance mode is set to per session. All the method are executed in a sequential manner one by one. In other words, only one thread is available for all method calls for a particular service instance.
For the above scenario, you should always open WCF client proxy explicitly before you are making any calls. Because it will maintain service state between method calls and obtain high performance.
For more detail you could refer to "WCF Concurrency (Single, Multiple, and Reentrant) and Throttling" and "Three ways to do WCF instance management".
I am new to authentication and authorization concepts. I wrote an authenticate method in my wcf servcice. Methods in wcf service will get called only by authenticated users with specific roles. How does the security context automatically get loaded before each request to wcf service?
Since you are looking to reach the authenticated identity, then the following link should be helpful:
http://msdn.microsoft.com/en-us/library/aa347790.aspx
EDIT: If you want to automate this, you should write a wrapper for your service host (i.e: a class that inherits from ServiceHost) to encapsulate that inside your service host rather than having to write it over and over again.
If I set my servis instance as Per Session or Single can I send some data between services instance in session? It should be done in Asp.net session - HttpContext.Current.Session
or wcf have own session ?
As I said - WCF is not ASP.NET and its session handling is vastly different. While ASP.NET sessions and WCF sessions are called the same - they are vastly different in their purpose and usefulness.
Read the MSDN page Using Sessions in WCF for more details.
One sentence reads: There is no general data store associated with a WCF session. - so the answer is no - sessions in WCF are not meant for data storage.
WCF sessions are merely to "tie together" several messages into a conversation. By default, with the "per-call" model, each WCF service request would get its own, freshly instantiated service class instance to handle the request, and that service class instance will be freed after returning the answer. Using sessions avoids this - the service class instance handling the first call of a session will stay alive on the server side (and thus also taking up memory on the server) and will handle all subsequent requests within the same session.
WCF and web services in general should however preferably be stateless, so sessions are a bit of an oddball architecture in a proper SOA environment - and that's most likely why sessions in WCF are also not nearly as useful as ASP.NET sessions are for web apps.
To remain stateless and support the per-call method (the preferred best practice), if you need to store data between calls, store it in a persistent store (e.g. a database) and fetch it back from there when needed later on.
If you're hosting services in IIS, you can enable ASP.Net Compatability mode. This will allow you to use ASP.Net session state, just like you would in a web application.
When Impersonating a client to a web service, do I need to call it once, or do I need to call it several times, each times I call the client essentially.
client.ClientCredentials.Windows.AllowedImpersonationLevel =
System.Security.Principal.TokenImpersonationLevel.Impersonation;
I call my client several times in the course of my controllers. I only call this once. I can't seem to get past the first page of my website though (this website an MVC2 website) calls my WCF webservice.
A little confused here. If you guys can be of any help I would greatly appreciate it. Thanks.
Impersonation is allowed per proxy (client channel) instance so if you create a new proxy instance (a client) for different controllers / actions you have to configure it for each proxy instance. Once you have created instance you can do multiple calls to the service on that instance and it will correctly impersonate the client. Be aware that you should create a new proxy instance for each MVC action which needs to communicate with WCF service.
Btw. Are you trying to impersonate an original user (the user accessing your MVC application) or an user account running AppPool hosting the MVC application? If the first case is your scenario you can have problems because impersonation is limited to a single network hop. That means that an user can be impersonated on the server hosting the MVC application (first hop) but if the WCF service will be on an another server (second hop) impersonation will not work there (because of single hop limitation). In such scenarios you need delegation instead of impersonation and delegation requires correctly configured Kerberos.
I have to create a WCF web service that proxies an IMAP service (so that it can be consumed by a SL application).
The IMAP service requires that first the Login(credentials) method is called, to authenticate with the IMAP server. After the Login method is called the connection is kept open and other operations can be performed.
Does anybody know how can achieve this with a WCF service?
One solution I want to avoid is the proxy to login for every operation it has to perform (as the login operation usually takes 1-2 seconds). And I would have to pass the credentials every time: GetMail(credentials), GetFolders(credentials), etc.
I know it is highly recommended that WCF services not to be stateful, but it seems I need to keep the state of IMAP connection for every client. How can I do this?
Thanks!
This is one of those rather rare cases where I think using WCF sessions makes sense:
your first call that calls the IMAP Login method starts a WCF session
any subsequent call will be using the same session
some final call (e.g. something like a Done or Logout) will terminate that session
With a session in WCF, your service class on the server stays in memory for the duration of the entire session, i.e. it's not constantly re-created, and thus you can keep the IMAP connection "live" inside your service class.
Resources:
Sessions, Instancing, and Concurrency (MSDN)
Using Sessions (MSDN)
WCF Sessions - a brief introduction
WCF Sessions
Per-Session Instance Management in WCF
Be aware: WCF sessions are NOT ASP.NET sessions - those are two totally different things! Just to be clear from the get-go.
Also: only a handful of WCF bindings support sessions - netTcpBinding, wsHttpBinding and netNamedPipeBinding (as far as I know)