Thanks so much for your responses and time. Your answers was enlightened me.
2013/2/16 Emmanuel Lécharny <[email protected]> > Le 2/16/13 2:30 PM, Ricardo Cristian Ramirez a écrit : > > On Saturday, February 16, 2013 12:02:21 AM Emmanuel Lécharny wrote: > > > >> What exactly do you want to do ? Is this interrupting some sending if a > >> message is received from the server ? > > I am trying to send a message only once to the server but it seems > > impossible > > in the scope of non-blocking communication and my enable/disable > conditions. > You have to define a stateful protocol to handle such conditional > communications. > > In other words, and this is totally orthogonal to the blocking or non > blocking IO, your client must know if it can send a message, and the > server must tell the client about this possibility. > > One possibility is to have a client blocked untl it receives an ACK from > the server. Here is a possible protocol : > > Initial state > ------------- > Client : can send > Server : can receive > > > Normal state > ------------ > (1) client : send message, switch to 'wait for ACK' (cannot send an > other message until this ACK is received) > ... > (some delay) > ... > (2) server : receive the message, send a ACK to the client > ... > (some delay) > ... > (3) client : receive the server's ACK, switch to 'can send a message' > > > And now, you can iterate to (1) > > > > > > Assume receiver thread takes the processor from sender thread before > > sending > > is not completed. And, receiver takes a disable message: > > > > Checking the client state before write() method may cause a missing > > message: > > Client writes message to the session. Receiver thread takes the > processor. > > Receiver takes a disable message. When, the sender has the processor > again, > > it > > sends the message but server does not take into account a client's > message > > after disabling it. However, client thinks that the message has been > sent. > > if(state==sending_enabled): > > session.write(...) > The message can be considered as sent by the client when the > 'MessageSent' event is fired. This event means the data has been fully > flushed into the socket. > > Now, checking that is totally irrelevant in your scenario : you *can't* > - I mean, you really can't - know if the server has received the > message, unless the server has sent you an aknowledge. For that, the > server has to receive the message and send a response (see the protocol > above). > > Eveything else (the threads reading or wraiting , whatsoever) is just > irrelevant. > > Just consider that when you ave session.write() the message from the > client side, then the client has to wait for a response from the server, > and it has to be a message, not something like a messageSent event. This > has to be present in your high level protocol, whatever the > communication layer you are using (TCP, UDP, etc). That also mean that > your server must send a message when it has received a full message from > the client. > > This is really simple. > > > > > Checking the client state after write() method may cause duplication: > > Client > > writes message to the session and waits for the completion. After > > completion, > > receiver thread takes the processor between two if statement below. > > Receiver > > takes a disable message. Then, sender thread takes the processor again. > > Checks > > the state and resends the messages for second time. > > FutureWriter fWriter = session.write(...) > > fWriter.join() > > if(fWriter.isWritten()): > > if(state==sending_disabled): > > mark this message as not send. try to send again when sending > > enabled > > You are trying to do some post-mortem control. It does not work, period. > Do it the other way : send a message when you know you can : > - either when the client connects for the first time > - or when you have actually received the server's response > > In any other case, you should be in a non-transmitting state. > > If you never receive a response from the server, then you should > consider either that the conneciton has been brutally closed from the > server side, or that the server is buggy. In any case, close the session > and inform the user. > > > > - o - > > > > On the other hand, interrupting the sending queue after taking a disable > > message may cause a loss too. Consider the following code: > > messageReceived(message): > > if(message==sending_disabled): > > list = session.getSendingQueue() > > session.cancelSendingQueue() > > addToResendList(list) > > > > Receiver takes a disable message and tries to cancel sending queue. > Before > > canceling (calling cancelSendingQueue()), sender thread gains the > processor > > and sends the message. Now, client thinks the message has been sent but > > server > > has just ignored it. Message is lost. > > One more thing : if your server may send a 'sending_disable' message at > any time, then you have no way to guarantee that this message will be > processed corectly on the client side. At best, if the server send you > such a message then it should consider that any message it will receive > from the client is invalid (just because such a message might have been > sent before the server sent its 'disable-sending' message). Or you can > consider that the server will accept the client message, assuming that > the client has sent it *before* it recived the 'disable-sending' > message. That's also a legitimate choice. > > But again, this is something you should design in your protocol, and the > way MINA works is really totally orthogonal. > > Note that using Blocking IO does not solve any of the issue you have : > just because you have written some data in a socket does not mean the > server has received those data. In fact, you can *at the same time* have > the client and the server sending some data to each other (this is a > full duplex communication). The only way to solve this issue is to remap > some high level protocol on top of the low mevel protocol to manage such > situations. > > Hope it helps. > > > -- > Regards, > Cordialement, > Emmanuel Lécharny > www.iktek.com > >
