Dear mina team and users,
I'm experiencing a behavior in which the server sends the data
unordered.
I struggled with the problem for a while and I believe that I succeeded
to pin point the problem.
Server side:
The server is based on mina 2.0.0 M6
I'm using 2 filters, the first one is FileWithHeaderWriteFilter and the
second is an ExecutorFilter.
No Decoders & Encoders are in use.
Once a connection is established the server sends a burst of messages
(couple of hundreds, each message is a few Kb) to the client, where each
message is a file preceded by a meta data string associated with the
file.
Here is the code in the session handler for sending these files:
public void sessionOpened(final IoSession session)
{
// Creating a thread to do all the job
new Thread(){
public void run() {
try {
File[] files = new
File("\\mailbox").listFiles();
for (File file : files)
{
FileWithHeader
fileWithHeader = new FileWithHeader(file);
System.out.println("send
"+file.getName()+ " len "+file.length());
session.write(fileWithHeader);
}
} catch (IOException e) {
}
}}.start();
}
The FileWithHeaderWriteFilter is used to send files, it extends
AbstractStreamWriteFilter<FileWithHeader>.
The main methods of FileWithHeaderWriteFilter are:
protected IoBuffer getNextBuffer(FileWithHeader message)
throws IOException
{
if (!message.isStarted())
{
message.markAsStarted();
return getHeader(message);
}
return getFile(message);
}
private IoBuffer getHeader(FileWithHeader message)
throws IOException
{
/* int for the message len + message itself */
String header = message.getHeader().to String();
int capacity = header.length() + 4;
IoBuffer buffer = IoBuffer.allocate(capacity, false);
buffer.putInt(header.length());
buffer.put(header.getBytes());
buffer.flip();
return buffer;
}
private IoBuffer getFile(FileWithHeader message) throws IOException
{
FileRegion fileRegion = message.getFileRegion();
// If there are no more bytes to read, return null
if (fileRegion.getRemainingBytes() <= 0)
{
return null;
}
// Allocate the buffer for reading from the file
final int bufferSize = (int) Math.min(getWriteBufferSize(),
fileRegion.getRemainingBytes());
IoBuffer buffer = IoBuffer.allocate(bufferSize);
// Read from the file
int bytesRead = fileRegion.getFileChannel().read(buffer.buf(),
fileRegion.getPosition());
fileRegion.update(bytesRead);
// return the buffer
buffer.flip();
return buffer;
}
As you can see first it sends the header as a string and then the file
content. That's it. The getFile method is a replica of
FileRegionWriteFilter.getNextBuffer().
The FileWithHeader class is actually a wrapper to FileRegion, it holds
DefaultFileRegion and the header.
Am I doing something wrong or do you think this could be a bug?
Thanks in advance,
Guy