这篇文章将为大家详细讲解有关怎么搭建spring+netty服务器,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。
站在用户的角度思考问题,与客户深入沟通,找到宾阳网站设计与宾阳网站推广的解决方案,凭借多年的经验,让设计与互联网技术结合,创造个性化、用户体验好的作品,建站类型包括:成都做网站、网站建设、企业官网、英文网站、手机端网站、网站推广、空间域名、网络空间、企业邮箱。业务覆盖宾阳地区。
我现在用spring+netty搭起简单的游戏服
思路:1自定义协议和协议包;2spring+netty整合;3半包粘包处理,心跳机制等;4请求分发(目前自己搞的都是单例模式)
下个是测试用的,结构如下
首先自定义包头
Header.java
package com.test.netty.message; /** * Header.java * 自定义协议包头 * @author janehuang * @version 1.0 */ public class Header { private byte tag; /* 编码*/ private byte encode; /*加密*/ private byte encrypt; /*其他字段*/ private byte extend1; /*其他2*/ private byte extend2; /*会话id*/ private String sessionid; /*包的长度*/ private int length = 1024; /*命令*/ private int cammand; public Header() { } public Header(String sessionid) { this.encode = 0; this.encrypt = 0; this.sessionid = sessionid; } public Header(byte tag, byte encode, byte encrypt, byte extend1, byte extend2, String sessionid, int length, int cammand) { this.tag = tag; this.encode = encode; this.encrypt = encrypt; this.extend1 = extend1; this.extend2 = extend2; this.sessionid = sessionid; this.length = length; this.cammand = cammand; } @Override public String toString() { return "header [tag=" + tag + "encode=" + encode + ",encrypt=" + encrypt + ",extend1=" + extend1 + ",extend2=" + extend2 + ",sessionid=" + sessionid + ",length=" + length + ",cammand=" + cammand + "]"; } public byte getTag() { return tag; } public void setTag(byte tag) { this.tag = tag; } public byte getEncode() { return encode; } public void setEncode(byte encode) { this.encode = encode; } public byte getEncrypt() { return encrypt; } public void setEncrypt(byte encrypt) { this.encrypt = encrypt; } public byte getExtend1() { return extend1; } public void setExtend1(byte extend1) { this.extend1 = extend1; } public byte getExtend2() { return extend2; } public void setExtend2(byte extend2) { this.extend2 = extend2; } public String getSessionid() { return sessionid; } public void setSessionid(String sessionid) { this.sessionid = sessionid; } public int getLength() { return length; } public void setLength(int length) { this.length = length; } public int getCammand() { return cammand; } public void setCammand(int cammand) { this.cammand = cammand; } }
包体,我简单处理用字符串转字节码,一般好多游戏用probuf系列化成二进制
Message.java
package com.test.netty.message; import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.UnsupportedEncodingException; import com.test.netty.decoder.MessageDecoder; /** * Message.java * * @author janehuang * @version 1.0 */ public class Message { private Header header; private String data; public Header getHeader() { return header; } public void setHeader(Header header) { this.header = header; } public String getData() { return data; } public void setData(String data) { this.data = data; } public Message(Header header) { this.header = header; } public Message(Header header, String data) { this.header = header; this.data = data; } public byte[] toByte() { ByteArrayOutputStream out = new ByteArrayOutputStream(); out.write(MessageDecoder.PACKAGE_TAG); out.write(header.getEncode()); out.write(header.getEncrypt()); out.write(header.getExtend1()); out.write(header.getExtend2()); byte[] bb = new byte[32]; byte[] bb2 = header.getSessionid().getBytes(); for (int i = 0; i < bb2.length; i++) { bb[i] = bb2[i]; } try { out.write(bb); byte[] bbb = data.getBytes("UTF-8"); out.write(intToBytes2(bbb.length)); out.write(intToBytes2(header.getCammand())); out.write(bbb); out.write('\n'); } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return out.toByteArray(); } public static byte[] intToByte(int newint) { byte[] intbyte = new byte[4]; intbyte[3] = (byte) ((newint >> 24) & 0xFF); intbyte[2] = (byte) ((newint >> 16) & 0xFF); intbyte[1] = (byte) ((newint >> 8) & 0xFF); intbyte[0] = (byte) (newint & 0xFF); return intbyte; } public static int bytesToInt(byte[] src, int offset) { int value; value = (int) ((src[offset] & 0xFF) | ((src[offset + 1] & 0xFF) << 8) | ((src[offset + 2] & 0xFF) << 16) | ((src[offset + 3] & 0xFF) << 24)); return value; } public static byte[] intToBytes2(int value) { byte[] src = new byte[4]; src[0] = (byte) ((value >> 24) & 0xFF); src[1] = (byte) ((value >> 16) & 0xFF); src[2] = (byte) ((value >> 8) & 0xFF); src[3] = (byte) (value & 0xFF); return src; } public static void main(String[] args) { ByteBuf heapBuffer = Unpooled.buffer(8); System.out.println(heapBuffer); ByteArrayOutputStream out = new ByteArrayOutputStream(); try { out.write(intToBytes2(1)); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } byte[] data = out.toByteArray(); heapBuffer.writeBytes(data); System.out.println(heapBuffer); int a = heapBuffer.readInt(); System.out.println(a); } }
解码器
MessageDecoder.java
package com.test.netty.decoder; import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.ByteToMessageDecoder; import io.netty.handler.codec.CorruptedFrameException; import java.util.List; import com.test.netty.message.Header; import com.test.netty.message.Message; /** * HeaderDecoder.java * * @author janehuang * @version 1.0 */ public class MessageDecoder extends ByteToMessageDecoder { /**包长度志头**/ public static final int HEAD_LENGHT = 45; /**标志头**/ public static final byte PACKAGE_TAG = 0x01; @Override protected void decode(ChannelHandlerContext ctx, ByteBuf buffer, List