Browse Source

Decoder optimizations

master
Nikita 13 years ago
parent
commit
2547c722ac
  1. 2
      src/main/java/com/corundumstudio/socketio/AuthorizeHandler.java
  2. 30
      src/main/java/com/corundumstudio/socketio/PacketHandler.java
  3. 5
      src/main/java/com/corundumstudio/socketio/SocketIOEncoder.java
  4. 44
      src/main/java/com/corundumstudio/socketio/parser/Decoder.java
  5. 2
      src/main/java/com/corundumstudio/socketio/transport/WebSocketTransport.java
  6. 2
      src/main/java/com/corundumstudio/socketio/transport/XHRPollingTransport.java

2
src/main/java/com/corundumstudio/socketio/AuthorizeHandler.java

@ -29,6 +29,7 @@ import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.MessageEvent;
import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
import org.jboss.netty.channel.ChannelHandler.Sharable;
import org.jboss.netty.handler.codec.http.HttpHeaders;
import org.jboss.netty.handler.codec.http.HttpMethod;
import org.jboss.netty.handler.codec.http.HttpRequest;
@ -40,6 +41,7 @@ import com.corundumstudio.socketio.messages.AuthorizeMessage;
import com.corundumstudio.socketio.parser.Packet;
import com.corundumstudio.socketio.parser.PacketType;
@Sharable
public class AuthorizeHandler extends SimpleChannelUpstreamHandler implements Disconnectable {
private final Logger log = LoggerFactory.getLogger(getClass());

30
src/main/java/com/corundumstudio/socketio/PacketHandler.java

@ -51,20 +51,13 @@ public class PacketHandler extends SimpleChannelUpstreamHandler {
private Packet decode(ChannelBuffer buffer) throws IOException {
if (isCurrentDelimiter(buffer, buffer.readerIndex())) {
StringBuilder length = new StringBuilder(4);
for (int i = buffer.readerIndex() + Packet.DELIMITER_BYTES.length; i < buffer.readerIndex() + buffer.readableBytes(); i++) {
if (isCurrentDelimiter(buffer, i)) {
break;
} else {
length.append((char)buffer.getUnsignedByte(i));
}
}
Integer len = Integer.valueOf(length.toString());
buffer.readerIndex(buffer.readerIndex() + Packet.DELIMITER_BYTES.length);
Integer len = parseLength(buffer);
int startIndex = buffer.readerIndex() + Packet.DELIMITER_BYTES.length + length.length() + Packet.DELIMITER_BYTES.length;
ChannelBuffer frame = buffer.slice(startIndex, len);
ChannelBuffer frame = buffer.slice(buffer.readerIndex(), len);
Packet packet = decoder.decodePacket(frame);
buffer.readerIndex(startIndex + len);
buffer.readerIndex(buffer.readerIndex() + len);
return packet;
} else {
Packet packet = decoder.decodePacket(buffer);
@ -73,6 +66,19 @@ public class PacketHandler extends SimpleChannelUpstreamHandler {
}
}
private Integer parseLength(ChannelBuffer buffer) {
byte[] digits = null;
for (int i = buffer.readerIndex(); i < buffer.readerIndex() + buffer.readableBytes(); i++) {
if (isCurrentDelimiter(buffer, i)) {
digits = new byte[i - buffer.readerIndex()];
buffer.getBytes(buffer.readerIndex(), digits);
break;
}
}
buffer.readerIndex(buffer.readerIndex() + digits.length + Packet.DELIMITER_BYTES.length);
return decoder.parseInt(digits);
}
private boolean isCurrentDelimiter(ChannelBuffer buffer, int index) {
for (int i = 0; i < Packet.DELIMITER_BYTES.length; i++) {
if (buffer.getByte(index + i) != Packet.DELIMITER_BYTES[i]) {

5
src/main/java/com/corundumstudio/socketio/SocketIOEncoder.java

@ -36,6 +36,7 @@ import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelFuture;
import org.jboss.netty.channel.ChannelFutureListener;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.ChannelHandler.Sharable;
import org.jboss.netty.handler.codec.http.DefaultHttpResponse;
import org.jboss.netty.handler.codec.http.HttpHeaders;
import org.jboss.netty.handler.codec.http.HttpResponse;
@ -59,6 +60,7 @@ import com.corundumstudio.socketio.messages.XHRPostMessage;
import com.corundumstudio.socketio.parser.Encoder;
import com.corundumstudio.socketio.parser.Packet;
@Sharable
public class SocketIOEncoder extends OneToOneEncoder implements MessageHandler {
class XHRClientEntry {
@ -146,9 +148,6 @@ public class SocketIOEncoder extends OneToOneEncoder implements MessageHandler {
break;
}
}
if (packets.isEmpty()) {
return;
}
String message = encoder.encodePackets(packets);
sendMessage(origin, sessionId, channel, message);

44
src/main/java/com/corundumstudio/socketio/parser/Decoder.java

@ -70,17 +70,32 @@ public class Decoder {
}
*/
// fastest way to parse chars to int
public Integer parseInt(byte[] chars) {
int result = 0;
for (int i = 0; i < chars.length; i++) {
int digit = ((int)chars[i] & 0xF);
for (int j = 0; j < chars.length-1-i; j++) {
digit *= 10;
}
result += digit;
}
return result;
}
public Packet decodePacket(ChannelBuffer buffer) throws IOException {
byte typeId = Byte.valueOf(Character.valueOf((char)buffer.getUnsignedByte(0)).toString());
if (typeId >= PacketType.VALUES.length
|| buffer.getByte(1) != separator) {
if (buffer.readableBytes() < 3) {
throw new DecoderException("Can't parse " + buffer.toString(CharsetUtil.UTF_8));
}
PacketType type = PacketType.valueOf(typeId);
PacketType type = getType(buffer);
int readerIndex = 1;
StringBuilder messageId = new StringBuilder(4);
// 'null' to avoid unnecessary StringBuilder creation
StringBuilder messageId = null;
for (readerIndex += 1; readerIndex < buffer.readableBytes(); readerIndex++) {
if (messageId == null) {
messageId = new StringBuilder(4);
}
byte msg = buffer.getByte(readerIndex);
if (msg == separator) {
break;
@ -90,12 +105,16 @@ public class Decoder {
}
}
Integer id = null;
if (messageId.length() > 0) {
if (messageId != null && messageId.length() > 0) {
id = Integer.valueOf(messageId.toString());
}
StringBuilder endpointBuffer = new StringBuilder();
// 'null' to avoid unnecessary StringBuilder creation
StringBuilder endpointBuffer = null;
for (readerIndex += 1; readerIndex < buffer.readableBytes(); readerIndex++) {
if (endpointBuffer == null) {
endpointBuffer = new StringBuilder();
}
byte msg = buffer.getByte(readerIndex);
if (msg == separator) {
break;
@ -104,7 +123,7 @@ public class Decoder {
}
String endpoint = null;
if (endpointBuffer.length() > 0) {
if (endpointBuffer != null && endpointBuffer.length() > 0) {
endpoint = endpointBuffer.toString();
}
@ -193,6 +212,15 @@ public class Decoder {
return packet;
}
private PacketType getType(ChannelBuffer buffer) {
int typeId = buffer.getByte(0) & 0xF;
if (typeId >= PacketType.VALUES.length
|| buffer.getByte(1) != separator) {
throw new DecoderException("Can't parse " + buffer.toString(CharsetUtil.UTF_8));
}
return PacketType.valueOf(typeId);
}
private String extract(Matcher matcher, int index) {
if (index > matcher.groupCount()) {
return null;

2
src/main/java/com/corundumstudio/socketio/transport/WebSocketTransport.java

@ -26,6 +26,7 @@ import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.Channels;
import org.jboss.netty.channel.MessageEvent;
import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
import org.jboss.netty.channel.ChannelHandler.Sharable;
import org.jboss.netty.handler.codec.http.HttpHeaders;
import org.jboss.netty.handler.codec.http.HttpRequest;
import org.jboss.netty.handler.codec.http.QueryStringDecoder;
@ -42,6 +43,7 @@ import com.corundumstudio.socketio.Disconnectable;
import com.corundumstudio.socketio.SocketIOClient;
import com.corundumstudio.socketio.messages.PacketsMessage;
@Sharable
public class WebSocketTransport extends SimpleChannelUpstreamHandler implements Disconnectable {
private final Logger log = LoggerFactory.getLogger(getClass());

2
src/main/java/com/corundumstudio/socketio/transport/XHRPollingTransport.java

@ -25,6 +25,7 @@ import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.Channels;
import org.jboss.netty.channel.MessageEvent;
import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
import org.jboss.netty.channel.ChannelHandler.Sharable;
import org.jboss.netty.handler.codec.http.HttpHeaders;
import org.jboss.netty.handler.codec.http.HttpMethod;
import org.jboss.netty.handler.codec.http.HttpRequest;
@ -45,6 +46,7 @@ import com.corundumstudio.socketio.parser.ErrorReason;
import com.corundumstudio.socketio.parser.Packet;
import com.corundumstudio.socketio.parser.PacketType;
@Sharable
public class XHRPollingTransport extends SimpleChannelUpstreamHandler implements Disconnectable {
private final Logger log = LoggerFactory.getLogger(getClass());

Loading…
Cancel
Save