Meaning of IsInitiating and IsOneWay in WCF OperationContract - wcf

i am very new in WCF. so often gaze for wcf code & article. after viewing many code i often stuck for very basic things and got no elaborate discussion for the below question. so here are my few basic question....and looking for details discussion with sample situation and with sample code.
[OperationContract(IsInitiating=false, IsOneWay=false)]
bool Add_Contact(int sessionkey, string Newusrname);
What is the meaning of IsInitiating=false or true. when i should set it true or false ? what is the meaning of IsOneWay=false or true. when i should set it true or false ?
i belief my question are very basic and lots of scholar every time monitoring this forum. i hope i will get the best answer in details with many situation like when one should choose which option over other option with few sample code for simulating situations. thanks

IsInitiating
The IsInitiating parameter specifies whether or not an operation implemented by the associated method
can initiate a session on the server. Session instancing is the ability to have separate instances of a class
be maintained for each client channel. This property controls whether an operation is allowed to be the
first operation called when a session is created. The default for this parameter is true, meaning that the
specified operation can be the first called on a channel. In this scenario, all following calls to this method
have no effect (meaning, no other sessions are created). If this parameter is set to false, the client is forced
to call other methods prior to calling this method.
This comes in handy when you are trying to set an “order of operation,” meaning that you need a specific
method to be called first because the other methods called depend on something returned from the
first method.
For example, the following contains three methods, or service operations. The first operation creates the
session and must be the first method called. The final operation, Logout, closes the session:
[ServiceContract]
public interface IBuyStock
{
[OperationContract(IsInitiating = true, IsTerminating = false)]
void Login(user);
[OperationContract(IsInitiating = false, IsTerminating = false)]
void BuyStock(string stocksymbol, int quantity);
[OperationContract(IsInitiating = false, IsTerminating = true)]
void Logout(user);
}
Once the initiating method has been called, subsequent calls can be made to that method with no effect
to its initiating properties.
If any method other than the initiating method is called first, the following error is returned:
The operation ‘operationname’ cannot be the first operation to be called because
IsInitiating is false.
The initiating method must be called first, then other operations can be called.
IsOneWay
Service communication by default is bi-directional. Bi-directional service communication means that a
service operation can receive incoming messages and send a reply.
The IsOneWay parameter specifies whether a service operation returns a reply message. The default
value for this parameter is false, meaning that the method does not return a reply message.
The following example illustrates a one-way communication:
[ServiceContract]
public interface IBuyStock
{
[OperationContract(IsOneWay = true)]
void Login(user);
[OperationContract(IsOneWay = false)]
void BuyStock(string stocksymbol, int quantity);
}
In a one-way communication, the client initiates the communication and continues code execution and
does not wait for a response from the service. In a two-way communication, it waits for a response from
the service before continuing code execution.
The downside to using one-way communication is that the caller has no way of knowing whether or not
the service processed the message successfully.
Any methods that return a value where the IsOneWay property is set to false will return an exception.
IsTerminating
The IsTerminating property specifies whether a called service operation is to terminate the communication
session. The following example shows the last call,
Logout(), has the IsTerminating property set to true:
[ServiceContract]
public interface IBuyStock
{
[OperationContract(IsInitiating = true, IsTerminating = false)]
void Login(user);
[OperationContract(IsInitiating = false, IsTerminating = false)]
void BuyStock(string stocksymbol, int quantity);
[OperationContract(IsInitiating = false, IsTerminating = true)]
void Logout(user);
}
When the IsTerminating property is set to true, the session is closed after the reply message is sent (if
a reply message needs to be sent). On the client side, an IsTerminating value of true tells WCF to close
the channel only after the reply arrives at the client.

[OperationContract(IsInitiating = true, IsTerminating = false)]
Blockquote
In above code IsInitiating property is set to true when we want to create session .
Blockquote
We know login method is called first before other methods,hence we
use IsInitiating = true for login method and for other methods we set it as false.
Blockquote
In the same way we use Isterminating=True for logout method then session is deleted.

Related

Channel.basicQos() ignored by rabbitMq

I'm developing an application that uses RabbitMq with Micronaut(v1.1.3) Framework, the goal of this application is to write on the queue the path of a file. The workers (RabbitListeners) consume the queue and do certain operations on the indicated file. These operations can be burdensome and therefore I don't want the queue to immediately assign messages to the first available worker so as to avoid overloading a worker. I have read that you need to set the "prefetch_count" to prevent the worker from being overloaded.
The problem is that channel.basicQos (1) is completely ignored and therefore the prefetch_count is not set in the queue.
#Singleton
public class ChannelPoolListener extends ChannelInitializer {
#Override
public void initialize(Channel channel) throws IOException {
channel.basicQos(1);
channel.exchangeDeclare("micronaut", BuiltinExchangeType.DIRECT, true);
channel.queueDeclare("log", true, false, false, null);
channel.queueBind("log", "micronaut", "log");
}
}
The channel passed in the initializer has no guarantees to be used beyond that scope. You need to set the prefetch in the Queue annotation. See https://micronaut-projects.github.io/micronaut-rabbitmq/latest/api/io/micronaut/configuration/rabbitmq/annotation/Queue.html#prefetch--

One-Way Operations in WCF Services

i am new in wcf. so often read basic tutorial & guide line from many site on wcf. i saw people design their wcf service with special attribute like [OperationContract(IsOneWay=true)]
[ServiceContract]
public interface IArticleService
{
[OperationContract(IsOneWay=true)]
void OneWayMethod();
}
after reading on this one-way operation i understand what it is as follow....
When an operation has no return value, and the client does not care about the success or failure of the invocation. WCF offers one-way operations to support this sort of fire-and-forget invocation,: once the client issues the call, WCF generates a request message, but no correlated reply message will ever return to the client
i like to know if i do not specify IsOneWay=true or IsOneWay=false then IsOneWay=true is default. just tell me what happen when we do not specify this attribute IsOneWay=true ?
or specify like IsOneWay=false
thanks
UPDATE
i read a write up from this url http://msdn.microsoft.com/en-us/library/system.servicemodel.operationcontractattribute.isoneway%28v=vs.110%29.aspx and understand what is the meaning of IsOneWay=true or IsOneWay=false
[ServiceContract]
public class OneAndTwoWay
{
// The client waits until a response message appears.
[OperationContract]
public int MethodOne (int x, out int y)
{
y = 34;
return 0;
}
// The client waits until an empty response message appears.
[OperationContract]
public void MethodTwo (int x)
{
return;
}
// The client returns as soon as an outbound message
// is queued for dispatch to the service; no response
// message is generated or sent.
[OperationContract(IsOneWay=true)]
public void MethodThree (int x)
{
return;
}
}
IsOneway is false by default and you have to explicitly set it to true if you want your operation to be a one way
Check this out :
http://msdn.microsoft.com/en-us/library/ms733035(v=vs.110).aspx

WCF Async call that return void and is OneWay

I use WCF to async communicate between 2 processes.
till now I implemented the IAsyncResult pattern, and did it by having 3 methods:
BeginOperation - client.BeginOperation, when service receive it queue the job on threadpool with delegate for Operation
Operation - run on service side
EndOperation - this is what client callback.
My question is, I want to send strings from client to service, I want the send to be async, AND I dont want to get response - just want the service to print the string.
Is this enough ? This must be Non-Blocking
[OperationContract(IsOneWay = true)]
void PrintString(string message);
OR i need to do as following:
[OperationContract(IsOneWay = true, AsyncPattern=true)]
void BeginPrintString(string message, AsyncCallback callback, object state);
void EndPrintString(IAsyncResult asyncResult);
IsOneWay should be enough, but it still can block your client in specific circumstances, as well as throw errors.
See this and this posts for more details:
General things you should keep in mind about OneWay operations -
O/W operations must return void. O/W operations can still yield
exceptions. invoking an operation on the client channel might still
throw an exception if it couldn’t transmit the call over to the
service. O/W operations can still block. if the service is pumped with
messages and a queue had started, calling O/W operation may block your
following code.
You can make it more asynchronous by using a separate thread to do your work.
Instead of:
public void MyOneWayServiceOperation() {
// do stuff
}
do something like:
public void MyOneWayServiceOperation() {
new Thread(() => {
// do stuff
}).Start();
}
The service operation will have been executed on a new thread anyway, so it shouldn't cause any more problems for your code to be on a different new thread.
You can add a Thread.Sleep() call before your work if you want the service operation to have completed before you begin. This allowed me to quit the service from a service operation without having an exception thrown.

C# WCF Sessions with Asynchronous functions

What happens in the case of a wcf session that has created an asynchronous function (such as background automated emailing ) when the client closes session ie client.Close()/client.Abort()?
In otherwords if have some as below:
[OperationContract(IsOneWay = true, IsInitiating = true, IsTerminating = false)]
void RegisterUser(string user);
[OperationContract(IsOneWay = false, IsInitiating = false, IsTerminating = false)]
void SendEmails(T[] listofDetails);
[OperationContract(IsOneWay = false, IsInitiating = false, IsTerminating = true)]
void UnRegisterUser();
and SendEmails creates a task or async function (the async call isn't done client side) that sends off all the emails in the background.
And the user Terminates the session before all the emails are finished sending? Does the session still stay open and wait or does it close and the emailing just keeps going until it finishes or what happens?
Thanks All
Sorry if the question is a bit ambiguous :/
In your example you have defined a request-response operation called SendEmails which returns void. This is not the same thing as an asynchronous operation.
I am assuming you are creating a new background thread within the operation method which then goes away and send the emails.
In this instance the operation will return void to the caller once the operation method has finished execution. If the client then terminates the channel the background thread will continue its work.

Async End<Method> not called in WCF

I have the following situation: My WCF service allows a client to register to wait for some event. The waiting is asynchronous on the service side, that is, the waiter is registered and when the process is finished, the waiter is notified. At the moment, it's simply a ManualResetEvent.
Now I want to expose this method via WCF. I tried to use AsyncPattern=true and created two methods, BeginWait which bundles the event into a IAsyncResult, and EndWait which calls AsyncWaitHandle.WaitOne(). However, if I call BeginWait, EndWait from the client, the server side EndWait is not executed. I'm using a manually implemented wrapper (my proxy class is derived from ChannelBase<IWaitService>, IWaitService), which basically calls Channel.EndWait(), and this function is indeed called; but on the server side, the call never arrives.
What am I doing wrong here? Follow-up question: If the asynchronous call is working, is there an easy way to make that synchronous on the client side?
The line
var task = Task.Factory.StartNew(() => IsPrime(a));
uses overload
TaskFactory.StartNew(Action)
which results in
((IAsyncResult)task).AsyncState == null
the call to callback(task) results in an ArgumentException, complaining that the state object is different from the state object that was passed to the BeginXxx method. The line must be modified to
var task = Task.Factory.StartNew((actionState) => IsPrime(a), state);
using overload
TaskFactory.StartNew(Action<object>, object)
such that the state object passed by WCF ends up in the task:
((IAsyncResult)task).AsyncState.GetType().FullName == System.ServiceModel.Dispatcher.MessageRpc+Wrapper
The synchronous/asynchronous decision can be made independently on the server or client side. Calling EndWait on the client does not translate into an EndWait call on the server. I would recommend testing an async service with a sync client just to keep things simple and avoid confusion.
I would further recommend that you not call WaitOne inside of the EndWait method. The contract is that this method will only be called after the IAsyncResult tells the framework that it is done. This is done in one of three ways:
CompletedSynchronously returns true
The AsyncCallback is invoked
The AsyncWaitHandle is signalled
CompletedSynchronously should only return true if BeginWait had enough information to complete the request before it returned. This is probably not the case. You can satisfy the other two conditions with your ManualResetEvent as follows:
class EventBasedAsyncResult : IAsyncResult
{
private readonly ManualResetEvent _manualResetEvent;
private readonly AsyncCallback _asyncCallback;
private readonly object _asyncState;
public EventBasedAsyncResult(AsyncCallback callback, object asyncState)
{
_manualResetEvent = new ManualResetEvent(false);
_asyncState = asyncState;
_asyncCallback = callback;
}
public void WaitCompleted()
{
_manualResetEvent.Set();
_asyncCallback(this);
}
public object AsyncState
{
get { return _asyncState; }
}
public WaitHandle AsyncWaitHandle
{
get { return _manualResetEvent; }
}
public bool CompletedSynchronously
{
get { return false; }
}
public bool IsCompleted
{
get { return _manualResetEvent.WaitOne(0); }
}
}
I think once you do this you'll find that EndWait is called, even if the client is synchronous.