I am running a Netty server for an online game, however I am experiencing some weird behavior:
Randomly, the channel just stops being able to write from the server, ie the user is still connected and incoming data is received but outgoing data doesn't reach the client.
I have took the time to debug this and I discovered that channel.isWriteable() is returning false for connecting client with the problem.
Can anyone shine any light on why this might be happening?
What are the reasons for a channel not to become writeable anmore?
By the way, this also happens on a localhost connection too.
public ChannelFuture write(Packet message) {
ioWrite++;
if (!channel.isConnected()) {
System.err.println("Trying to write to bad channel");
return null;
}
if (!channel.isWritable()) {
System.err.println("Channel buffer is full?");
}
if ((channel != null) && channel.isConnected()) {
return channel.write(message);
}
return null;
}
Encoder:
public class GameProtocolEncoder extends OneToOneEncoder {
private ChannelBuffer response;
protected Object encode(ChannelHandlerContext channelHandlerContext, Channel channel, Object o) throws Exception {
Packet p = (Packet) o;
try {
byte[] data = p.getData();
int dataLength = p.getLength();
if (p.getLength() > 5000) {
System.err.println("unable to write data chunk to large");
return null;
}
if (!p.isBare()) {
int siz = 0;
siz += (p.getSize() == Packet.Size.VariableShort)
? 2
: 1;
siz += (p.getId() > 128)
? 2
: 1;
response = ChannelBuffers.buffer(siz + p.getLength());
int id = p.getId();
if (id< 128) {
response.writeByte(id);
} else {
response.writeByte((byte) ((id >> 8) + 128));
response.writeByte((byte) (id & 0xFF));
}
if (p.getSize() != Packet.Size.Fixed) { // variable length
if (p.getSize() == Packet.Size.VariableByte) {
if (dataLength > 255) { // trying to send more data then we can represent with 8 bits!
throw new IllegalArgumentException("Tried to send packet length " + dataLength
+ " in 8 bits [pid=" + p.getId() + "]");
}
response.writeByte((byte) dataLength);
} else if (p.getSize() == Packet.Size.VariableShort) {
if (dataLength > 5000) {
throw new IllegalArgumentException("Tried to send packet length to big: " + id);
}
response.writeShort((short) dataLength);
}
}
} else {
response = ChannelBuffers.buffer(dataLength);
}
response.writeBytes(p.getData());
return response;
} catch (Exception e) {
Logger.err("Error handling message: " + p);
Logger.err(e);
}
return null;
}