I have a per call service, and in my client proxy, I close the proxy when the method has finished. So when I want to call another method, I instantiate a new proxy.
In this second call, I can see that the uuid part of the sessionId is the same in the two calls, but the id part is different.
So if I tried to compared the two sessionId are different.
I would like to know if really the id part is important or not, of if the uuid is the same, really is the same client although the id part is different.
Thanks so much.
If you close proxy then, regardless of whether the session was supported or not, service is destroyed and session is terminated, if any existed.
If you wish to share the same sessionId across many calls you need to make sure both binding and service supports session (either SessionMode.Allowed or SessionMode.Required) and perform calls within the same client.
New client = new session
Related
The project I am currently working in, we have over 30 wcf services, which are called a lot in our web application, we ran into performance issues and once of the solutions was to cache the proxy. So what we did is create a dictionary object and using the endpoint name as key, cached the channel factory object so that subsequent calls will pull from the cache rather than re-instantiating the channel factory object at every call. There are many implementations over on other forums.
But we ran into one issue, the way our system is setup is that our services reside on one or more servers, of which only one is active at any one time, if a server fails then another is used as a fail safe. When creating the channel factory before putting into the cache, we can get the latest endpoint address for a given service and then instantiate it. However in this scenario, if a server fails and we pull a channel factory object from the cache, it'll refer to an old endpoint address.
I was checking on forums whether it was possible to update the endpoint address in channel factory object, if this was doable I could update the channel factory object in the cache and use it from then, I don't think this is possible.
The only thing I came up with recently is, that we check for a possible 404 fault exception which will happen when an old endpoint address is hit, then get the latest endpoint address and recreate the channel factory, and update that in the cache.
If you guys have any other ideas, would be helpful. Kinda stuck at this point.
You can create the channel factory without specifying an endpoint address and pass it to the method CreateChannel later:
public TChannel CreateChannel(EndpointAddress address)
According to this post, I am using a data context per call, so in each method of my WCF service, I use a using block to create a new data context.
But I have some doubts in the form to work in this way.
For example, I use a method getAllCLients() from my repository to get all the clients of the data base, then the service send to the client that call the method a list with all the clients. Then the user modify the information of some of them, three for example. The modify client perhaps I can add to a list that have the modified clients.
When I want to update this three clients, I can call a method updateClients() which receive a list of modified clients. How I am use a new data context per each method, in updateCients() get a new dataContext, without entities, so I think that I have to follow this steps:
1.- create a new data context which has the clients that I want to update. SO I need to specified the conditions for that. This is an extra operation (I get the clients before with the getAllClients() method), so I need to get again the clients.
2.- go throw the clients collection of the DBSet (I use EF 4.1) and change the information. This makes me to go throw the list that I receive from the client application too. So I must to go throw two lists. This needs resources.
3.- save the changes. This is needed anyway, so it has no required more work.
There is any way to make the step 2 easily? exist some method in dataContext to pass the values from my modified client to the client in the data context? I use POCO entities, perhaps it exists an easy way to do that.
Other question is about concurrency. If I control the concurrency with pesimistic concurrency that allow EF (with a timestamp field for example), is it better to call the updateClient() one for each client or better to pass a list with all the clients? I mean that if I use a list as parameter, if there is a concurrency issue with one client,the second for example, the first client will be update correctly, but the second not and the third neither. How can I notify to the user that there is problems with some clients?
To resume, I would like to know the best way to make updates when I have a short life datacontext.
Thanks.
Daimroc.
The service is disconnected scenario so when your client passes backs modified records you just need to process them as modified. You don't need to load all records from database for that.
public void SaveClients(List<Client> modifiedClients)
{
using (var context = new Context())
{
modifiedClients.ForEach(c =>
{
context.Entry(c).State = EntityState.Modified;
});
context.SaveChanges();
}
}
If you are using per call service and every service operation needs context you can move your context instancing to service constructor because service instance will live only to server single service call = you don't need using for every call. If you do that don't forget to implement IDisposable on your service to dispose context.
Other question is about concurrency. If I control the concurrency with
pesimistic concurrency that allow EF (with a timestamp field for
example), is it better to call the updateClient() one for each client
or better to pass a list with all the clients?
EF doesn't support pesimistic concurrency out of the box. Using timestamp is optimistic concurrency because it allows others to use the record. Pesimistic concurrency is application logic where other client is not able to select locked record for update.
The concurrency is resolved per record but the problem in this case is transaction. Each call to SaveChanges results in transaction used to process all changes in the database. So if any of your modified records is not up to date you will get concurrency exception and whole transaction is rolled back = no record is updated.
You can still overcome the issue by passing list of modified records to the service (reducing roundtrips between client and service is a best practice) but you can process each record separately by calling SaveChanges for every single record. Anyway this should be very carefully considered because each call to SaveChanges is like separate unit of work - is it really what you want?
Btw. the best practice is to make your service statless. You should avoid maintaining data between service calls and this example really doesn't need it.
I have a web service that will be consumed by some application (web site currently).
The calls are almost all specific to a certain client but still the same. So one call might be getAllFoo() but I would need some parameter to say from which client the Foo is.
It would become bothersome quickly if I just add a standard parameter to all calls so I was hoping to do it a little bit DRY and automatic. Something that would be included in all service calls.
Is IDispatchMessageInspector the right thing for me here? What kind of info could that include and can I access that info inside the methods?
Should I create some sort of attribute perhaps for the calls?
If anyone could point me towards a solution for this it would be great.
Edit
Another solution I'm thinking off.
Where the service call to a specific client happens on the consumer side, it will be known at instanceCreation so I could instance the ServiceClient with a known client.
Could I use this solution for the ClientBase<> extender somehow.
Let's say I'm serving Domain1 (let's call the client Domain to not confuse it with a serviceclient/consumer) I create a InformationProvider consumer side that has a ClientBase<IInformationService> field. I ensure that the DomainName (domain1) is set at construction so I could parhaps do the same thing when instancing the ClientBase<IInformationService> so It somehow let's the service know what domain I'm calling for.
I'm just still learning about WCF so I'm not sure how one would do this.
I can understand that you want to keep you solution simple and tidy, but ultimately - as you say yourself -
... I would need some parameter to say from which client...
The obvious and simplest solution is to include a client parameter on all your service calls where it is required. Surely there'll be service calls that don't require the client parameter, and in those cases you don't need to include the parameter.
You may be able to do something clever where a client identifier is passed discreetly under the covers, but beware of doing unnecessarily clever things. I would pass the client as a simple parameter because it is being used as a parameter. Two reasons come to mind:
if someone maintains your code they quickly understand what's going on.
if someone needs to use the service it is obvious how to use it.
A possible pattern:
Make sure you service instantiates per session. This means you'll have to use wsHttpBinding, netTcpBinding, or a custom binding as http does not support sessions.
Always call an initialization operation when each session is instantiated that sets the client id for that service.
Put this initialization operation inside a constructor for a proxy.
The steps involved would be something like this:
[ServiceBehavior(InstanceContextMode=InstanceContextMode.PerSession)]
public class MyService : IMyService
{
private int clientId;
public void StartUp(int clientId)
{
this.clientId = clientId;
and then client side, assuming you use the generated proxy, wrap the client inside another proxy.
public class ExtendedClient : MyServiceClient
{
public ExtendedClient(int clientid) : base()
{
this.StartUp(clientid);
}
Now you should instantiate the ExtendedClient, it will create the channel and prime the service by delivering the client id.
I would personally prefer to simply send the client id for each service call, but if you are able to use a session-able binding then this should work.
Just some information on WCF for you. If you have a stateless service, then you'll need to include the client as a parameter in every service call. This does not mean you need to include the client everywhere throughout your code - you could, for example, retrieve it inside the ClientBase constructor. But you will need to add it to every OperationContract and all the service implementations.
The alternative is to have a stateful service - the instance that you first use will remain for you to reuse (except for timeouts / exceptions). In this case you can potentially send the client just once, and then the service will know about the client for subsequent calls. This is the pattern described above. It means that you cannot use http binding. I believe that by doing this you're only increasing the potential for problems in your application (stateful services, having to ensure the initialization operation completes, more service calls being made).
My iOS app does a lot of different requests to a Web service. Each request is a call to a method of a ConnectionManager object. When the response arrives from the Web service, a delegate's method is called to notify an interested receiver. Moreover, to maintain the session active, a polling every X seconds is required.
Said so, in your opinion it is better if ConnectionManager is a Singleton or not?
The singleton is simpler (because I do not have to pass a ConnectionManager's reference to all those who need to do a request to the Web service or I do not have to create more ConnectionManagers). Moreover, it is easy to handle the issue of polling: I just add two methods startPolling and stopPolling on the ConnectionManager. But I do not like to use the delegates with a singleton (because there can be only one delegate, and what happens if a response comes when there is not one set?) and at the same time I do not like to use the notifications. I do not like the singleton, too :)
Do you have advice on alternative patterns?
I went through similar thinking as you and ended up with this pattern:
ConnectionManager [singleton] - responsible for maintaining a connection to the server and submitting & receiving requests
ConnectionQueue [singleton] - Stores a stack of Requests waiting to be fulfilled
Request - Created each time something is needed from the server. It contains all the request data (urls, params etc) and a reference to the delegate.
Response - A container for the data retrieved from the server along with the original request.
Hooking it all together...
The ConnectionManager is started at startup and it creates the ConnectionQueue
When a call to the server is needed create a Request object, pass in all required params and add it to the ConnectionQueue
The queue lets the manager know there's a request that needs to be processed
The manager removes the request from the queue & makes the call to the server
Data is received
The manager creates the response and sends it back to the delegate.
You can see this other post:.
I think it can be useful.
I'm trying to make a simple scheduler service that will automatically send emails, etc.
For now I have simple WCF service in which I create an instance of a timer, set a callback and do some work in the callback. Now this part works fine, with the callback being called and the work in it being done as expected.
The issue is I need to make some change to the timer, say change the interval or maybe just stop it.
But I can't seem to figure out a way to store/get the instance of that timer that I created. As each time I create a new proxy and access the service, I get a new instance of the service...
I know I could use a static variable but that kind of makes it a 'singleton' service, and the service host I am using at the current time does not support that...
So how can I get that instance of a timer/thread that I actually created in a previous call? Or am I just going about this the wrong way?
Static isn't all that bad of an idea here. Maybe that static is a dictionary keyed by a Guid and the Guid is returned to the client. Subsequent client calls use the Guid parameter, so new instances of your service lookup the timer using the Guid.