一、协议
1. 请求:
字段 | 类型 | 说明 |
length | short | 消息长度 |
commandid | short | 消息类型 |
userid | int | 用户号 |
字段 | 类型 | 说明 |
length | short | 消息长度 |
commandid | short | 消息类型 |
userid | int | 用户号 |
result | byte | 0: 成功 1: 失败 |
public abstract class KaMessage {
protected short commandId;
protected int userId;
public static final short HEADLENGTH = 6;
public static final short REQ = 0x0001;
public static final short RES = 0x1001;
public void encode(ByteBuffer buffer) {
buffer.putInt(userId);
subencode(buffer);
}
public void decode(ByteBuffer buffer) {
userId = buffer.getInt();
subdecode(buffer);
}
public abstract short length();
public abstract void subencode(ByteBuffer buffer);
public abstract void subdecode(ByteBuffer buffer);
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
public short getCommandId() {
return commandId;
}
}
public class KaRes extends KaMessage {
private short result = 200;
public KaRes() {
commandId = KaMessage.RES;
}
@Override
public short length() {
// TODO Auto-generated method stub
short len = KaMessage.HEADLENGTH;
len += 2;
return len;
}
@Override
public void subencode(ByteBuffer buffer) {
// TODO Auto-generated method stub
buffer.putShort(result);
}
@Override
public void subdecode(ByteBuffer buffer) {
// TODO Auto-generated method stub
result = buffer.getShort();
}
@Override
public String toString() {
// TODO Auto-generated method stub
StringBuffer sb = new StringBuffer();
sb.append(super.toString());
sb.append(" - result: " + result);
return sb.toString();
}
public short getResult() {
return result;
}
public void setResult(short result) {
this.result = result;
}
}
public class KaReq extends KaMessage {
public KaReq() {
commandId = KaMessage.REQ;
}
@Override
public void subencode(ByteBuffer buffer) {
// TODO Auto-generated method stub
}
@Override
public short length() {
// TODO Auto-generated method stub
short len = PaMessage.HEADLENGTH;
return len;
}
@Override
public void subdecode(ByteBuffer buffer) {
// TODO Auto-generated method stub
}
}
public class KaCodecUtil {
public static byte[] NetEncode(PaMessage message) {
ByteBuffer buffer = ByteBuffer.allocate(message.length() + 2);
buffer.putShort(message.length());
buffer.putShort(message.getCommandId());
message.encode(buffer);
return buffer.array();
}
public static KaMessage NetDecode(byte[] data) {
ByteBuffer buffer = ByteBuffer.wrap(data);
short commandId = buffer.getShort();
PaMessage message = null;
switch(commandId) {
case KaMessage.SEQ:
message = new KaReq();
message.decode(buffer);
return message;
case KaMessage.Res:
message = new KaRes();
message.decode(buffer);
return message;
}
return message;
}
public class KaEncoder extends OneToOneEncoder {
@Override
protected Object encode(ChannelHandlerContext context, Channel channel,
Object object) throws Exception {
// TODO Auto-generated method stub
KaMessage message = (KaMessage)object;
ChannelBuffer buf = ChannelBuffers.dynamicBuffer();
buf.writeBytes(KaCodecUtil.NetEncode(message));
return buf;
}
}
public class KaDecoder extends FrameDecoder {
@Override
protected Object decode(ChannelHandlerContext context, Channel channel,
ChannelBuffer buffer) throws Exception {
// TODO Auto-generated method stub
if(buffer.readableBytes() < 2) {
buffer.resetReaderIndex();
return null;
}
short length = buffer.readShort();
if(buffer.readableBytes() < length) {
buffer.resetReaderIndex();
return null;
}
byte[] decode = new byte[length];
buffer.readBytes(decode);
KaMessage message = KaCodecUtil.NetDecode(decode);
return message;
}
}
public class ServerBoot {
public static void main(String[] args) {
ChannelPipelineFactory pipelineFactory = new ChannelPipelineFactory() {
public ChannelPipeline getPipeline() {
ChannelPipeline pipeline = Channels.pipeline();
pipeline.addLast("decoder", new KaDecoder());
pipeline.addLast("encoder", new KaEncoder());
pipeline.addLast("handler", new KaHandler());
return pipeline;
}
};
ChannelFactory factory = new NioServerSocketChannelFactory(Executors.newCachedThreadPool(), Executors.newCachedThreadPool());
ServerBootstrap bootstrap = new ServerBootstrap(factory);
bootstrap.setPipelineFactory(pipelineFactory);
bootstrap.setOption("child.tcpNoDelay", true);
bootstrap.setOption("child.keepAlive", true);
bootstrap.bind(new InetSocketAddress(8080));
}
}
public class KaHandler extends SimpleChannelUpstreamHandler {
private static Logger log = Logger.getLogger(PaHandler.class);
@Override
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
try {
KaMessage req = (KaMessage) e.getMessage();
log.info("messageReceived: " + req);
KaRes res = new KaRes();
e.getChannel().write(res);
}catch(Exception ee) {
ee.printStackTrace();
}
}
}
三、客户端代码
public class ServerBoot {
public static void main(String[] args) {
// TODO Auto-generated method stub
ClientBootstrap bootstrap = new ClientBootstrap(
new NioClientSocketChannelFactory(
Executors.newCachedThreadPool(),
Executors.newCachedThreadPool()));
bootstrap.getPipeline().addLast("encoder", new KaEncoder());
bootstrap.getPipeline().addLast("decoder", new KaDecoder());
bootstrap.getPipeline().addLast("handler", new KaHandler());
ChannelFuture future = bootstrap.connect(new InetSocketAddress("127.0.0.1", 8080));
future.awaitUninterruptibly();
Channel channel = future.getChannel();
KaReq req = new KaReq();
future = channel.write(req);
future.awaitUninterruptibly();
}
}