Hi Endolf and Kev,
I like your NIO API, its quite elegant and simple. I examined your code and ran my own tests and I noticed that the recieveMessage method would return null twice before it returned a message, even when I knew the message was waiting there. So I changed the method to this, and it works as it should:
public Message readMessage() throws IOException {
int addBytes;
if (invalid) {
return null;
}
if (state == WAIT_FOR_CODE) {
addBytes = channel.read(shortBuffer);
if (addBytes < 0) {
invalid = true;
throw new IOException("Connection closed");
}
read += addBytes;
if (read == 2) {
messageCode = shortBuffer.getShort(0);
shortBuffer.rewind();
state = WAIT_FOR_LENGTH;
read = 0;
}
//return null;
} //else if (state == WAIT_FOR_LENGTH) {
if (state == WAIT_FOR_LENGTH) {
addBytes = channel.read(shortBuffer);
if (addBytes < 0) {
invalid = true;
throw new IOException("Connection closed");
}
read += addBytes;
if (read == 2) {
messageLength = shortBuffer.getShort(0);
bodyBuffer.limit(messageLength);
shortBuffer.rewind();
state = READING_BODY;
read = 0;
}
//return null;
} //else if (state == READING_BODY) {
if (state == READING_BODY) {
addBytes = channel.read(bodyBuffer);
if (addBytes < 0) {
invalid = true;
throw new IOException("Connection closed");
}
read += addBytes;
if (read == messageLength) {
Message message = factory.getMessage(messageCode);
if (message != null) {
ByteArrayMessageEncoder.decode(message,bodyBuffer.array());
}
bodyBuffer.rewind();
state = WAIT_FOR_CODE;
read = 0;
return message;
}
//return null;
}
return null;
}
Good idea?
Also, how hard would it be to adapt your library to UDP NIO?
Thanks,
Keith