JXTA

net.jxta.impl.endpoint.tcp
Class TcpMessenger

java.lang.Object
  extended by net.jxta.util.AbstractSimpleSelectable
      extended by net.jxta.endpoint.AbstractMessenger
          extended by net.jxta.impl.endpoint.BlockingMessenger
              extended by net.jxta.impl.endpoint.tcp.TcpMessenger
All Implemented Interfaces:
Runnable, Messenger, SimpleSelectable

public class TcpMessenger
extends BlockingMessenger
implements Runnable

Implements a messenger which sends messages via raw TCP sockets.


Nested Class Summary
 
Nested classes/interfaces inherited from interface net.jxta.util.SimpleSelectable
SimpleSelectable.IdentityReference
 
Field Summary
(package private)  long receiveBeginTime
          Time at which we began receiving the current incoming message.
 
Fields inherited from class net.jxta.endpoint.AbstractMessenger
DEFAULT_MTU
 
Fields inherited from class net.jxta.util.AbstractSimpleSelectable
identityReference
 
Fields inherited from interface net.jxta.endpoint.Messenger
ANYSTATE, BREAKING, BROKEN, CLOSED, CLOSING, CONNECTED, DISCONNECTED, DISCONNECTING, IDLE, RECONCLOSING, RECONNECTING, RECONSATURATED, RESOLCLOSING, RESOLPENDING, RESOLSATURATED, RESOLVED, RESOLVING, SATURATED, SENDING, SENDINGSATURATED, TERMINAL, UNRESOLVABLE, UNRESOLVED, UNRESOLVING, USABLE
 
Constructor Summary
TcpMessenger(EndpointAddress destaddr, TcpTransport tcpTransport)
          Create a new TcpMessenger for the specified address.
TcpMessenger(EndpointAddress destaddr, TcpTransport tcpTransport, boolean selfDestruct)
          Create a new TcpMessenger for the specified address.
TcpMessenger(SocketChannel socketChannel, TcpTransport transport)
          Create a new TcpMessenger for the specified address.
 
Method Summary
 void closeImpl()
          Close connection.
protected  void finalize()
          The cost of just having a finalize routine is high.
 EndpointAddress getLogicalDestinationImpl()
          Obtain the logical destination address from the implementer (a transport for example).
(package private)  TransportBindingMeter getTransportBindingMeter()
          Returns the metering object for this tcpTransport
 boolean isClosed()
          Returns true if this messenger is closed and no longer accepting messages to be sent.
 boolean isIdleImpl()
          return true if this messenger has not been used for a long time.
 List<Message> processBuffer()
          processes the input byte buffer
 void run()
          

This is what gets run by the Executor.

 void sendMessageBImpl(Message message, String service, String serviceParam)
          Send a message blocking as needed until the message is sent.
 void sendMessageDirect(Message message, String service, String serviceParam, boolean direct)
           
 
Methods inherited from class net.jxta.impl.endpoint.BlockingMessenger
close, getChannelMessenger, getDestAddressToUse, getLogicalDestinationAddress, getState, resolve, sendMessageB, sendMessageN, setOwner, shutdown
 
Methods inherited from class net.jxta.endpoint.AbstractMessenger
flush, getDestinationAddress, getDestinationAddressObject, getMTU, isIdle, isSynchronous, itemChanged, sendMessage, sendMessage, sendMessage, setStateLock, toString, waitState
 
Methods inherited from class net.jxta.util.AbstractSimpleSelectable
getIdentityReference, haveListeners, notifyChange, register, registerListener, unregister, unregisterListener
 
Methods inherited from class java.lang.Object
clone, equals, getClass, hashCode, notify, notifyAll, wait, wait, wait
 
Methods inherited from interface net.jxta.util.SimpleSelectable
getIdentityReference, register, unregister
 

Field Detail

receiveBeginTime

long receiveBeginTime
Time at which we began receiving the current incoming message.

Constructor Detail

TcpMessenger

TcpMessenger(SocketChannel socketChannel,
             TcpTransport transport)
       throws IOException
Create a new TcpMessenger for the specified address.

Parameters:
socketChannel - the SocketChannel for the messenger
transport - the tcp MessageSender we are working for.
Throws:
IOException - if an io error occurs

TcpMessenger

TcpMessenger(EndpointAddress destaddr,
             TcpTransport tcpTransport)
       throws IOException
Create a new TcpMessenger for the specified address.

Parameters:
destaddr - the destination of the messenger
tcpTransport - the tcp MessageSender we are working for.
Throws:
IOException - if an io error occurs

TcpMessenger

TcpMessenger(EndpointAddress destaddr,
             TcpTransport tcpTransport,
             boolean selfDestruct)
       throws IOException
Create a new TcpMessenger for the specified address.

Parameters:
destaddr - the destination of the messenger
tcpTransport - the tcp MessageSender we are working for.
selfDestruct - indicates whether the messenger created will self destruct when idle
Throws:
IOException - if an io error occurs
Method Detail

finalize

protected void finalize()
                 throws Throwable
The cost of just having a finalize routine is high. The finalizer is a bottleneck and can delay garbage collection all the way to heap exhaustion. Leave this comment as a reminder to future maintainers. Below is the reason why finalize is not needed here.

These messengers are never given to application layers. Endpoint code always calls close when needed.

There used to be an incoming special case in order to *prevent* closure because the inherited finalize used to call close. This is no-longer the case. For the outgoing case, we do not need to call close for the reason explained above.

Overrides:
finalize in class Object
Throws:
Throwable

closeImpl

public void closeImpl()
Close connection. May fail current send.

Now everyone knows its closed and the connection can no-longer be obtained. So, we can go about our business of closing it. It can happen that a redundant close() is done but it does not matter. close() is idempotent.

Specified by:
closeImpl in class BlockingMessenger

isClosed

public boolean isClosed()
Returns true if this messenger is closed and no longer accepting messages to be sent. This is a shortcut for (getState() & USABLE == 0). Once closed, a messenger should be discarded.

This is a minimal implementation. It may not detect closure initiated by the other side unless the messenger was actually used since. A more accurate (but not mandatory implementation) would actually go and check the underlying connection, if relevant...unless breakage initiated by the other side is actually reported asynchronously when it happens. Breakage detection from the other side need not be reported atomically with its occurrence. This not very important since we canonicalize transport messengers and so do not need to aggressively collect closed ones. When not used, messengers die by themselves.

We overload isClosed because many messengers still use super.isClosed() as part of their own implementation or don't override it at all. They expect it to be true only when all is shutdown; not while we're closing gently. FIXME - jice@jxta.org 20040413: transports should get a deeper retrofit eventually.

Specified by:
isClosed in interface Messenger
Overrides:
isClosed in class BlockingMessenger
Returns:
true if this messenger is closed, otherwise false.

isIdleImpl

public boolean isIdleImpl()
return true if this messenger has not been used for a long time. The definition of long time is: "sufficient such that closing it is worth the cost of having to re-open". A messenger should self close if it thinks it meets the definition of idle. BlockingMessenger leaves the evaluation to the transport but does the work automatically. Important: if self destruction is used, this method must work; not just return false. See the constructor. In general, if closeImpl does not need to do anything, then self destruction is not needed.

Since we probe the connection status, we'll keep a messenger as long as the connection is active, even if only on the incoming side. So we're being a bit nice to the other side. Anyway, incoming connections do not go away when the messenger does. There's a receive timeout for that.

Specified by:
isIdleImpl in class BlockingMessenger
Returns:
true if theis messenger is, by it's own definition, idle.

getLogicalDestinationImpl

public EndpointAddress getLogicalDestinationImpl()
Obtain the logical destination address from the implementer (a transport for example).

Specified by:
getLogicalDestinationImpl in class BlockingMessenger

sendMessageBImpl

public void sendMessageBImpl(Message message,
                             String service,
                             String serviceParam)
                      throws IOException
Send a message blocking as needed until the message is sent.

Specified by:
sendMessageBImpl in class BlockingMessenger
Parameters:
message - The message to send.
service - The destination service.
serviceParam - The destination serivce param.
Throws:
IOException - Thrown for errors encountered while sending the message.

sendMessageDirect

public void sendMessageDirect(Message message,
                              String service,
                              String serviceParam,
                              boolean direct)
                       throws IOException
Throws:
IOException

run

public void run()

This is what gets run by the Executor. It reads whatever is available, processes it and then goes back to the selector waiting for more IO

Specified by:
run in interface Runnable

processBuffer

public List<Message> processBuffer()
processes the input byte buffer

Returns:
the list of messages present in the buffer

getTransportBindingMeter

TransportBindingMeter getTransportBindingMeter()
Returns the metering object for this tcpTransport

Returns:
the metering object for this tcpTransport

JXSE