Hi,
I have modified the 'imagine' example from tutorial about ProtocolCodecFilter : i add a RequestResponseFilter (on the ImageClient side) : now an ImageRequest specify the number of ImageResponse to receive.

The flow is now :
ImageRequest --(encode)--> network --(decode)--> ImageRequest -> ImageResponse--(encode)
--> network--(decode)-->ImageResponse is PARTIAL or PARTIAL_LAST

The number of total response to receive for each request ID is stored in an IoSession attribute and the number of response received too.
I'll be happy if this example can help someone.

Apply the patch :
1) mkdir test ; cd test ; wget http://mina.apache.org/tutorial-on-protocolcodecfilter.data/mina-codec-tutorial-src.zip
2) unzip mina-codec-tutorial-src.zip
3) copy the patch here
4) Apply the patch : patch -p1 < imagine.patch

Building
5) cd src/org/apache/mina/example/imagine/
6) export JAVA_HOME=/usr/lib/jvm/java-6-sun
7) ant

Execute
7) /usr/lib/jvm/java-6-sun/bin/java -classpath ./build:.:${HOME}/mina_trunk/mina/core/target/classes org.apache.mina.example.imagine.server.ImageServer 8) /usr/lib/jvm/java-6-sun/bin/java -classpath ./build:.:${HOME}/mina_trunk/mina/core/target/classes org.apache.mina.example.imagine.client.ImageClient

(you should adapt paths)

Any remarks are welcome.
Please let me know if you find any errors and if comments are needed, please notify me :)

Pierre


diff -Naur mina_tuto/src/org/apache/mina/example/imagine/ImageRequest.java mina_tuto_with_trunk/src/org/apache/mina/example/imagine/ImageRequest.java
--- mina_tuto/src/org/apache/mina/example/imagine/ImageRequest.java	2007-05-27 16:50:40.000000000 +0000
+++ mina_tuto_with_trunk/src/org/apache/mina/example/imagine/ImageRequest.java	2007-06-29 10:05:30.000000000 +0000
@@ -5,12 +5,16 @@
   private int width;
   private int height;
   private int numberOfCharacters;
+  private int id;
+  private int nb;
 
-  public ImageRequest(int width, int height, int numberOfCharacters)
+  public ImageRequest(int id, int width, int height, int numberOfCharacters, int nb)
   {
+    this.id = id;
     this.width = width;
     this.height = height;
     this.numberOfCharacters = numberOfCharacters;
+    this.nb = nb;
   }
 
   public int getWidth()
@@ -23,8 +27,18 @@
     return height;
   }
 
-    public int getNumberOfCharacters()
-    {
-        return numberOfCharacters;
-    }
+  public int getNumberOfCharacters()
+  {
+      return numberOfCharacters;
+  }
+
+  public int getId()
+  {
+      return this.id;
+  }
+
+  public int getNb()
+  {
+      return this.nb;
+  }
 }
diff -Naur mina_tuto/src/org/apache/mina/example/imagine/ImageResponse.java mina_tuto_with_trunk/src/org/apache/mina/example/imagine/ImageResponse.java
--- mina_tuto/src/org/apache/mina/example/imagine/ImageResponse.java	2007-05-27 13:27:58.000000000 +0000
+++ mina_tuto_with_trunk/src/org/apache/mina/example/imagine/ImageResponse.java	2007-06-29 10:01:45.000000000 +0000
@@ -7,9 +7,11 @@
     private BufferedImage image1;
 
     private BufferedImage image2;
+    private int id;
 
-    public ImageResponse(BufferedImage image1, BufferedImage image2)
+    public ImageResponse(int id, BufferedImage image1, BufferedImage image2)
     {
+        this.id = id;
         this.image1 = image1;
         this.image2 = image2;
     }
@@ -24,4 +26,13 @@
         return image2;
     }
 
+    public void setId(int id)
+    {
+        this.id = id;
+    }
+    
+    public int getId()
+    {
+        return this.id;
+    }
 }
diff -Naur mina_tuto/src/org/apache/mina/example/imagine/build.xml mina_tuto_with_trunk/src/org/apache/mina/example/imagine/build.xml
--- mina_tuto/src/org/apache/mina/example/imagine/build.xml	1970-01-01 00:00:00.000000000 +0000
+++ mina_tuto_with_trunk/src/org/apache/mina/example/imagine/build.xml	2007-07-05 15:09:20.000000000 +0000
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="iso-8859-15"?>
+<project name="ex" default="main" basedir=".">
+    <description>
+    jclient
+    </description>
+
+    <property name="builddir" value="${basedir}/build" />
+    <property name="minadir" value="${user.home}/mina_trunk/mina/core/target/classes" />
+    <property name="slf4jdir" value="${user.home}/jclient/slf4j-1.4.0" />
+
+    <property name="build.compiler" value="modern" />
+
+    <target name="init" description="construit l'arborescence cible" >
+        <mkdir  dir="${builddir}"/>
+    </target>
+
+    <target name="main" description="compile les sources" depends="init">
+        <javac  srcdir="${basedir}" destdir="${builddir}" classpath="${builddir}:${minadir}:." debug="on" deprecation="on" optimize="off" >
+            <include name="*.java" />
+            <include name="client/*.java" />
+            <include name="codec/*.java" />
+            <include name="server/*.java" />
+        </javac>    
+    </target>
+
+    <target name="prof" description="compile les sources" depends="clean,init">
+        <javac  srcdir="${basedir}" destdir="${builddir}" classpath="${builddir}" debug="on" deprecation="on" optimize="off" >
+            <include name="*.java" />
+            <compilerarg value="-J-agentlib:hprof=cpu=times"/>
+        </javac>    
+    </target>
+   
+    <target name="clean" description="nettoie tous les repertoires generes" >
+        <delete includeEmptyDirs="true" quiet="true">
+            <fileset dir="${builddir}" />
+        </delete>
+    </target>
+
+</project>
diff -Naur mina_tuto/src/org/apache/mina/example/imagine/client/GraphicalCharGenClient.java mina_tuto_with_trunk/src/org/apache/mina/example/imagine/client/GraphicalCharGenClient.java
--- mina_tuto/src/org/apache/mina/example/imagine/client/GraphicalCharGenClient.java	2007-05-27 22:00:34.000000000 +0000
+++ mina_tuto_with_trunk/src/org/apache/mina/example/imagine/client/GraphicalCharGenClient.java	2007-07-09 15:05:05.000000000 +0000
@@ -1,11 +1,16 @@
 package org.apache.mina.example.imagine.client;
 
 import org.apache.mina.example.imagine.ImageRequest;
+import org.apache.mina.filter.reqres.ResponseInspector;
+
+import java.util.concurrent.Executors;
+import java.util.concurrent.ExecutorService;
 
 import javax.swing.*;
 import java.awt.image.BufferedImage;
 import java.awt.*;
 
+
 /**
  * @author  Maarten Bosteels
  */
@@ -13,10 +18,31 @@
 {
     public static final int PORT = 33789;
     public static final String HOST = "localhost";
+    
+    private int numRequest = 0; // message Id for request
+    private int numResponse = 0; // number received responses
+    private int nbResponsePerRequest = 4; // number of responses per request
+
+    private MyResponseInspector2 responseInspector;
+    private ExecutorService pool; 
 
     public GraphicalCharGenClient()
     {
         initComponents();
+        this.responseInspector = new MyResponseInspector2();
+        pool = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()+1);
+
+        imageClient = new ImageClient(HOST, PORT, this);
+    }
+    
+    public MyResponseInspector2 getResponseInspector()
+    {
+        return this.responseInspector;
+    }
+
+    public ExecutorService getPool()
+    {
+        return this.pool;
     }
 
     private void jButtonConnectActionPerformed()
@@ -41,12 +67,19 @@
         int chars  = spinnerCharsModel.getNumber().intValue();
         int height = spinnerHeightModel.getNumber().intValue();
         int width  = spinnerWidthModel.getNumber().intValue();
-        imageClient.sendRequest(new ImageRequest(width, height, chars));
+        imageClient.sendRequest(new ImageRequest(this.getNumRequest(), width, height, chars, this.nbResponsePerRequest));
+    }
+    
+    private synchronized int getNumRequest()
+    {
+        this.numRequest++;
+        return this.numRequest;
     }
 
-    public void onImages(BufferedImage image1, BufferedImage image2)
+    public synchronized void onImages(BufferedImage image1, BufferedImage image2)
     {
-        if (checkboxContinous.getState())
+        this.numResponse++;
+        if (checkboxContinous.getState() && (this.numResponse % this.nbResponsePerRequest == 0))
         {
             // already request next image
             sendRequest();
@@ -60,12 +93,15 @@
         while (cause.getCause() != null)
         {
             cause = cause.getCause();
+            System.out.println(cause.getMessage());
+            System.out.println(throwable.getMessage());
         }
         JOptionPane.showMessageDialog(
                 this,
                 cause.getMessage(),
                 throwable.getMessage(),
                 JOptionPane.ERROR_MESSAGE);
+        throwable.printStackTrace();
     }
 
     public void sessionOpened()
@@ -222,7 +258,6 @@
                 .addComponent(checkboxContinous, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                 .addContainerGap(35, Short.MAX_VALUE))
         );
-
         javax.swing.GroupLayout imagePanel1Layout = new javax.swing.GroupLayout(imagePanel1);
         imagePanel1.setLayout(imagePanel1Layout);
         imagePanel1Layout.setHorizontalGroup(
@@ -252,6 +287,7 @@
                 .addComponent(imagePanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
         );
         pack();
+
     }
 
     /**
@@ -288,7 +324,7 @@
     private SpinnerNumberModel spinnerWidthModel = new SpinnerNumberModel(175, 50, 1000, 25);
     private SpinnerNumberModel spinnerCharsModel = new SpinnerNumberModel(10, 1, 60, 1);
     private Checkbox checkboxContinous;
-    private ImageClient imageClient = new ImageClient(HOST, PORT, this);
+    private ImageClient imageClient; 
 
 }
 
diff -Naur mina_tuto/src/org/apache/mina/example/imagine/client/ImageClient.java mina_tuto_with_trunk/src/org/apache/mina/example/imagine/client/ImageClient.java
--- mina_tuto/src/org/apache/mina/example/imagine/client/ImageClient.java	2007-05-27 20:17:00.000000000 +0000
+++ mina_tuto_with_trunk/src/org/apache/mina/example/imagine/client/ImageClient.java	2007-07-09 15:39:13.000000000 +0000
@@ -5,13 +5,20 @@
 import org.apache.mina.example.imagine.ImageResponse;
 import org.apache.mina.transport.socket.nio.SocketConnector;
 import org.apache.mina.filter.codec.ProtocolCodecFilter;
+import org.apache.mina.filter.reqres.RequestResponseFilter;
+import org.apache.mina.filter.reqres.Request;
+import org.apache.mina.filter.reqres.Response; 
 import org.apache.mina.common.IoHandlerAdapter;
 import org.apache.mina.common.IoSession;
 import org.apache.mina.common.ConnectFuture;
 import org.apache.mina.common.RuntimeIOException;
+import org.apache.mina.filter.reqres.RequestTimeoutException;
 
+import java.util.concurrent.*;
 import java.net.InetSocketAddress;
 
+import java.util.Hashtable;
+
 public class ImageClient extends IoHandlerAdapter
 {
     public static final int CONNECT_TIMEOUT = 3000;
@@ -20,42 +27,52 @@
     private int port;
     private SocketConnector connector;
     private IoSession session;
-    private ImageListener imageListener;
+    private GraphicalCharGenClient imageListener;
 
-    public ImageClient(String host, int port, ImageListener imageListener)
+    public ImageClient(String host, int port, GraphicalCharGenClient imageListener)
     {
         this.host = host;
         this.port = port;
         this.imageListener = imageListener;
-        connector = new SocketConnector();
+       
+        ExecutorService executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()+1);
+        connector = new SocketConnector(Runtime.getRuntime().availableProcessors(), executor);    
+        // Runtime.getRuntime().availableProcessors() threads for the processing of existing connection
+        // 1 thread for accepting
+    
+        connector.getSessionConfig().setTcpNoDelay(true);
+ 
         connector.getFilterChain().addLast("codec", new ProtocolCodecFilter(new ImageCodecFactory(true)));
+
+        ScheduledThreadPoolExecutor scheduler = new ScheduledThreadPoolExecutor(Runtime.getRuntime().availableProcessors());
+        connector.getFilterChain().addLast("reqres", new RequestResponseFilter(this.imageListener.getResponseInspector(), scheduler));
     }
 
     public void connect()
     {
-        ConnectFuture connectFuture = connector.connect(new InetSocketAddress(host,port), this);
-        connectFuture.join(CONNECT_TIMEOUT);
-        try
-        {
+        connector.setHandler(this);
+        ConnectFuture connectFuture = connector.connect(new InetSocketAddress(host,port));
+        
+        if(connectFuture.awaitUninterruptibly(CONNECT_TIMEOUT)) {
             session = connectFuture.getSession();
+        } else {
+            imageListener.onException(new Exception("timeout connect"));
         }
-        catch (RuntimeIOException e)
-        {
-            imageListener.onException(e);
-        }
+        
     }
 
     public void disconnect() {
         if (session != null)
         {
-            session.close().join(CONNECT_TIMEOUT);
+            // Now connection should be closed.
+            session.close().awaitUninterruptibly(CONNECT_TIMEOUT);
             session = null;
         }
     }
 
     public void sessionOpened(IoSession session) throws Exception
     {
-      imageListener.sessionOpened();
+        imageListener.sessionOpened();
     }
 
     public void sessionClosed(IoSession session) throws Exception
@@ -70,19 +87,33 @@
         }
         else
         {
-            session.write(imageRequest);
+            ((MyResponseInspector2)this.imageListener.getResponseInspector()).addId(imageRequest.getId(), imageRequest.getNb());
+            session.write(new Request(imageRequest.getId(), imageRequest, 5, TimeUnit.SECONDS));
         }
     }
 
     public void messageReceived(IoSession session, Object message) throws Exception
     {
-        ImageResponse response = (ImageResponse) message;
-        imageListener.onImages(response.getImage1(), response.getImage2());
+        final ImageResponse response = (ImageResponse)((Response) message).getMessage();
+        Runnable r =  new Runnable() 
+        {
+             public void run() 
+             {
+                 imageListener.onImages(response.getImage1(), response.getImage2());
+             }
+        };
+        this.imageListener.getPool().execute(r); 
     }
 
     public void exceptionCaught(IoSession session, Throwable cause) throws Exception
     {
+        // clean
+        if(cause instanceof RequestTimeoutException)
+        {
+            RequestTimeoutException rte = (RequestTimeoutException)cause;
+            this.imageListener.getResponseInspector().getHashId().remove(((Request)rte.getRequest()).getId());
+        } 
+    
         imageListener.onException(cause);
     }
-
 }
diff -Naur mina_tuto/src/org/apache/mina/example/imagine/client/ImageListener.java mina_tuto_with_trunk/src/org/apache/mina/example/imagine/client/ImageListener.java
--- mina_tuto/src/org/apache/mina/example/imagine/client/ImageListener.java	2007-05-27 17:26:12.000000000 +0000
+++ mina_tuto_with_trunk/src/org/apache/mina/example/imagine/client/ImageListener.java	2007-07-09 15:08:30.000000000 +0000
@@ -1,5 +1,7 @@
 package org.apache.mina.example.imagine.client;
 
+import java.util.concurrent.ExecutorService;
+import org.apache.mina.filter.reqres.ResponseInspector;
 import java.awt.image.BufferedImage;
 
 public interface ImageListener
diff -Naur mina_tuto/src/org/apache/mina/example/imagine/client/MyResponseInspector2.java mina_tuto_with_trunk/src/org/apache/mina/example/imagine/client/MyResponseInspector2.java
--- mina_tuto/src/org/apache/mina/example/imagine/client/MyResponseInspector2.java	1970-01-01 00:00:00.000000000 +0000
+++ mina_tuto_with_trunk/src/org/apache/mina/example/imagine/client/MyResponseInspector2.java	2007-07-09 15:39:57.000000000 +0000
@@ -0,0 +1,85 @@
+package org.apache.mina.example.imagine.client;
+
+import org.apache.mina.filter.reqres.ResponseType;
+import org.apache.mina.filter.reqres.ResponseInspector;
+
+import org.apache.mina.example.imagine.ImageResponse;
+import org.apache.mina.example.imagine.ImageRequest;
+
+import java.util.Hashtable;
+
+public class MyResponseInspector2 implements ResponseInspector 
+{
+
+    private Hashtable<Integer, ResponseState> mHashId;
+    
+    public MyResponseInspector2()
+    {
+        this.mHashId =  new Hashtable<Integer, ResponseState>();
+    }
+    
+    public Hashtable<Integer, ResponseState> getHashId()
+    {
+        return this.mHashId;
+    }
+
+    public void addId(int id, int nbResponse)
+    {
+        ResponseState responseState = new ResponseState();
+        responseState.mTotalResponse = nbResponse;
+        this.mHashId.put(new Integer(id), responseState);
+    }
+
+    public void setTotalResponse(int id, int nbResponse)
+    {
+        ResponseState responseState = this.mHashId.get(new Integer(id));
+        if (responseState == null) {
+
+        } else {
+            if(responseState.mTotalResponse != 0) {
+
+            } else {
+                responseState.mTotalResponse = nbResponse;
+            }
+        }
+    }
+
+    public Object getRequestId(Object message) 
+    {
+        if (!(message instanceof ImageResponse)) {
+             return null;
+        }
+
+        ImageResponse response = (ImageResponse) message;
+        return response.getId();
+    }
+
+    public ResponseType getResponseType(Object message) {
+        ImageResponse response = (ImageResponse) message;
+        ResponseState responseState = this.mHashId.get(new Integer(response.getId()));
+        
+        if(responseState != null) 
+        {
+            assert responseState.mTotalResponse == 0;
+
+            if(responseState.mNbResponse + 1 == responseState.mTotalResponse) 
+            {
+                this.mHashId.remove(new Integer(response.getId()));
+                /*
+                 * if timeout remove is done in ImageClient.exceptionCaught(...)
+                 * */
+                return ResponseType.PARTIAL_LAST;
+            } 
+            else 
+            {
+                responseState.mNbResponse++;
+                return ResponseType.PARTIAL;
+            }
+        }
+        else
+        {
+            /* must log ... */
+            return ResponseType.PARTIAL;
+        }
+    }
+} 
diff -Naur mina_tuto/src/org/apache/mina/example/imagine/client/ResponseState.java mina_tuto_with_trunk/src/org/apache/mina/example/imagine/client/ResponseState.java
--- mina_tuto/src/org/apache/mina/example/imagine/client/ResponseState.java	1970-01-01 00:00:00.000000000 +0000
+++ mina_tuto_with_trunk/src/org/apache/mina/example/imagine/client/ResponseState.java	2007-07-09 15:14:25.000000000 +0000
@@ -0,0 +1,7 @@
+package org.apache.mina.example.imagine.client;
+
+class ResponseState
+{
+    int mNbResponse;
+    int mTotalResponse; 
+}
diff -Naur mina_tuto/src/org/apache/mina/example/imagine/codec/ImageRequestDecoder.java mina_tuto_with_trunk/src/org/apache/mina/example/imagine/codec/ImageRequestDecoder.java
--- mina_tuto/src/org/apache/mina/example/imagine/codec/ImageRequestDecoder.java	2007-05-27 16:50:42.000000000 +0000
+++ mina_tuto_with_trunk/src/org/apache/mina/example/imagine/codec/ImageRequestDecoder.java	2007-07-05 16:36:08.000000000 +0000
@@ -10,12 +10,15 @@
 {
     protected boolean doDecode(IoSession session, ByteBuffer in, ProtocolDecoderOutput out) throws Exception
     {
-        if (in.remaining() >= 12)
+        if (in.remaining() >= 20)
         {
+            int id = in.getInt();
             int width = in.getInt();
             int height = in.getInt();
             int numberOfCharachters = in.getInt();
-            ImageRequest request = new ImageRequest(width, height, numberOfCharachters);
+            int nb = in.getInt();
+
+            ImageRequest request = new ImageRequest(id, width, height, numberOfCharachters, nb);
             out.write(request);
             return true;
         }
diff -Naur mina_tuto/src/org/apache/mina/example/imagine/codec/ImageRequestEncoder.java mina_tuto_with_trunk/src/org/apache/mina/example/imagine/codec/ImageRequestEncoder.java
--- mina_tuto/src/org/apache/mina/example/imagine/codec/ImageRequestEncoder.java	2007-05-27 16:50:42.000000000 +0000
+++ mina_tuto_with_trunk/src/org/apache/mina/example/imagine/codec/ImageRequestEncoder.java	2007-07-05 12:54:17.000000000 +0000
@@ -6,15 +6,19 @@
 import org.apache.mina.common.ByteBuffer;
 import org.apache.mina.example.imagine.ImageRequest;
 
+import org.apache.mina.filter.reqres.Request;
+
 public class ImageRequestEncoder implements ProtocolEncoder
 {
   public void encode(IoSession session, Object message, ProtocolEncoderOutput out) throws Exception
   {
     ImageRequest request = (ImageRequest) message;
-    ByteBuffer buffer = ByteBuffer.allocate(12, false);
+    ByteBuffer buffer = ByteBuffer.allocate(20, false);
+    buffer.putInt(request.getId());
     buffer.putInt(request.getWidth());
     buffer.putInt(request.getHeight());
     buffer.putInt(request.getNumberOfCharacters());
+    buffer.putInt(request.getNb());
     buffer.flip();
     out.write(buffer);
   }
diff -Naur mina_tuto/src/org/apache/mina/example/imagine/codec/ImageResponseDecoder.java mina_tuto_with_trunk/src/org/apache/mina/example/imagine/codec/ImageResponseDecoder.java
--- mina_tuto/src/org/apache/mina/example/imagine/codec/ImageResponseDecoder.java	2007-05-27 17:42:42.000000000 +0000
+++ mina_tuto_with_trunk/src/org/apache/mina/example/imagine/codec/ImageResponseDecoder.java	2007-07-05 12:55:57.000000000 +0000
@@ -19,21 +19,33 @@
 
     private static class DecoderState
     {
+      int id;
       BufferedImage image1;
     }
 
     protected boolean doDecode(IoSession session, ByteBuffer in, ProtocolDecoderOutput out) throws Exception
     {
+
         DecoderState decoderState = (DecoderState) session.getAttribute(DECODER_STATE_KEY);
         if (decoderState == null)
         {
             decoderState = new DecoderState();
             session.setAttribute(DECODER_STATE_KEY, decoderState);
         }
-        if (decoderState.image1 == null)
+        
+        if(decoderState.id == 0)
+        {
+            if(in.remaining() >= 4) {
+                decoderState.id = in.getInt();
+            } else {
+                return false;
+            }
+        }
+
+        if(decoderState.id != 0 && decoderState.image1 == null)
         {
             // try to read first image
-            if (in.prefixedDataAvailable(4, MAX_IMAGE_SIZE))
+            if(in.prefixedDataAvailable(4, MAX_IMAGE_SIZE))
             {
                 decoderState.image1 = readImage(in);
             }
@@ -43,15 +55,17 @@
                 return false;
             }
         }
+
         if (decoderState.image1 != null)
         {
             // try to read second image
             if (in.prefixedDataAvailable(4, MAX_IMAGE_SIZE))
             {
                 BufferedImage image2 = readImage(in);
-                ImageResponse imageResponse = new ImageResponse(decoderState.image1, image2);
+                ImageResponse imageResponse = new ImageResponse(decoderState.id, decoderState.image1, image2);
                 out.write(imageResponse);
                 decoderState.image1 = null;
+                decoderState.id = 0;
                 return true;
             }
             else
diff -Naur mina_tuto/src/org/apache/mina/example/imagine/codec/ImageResponseEncoder.java mina_tuto_with_trunk/src/org/apache/mina/example/imagine/codec/ImageResponseEncoder.java
--- mina_tuto/src/org/apache/mina/example/imagine/codec/ImageResponseEncoder.java	2007-05-27 20:56:02.000000000 +0000
+++ mina_tuto_with_trunk/src/org/apache/mina/example/imagine/codec/ImageResponseEncoder.java	2007-07-05 12:55:30.000000000 +0000
@@ -18,9 +18,10 @@
         ImageResponse imageResponse = (ImageResponse) message;
         byte[] bytes1 = getBytes(imageResponse.getImage1());
         byte[] bytes2 = getBytes(imageResponse.getImage2());
-        int capacity = bytes1.length + bytes2.length + 8;
+        int capacity = bytes1.length + bytes2.length + 12; // 12 = 3 * int
         ByteBuffer buffer = ByteBuffer.allocate(capacity, false);
         buffer.setAutoExpand(true);
+        buffer.putInt(imageResponse.getId());
         buffer.putInt(bytes1.length);
         buffer.put(bytes1);
         buffer.putInt(bytes2.length);
diff -Naur mina_tuto/src/org/apache/mina/example/imagine/server/ImageServer.java mina_tuto_with_trunk/src/org/apache/mina/example/imagine/server/ImageServer.java
--- mina_tuto/src/org/apache/mina/example/imagine/server/ImageServer.java	2007-05-27 21:43:16.000000000 +0000
+++ mina_tuto_with_trunk/src/org/apache/mina/example/imagine/server/ImageServer.java	2007-07-06 09:04:28.000000000 +0000
@@ -2,10 +2,17 @@
 
 import org.apache.mina.transport.socket.nio.SocketAcceptor;
 import org.apache.mina.filter.codec.ProtocolCodecFilter;
+import org.apache.mina.filter.reqres.RequestResponseFilter;
+import org.apache.mina.filter.executor.ExecutorFilter;
 import org.apache.mina.example.imagine.codec.ImageCodecFactory;
+import org.apache.mina.common.*;
+
 
 import java.net.InetSocketAddress;
 import java.io.IOException;
+import java.util.concurrent.*;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
 
 public class ImageServer
 {
@@ -13,11 +20,22 @@
 
   public static void main(String[] args) throws IOException
   {
-    ImageServerIoHandler handler = new ImageServerIoHandler();
-    SocketAcceptor acceptor = new SocketAcceptor();
+    org.apache.mina.common.ByteBuffer.setAllocator(new org.apache.mina.common.SimpleByteBufferAllocator());
+    
+    ExecutorService executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()+1);
+    SocketAcceptor acceptor = new SocketAcceptor(Runtime.getRuntime().availableProcessors(), executor);    
+    // Runtime.getRuntime().availableProcessors() threads for the processing of existing connection
+    // 1 thread for accepting
+    
+    acceptor.getSessionConfig().setTcpNoDelay(true);
+
     acceptor.getFilterChain().addLast("protocol", new ProtocolCodecFilter(new ImageCodecFactory(false)));
-    acceptor.bind(new InetSocketAddress(PORT), handler);
+   
+   ImageServerIoHandler handler = new ImageServerIoHandler();
+   
+    acceptor.setHandler(handler);
+    acceptor.setLocalAddress(new InetSocketAddress(PORT));
+    acceptor.bind();
     System.out.println("server is listenig at port " + PORT);
   }
-
 }
diff -Naur mina_tuto/src/org/apache/mina/example/imagine/server/ImageServerIoHandler.java mina_tuto_with_trunk/src/org/apache/mina/example/imagine/server/ImageServerIoHandler.java
--- mina_tuto/src/org/apache/mina/example/imagine/server/ImageServerIoHandler.java	2007-05-27 20:14:44.000000000 +0000
+++ mina_tuto_with_trunk/src/org/apache/mina/example/imagine/server/ImageServerIoHandler.java	2007-07-05 15:41:11.000000000 +0000
@@ -22,18 +22,23 @@
 
     public void exceptionCaught(IoSession session, Throwable cause) throws Exception
     {
-        SessionLog.warn(session, cause.getMessage(), cause);
+        //SessionLog.warn(session, cause.getMessage(), cause);
     }
 
     public void messageReceived(IoSession session, Object message) throws Exception
     {
         ImageRequest request = (ImageRequest) message;
+        for(int i = 0 ; i < request.getNb() ; i++)
+        {
         String text1 = generateString(session, request.getNumberOfCharacters());
         String text2 = generateString(session, request.getNumberOfCharacters());
         BufferedImage image1 = createImage(request, text1);
         BufferedImage image2 = createImage(request, text2);
-        ImageResponse response = new ImageResponse(image1, image2);
-        session.write(response);
+        
+        ImageResponse response = new ImageResponse(request.getId(), image1, image2);
+
+            session.write(response);
+        }
     }
 
     private BufferedImage createImage(ImageRequest request, String text)

Reply via email to