Peter, thanks for the information, it works like a charm.
In case anyone else wants to try this, here is a preliminary example. The
server and client used in this example are slight modifications of the SumUp
example provided in MINA
/*****************************************/
/* API.java */
/*****************************************/
import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.concurrent.ExecutionException;
import org.apache.mina.common.ConnectFuture;
import org.apache.mina.common.IoConnector;
import org.apache.mina.common.IoConnectorConfig;
import org.apache.mina.common.IoSession;
import org.apache.mina.transport.socket.nio.SocketConnector;
public final class API
{
private String m_strServer = "";
private int m_iPort = 8080;
private int m_iTimeout = 30; // seconds
private int m_iSessionId = 0;
private IoSession m_Session = null;
APIFuture m_Future = new APIFuture();
protected API()
{
super();
}
public API(String server, int port, int timeout)
{
super();
this.m_iPort = port;
this.m_iTimeout = timeout;
this.m_strServer = server;
}
/**
* @return the port
*/
public int getPort()
{
return m_iPort;
}
/**
* Port that this session will try to connect to
* @param port the port to set
*/
public void setPort(int port)
{
m_iPort = port;
}
/**
* @return the timeout
*/
public int getTimeout()
{
return m_iTimeout;
}
/**
* Sets the number of seconds to use as a timeout value
* @param timeout the timeout to set
*/
public void setTimeout(int timeout)
{
m_iTimeout = timeout;
}
/**
* @return the server
*/
public String getServer()
{
return m_strServer;
}
/**
* Name of the server that this session will connect to
* @param server the server to set
*/
public void setServer(String server)
{
m_strServer = server;
}
public int getSessionId()
{
return m_iSessionId;
}
/**
* Sets up a session connection to the server
*
* @return
* @throws IOException
*/
public boolean connect() throws IOException
{
IoConnector connector = new SocketConnector();
( ( IoConnectorConfig ) connector.getDefaultConfig()
).setConnectTimeout( getTimeout() );
ConnectFuture future = connector.connect(
new InetSocketAddress( getServer(), getPort() ),
new ClientSessionHandler() );
future.join();
m_Session = future.getSession();
return true;
}
/**
* Disconnects the session from the server
*
* @return
*/
public boolean disconnect()
{
m_Session.close();
return true;
}
public boolean isConnected()
{
if (m_Session == null)
return false;
else
return m_Session.isConnected();
}
public Object serverCall(Object message) throws InterruptedException,
ExecutionException
{
if (isConnected())
{
synchronized (m_Future)
{
m_Future.setValue(null);
m_Session.setAttribute("next-future", m_Future);
m_Session.write(message);
m_Future.wait();
}
return m_Future.get();
}
return null;
}
}
/*****************************************/
/* APIFuture.java */
/*****************************************/
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
public class APIFuture implements Future
{
private Object m_Value = null;
private boolean m_bDone = false;
public boolean cancel(boolean mayInterruptIfRunning)
{
// TODO Auto-generated method stub
return false;
}
public Object get() throws InterruptedException, ExecutionException
{
return m_Value;
}
public Object get(long timeout, TimeUnit unit) throws
InterruptedException, ExecutionException, TimeoutException
{
//TODO add code here that honors the parameters
return m_Value;
}
public boolean isCancelled()
{
// TODO Auto-generated method stub
return false;
}
public boolean isDone()
{
return m_bDone;
}
public void setValue(Object value)
{
m_Value = value;
}
public void setDone(boolean done)
{
m_bDone = done;
}
}
/*****************************************/
/* ClientSessionHandler.java */
/*****************************************/
import org.apache.mina.common.IoHandlerAdapter;
import org.apache.mina.common.IoSession;
import org.apache.mina.filter.codec.ProtocolCodecFactory;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import
org.apache.mina.filter.codec.serialization.ObjectSerializationCodecFactory;
public class ClientSessionHandler extends IoHandlerAdapter
{
public ClientSessionHandler()
{
}
public void sessionCreated( IoSession session ) throws Exception
{
ProtocolCodecFactory codec;
codec = new ObjectSerializationCodecFactory();
session.getFilterChain().addLast(
"protocolFilter", new ProtocolCodecFilter( codec ) );
}
public void sessionOpened( IoSession session )
{
// send summation requests
String test = "session message";
{
session.write( test );
}
}
public void messageReceived( IoSession session, Object message )
{
APIFuture future = (APIFuture) session.getAttribute("next-future");
synchronized (future)
{
future.setValue(message);
future.notifyAll();
}
//TODO add handling here
}
public void exceptionCaught( IoSession session, Throwable cause )
{
System.err.println(cause);
session.close();
}
}
On 4/27/06, peter royal <[EMAIL PROTECTED]> wrote:
On Apr 26, 2006, at 6:19 PM, list cs wrote:
> Ideally, I'd like to hide any mina implementation details so that
> the user
> never sees it (and has no access to it), and would like to know if
> anyone
> has done something similiar.
>
...
>
> Does anyone have any idea what would be the best way to try and
> implement
> something like this?
You'll want an encapsulation-based relationship with MINA, rather
than an inheritance-based one.
With that said, if you want to mimic a synchronous API, you'll want
to make a 'Future' to hold the result of your call. Something akin to:
IoSession session = // your MINA session;
MyCustomFuture future = new MyCustomFuture();
session.setAttribute("next-future", future);
session.write( object );
future.await();
return future.get();
.. And then in your IoHandler,
void messageReceived( Object message ) {
MyCustomFuture future = getAttribute( "next-future" );
future.setValue( message );
}
You can use the Future in MINA as an example. Or build off of Java5's
or what is in util.concurrent.
-pete
--
[EMAIL PROTECTED] - http://fotap.org/~osi