├── .gitignore
├── README
├── gserver-core
├── .gitignore
├── pom.xml
└── src
│ └── main
│ ├── java
│ └── org
│ │ └── gserver
│ │ └── core
│ │ ├── exception
│ │ └── GsException.java
│ │ ├── handler
│ │ └── IHandler.java
│ │ ├── net
│ │ ├── Header.java
│ │ ├── Message.java
│ │ └── codec
│ │ │ ├── Decoder.java
│ │ │ ├── Encoder.java
│ │ │ ├── HeaderDecoder.java
│ │ │ ├── HeaderEncoder.java
│ │ │ ├── decoder
│ │ │ └── ProtobufDecoder.java
│ │ │ └── encoder
│ │ │ └── ProtobufEncoder.java
│ │ ├── server
│ │ ├── AbstractServer.java
│ │ ├── config
│ │ │ ├── ClientServerConfig.java
│ │ │ ├── Config.java
│ │ │ ├── ServerConfig.java
│ │ │ └── ServerInfo.java
│ │ ├── impl
│ │ │ ├── ClientServer.java
│ │ │ └── Server.java
│ │ └── loader
│ │ │ ├── ClientServerConfigXmlLoader.java
│ │ │ └── ServerConfigXmlLoader.java
│ │ ├── threadPool
│ │ ├── AbstractWork.java
│ │ ├── executor
│ │ │ ├── NonOrderedQueuePoolExecutor.java
│ │ │ └── OrderedQueuePoolExecutor.java
│ │ └── struts
│ │ │ ├── OrderedQueuePool.java
│ │ │ └── TasksQueue.java
│ │ └── util
│ │ ├── ChannelPoolManager.java
│ │ ├── SessionChannelManager.java
│ │ └── SessionUtil.java
│ └── resources
│ └── log4j.properties
├── gserver-db
├── .gitignore
├── pom.xml
└── src
│ └── main
│ ├── java
│ └── org
│ │ └── gserver
│ │ └── db
│ │ ├── IMysqlJdbcTemplate.java
│ │ ├── MysqlJdbcTemplate.java
│ │ └── accessor
│ │ ├── AbstractMysqlAccessor.java
│ │ ├── IMysqlAccessor.java
│ │ ├── JdbcFactory.java
│ │ ├── MysqlAccessor.java
│ │ └── SQLUtil.java
│ └── resources
│ └── gs-mysql.xml
├── gserver-distribution
├── .gitignore
├── assembly.xml
├── pom.xml
├── shell
│ ├── all-shutdown.bat
│ └── all-startup.bat
└── src
│ └── main
│ └── java
│ └── org
│ └── gserver
│ └── distribution
│ └── App.java
├── gserver-gate
├── .gitignore
├── gate-config
│ ├── connect-app-config.xml
│ └── server-config.xml
├── pom.xml
├── shell
│ └── gate-startup.bat
└── src
│ ├── main
│ ├── java
│ │ └── org
│ │ │ └── gserver
│ │ │ ├── GateStart.java
│ │ │ └── gate
│ │ │ ├── ChannelCloseListener.java
│ │ │ ├── GateHandler.java
│ │ │ ├── GatePipelineFactory.java
│ │ │ ├── GateServer.java
│ │ │ └── clientServer
│ │ │ ├── ConnectAppServer.java
│ │ │ ├── ConnectHandler.java
│ │ │ └── ConnectPipelineFactory.java
│ └── resources
│ │ ├── gs-application.xml
│ │ └── log4j.properties
│ └── test
│ └── java
│ └── org
│ └── gserver
│ └── test
│ ├── Client.java
│ └── ClientHandler.java
├── gserver-logic
├── .gitignore
├── logic-config
│ └── server-config.xml
├── pom.xml
├── shell
│ └── logic-startup.bat
└── src
│ └── main
│ ├── java
│ └── org
│ │ └── gserver
│ │ ├── LogicStart.java
│ │ ├── handler
│ │ └── Handler100001.java
│ │ └── logic
│ │ ├── LogicHandler.java
│ │ ├── LogicPipelineFactory.java
│ │ └── LogicServer.java
│ └── resources
│ ├── gs-handlers.xml
│ └── log4j.properties
├── gserver-redis
├── .gitignore
├── pom.xml
└── src
│ └── main
│ ├── java
│ └── org
│ │ └── gserver
│ │ └── redis
│ │ ├── IRedisTemplateMethod.java
│ │ ├── RedisTemplateMethod.java
│ │ ├── accessor
│ │ ├── AbstractRedisAccessor.java
│ │ ├── IRedisAccessor.java
│ │ ├── RedisAccessor.java
│ │ └── RedisFactory.java
│ │ ├── persistence
│ │ ├── AbstractRedisBean.java
│ │ └── RedisBeanField.java
│ │ └── util
│ │ ├── BeanUtil.java
│ │ └── KeyUtil.java
│ └── resources
│ ├── gs-context.xml
│ ├── gs-redis.xml
│ └── redis.properties
├── gserver-services
├── .gitignore
├── pom.xml
└── src
│ └── main
│ ├── java
│ ├── org
│ │ └── gserver
│ │ │ ├── dao
│ │ │ ├── BaseDao.java
│ │ │ ├── IBaseDao.java
│ │ │ └── IRedisKey.java
│ │ │ ├── handler
│ │ │ └── AbstractHandler.java
│ │ │ ├── services
│ │ │ ├── SendMessageService.java
│ │ │ └── SessionService.java
│ │ │ └── util
│ │ │ ├── CommandEnum.java
│ │ │ ├── CommandEnumUtil.java
│ │ │ ├── Components.java
│ │ │ ├── ErrorCode.java
│ │ │ ├── ServerType.java
│ │ │ └── SpringContainer.java
│ └── protocol
│ │ ├── BaseType.java
│ │ ├── ClientServerProtocol.java
│ │ └── ServerClientProtocol.java
│ └── resources
│ └── gs-service.xml
└── pom.xml
/.gitignore:
--------------------------------------------------------------------------------
1 | /target
2 | /logs
3 | /.settings
--------------------------------------------------------------------------------
/README:
--------------------------------------------------------------------------------
1 | 服务:
2 | gserver-gate:网关服务器
3 | gserver-logic:逻辑服务器
4 |
5 | 公用类:
6 | gserver-core:核心类
7 | gserver-redis:redis缓存管理
8 | gserver-services:逻辑类
9 | gserver-db:mysql数据库管理
10 |
11 | 打包:
12 | gserver-distribute:打包程序,路径/target目录下
13 |
--------------------------------------------------------------------------------
/gserver-core/.gitignore:
--------------------------------------------------------------------------------
1 | /target
2 | /logs
3 | /.settings
--------------------------------------------------------------------------------
/gserver-core/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | com.gserver
8 | gserver
9 | 0.0.1-SNAPSHOT
10 |
11 | gserver-core
12 |
13 | gserver-core
14 | http://maven.apache.org
15 |
16 | UTF-8
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/gserver-core/src/main/java/org/gserver/core/exception/GsException.java:
--------------------------------------------------------------------------------
1 | package org.gserver.core.exception;
2 |
3 | public class GsException extends Exception {
4 |
5 | private static final long serialVersionUID = 1L;
6 | private int errorCode;
7 | private String message;
8 |
9 | public GsException(int errorCode) {
10 | this.errorCode = errorCode;
11 | }
12 |
13 | public GsException(int errorCode, String message) {
14 | super(message);
15 | this.message = message;
16 | this.errorCode = errorCode;
17 | }
18 |
19 | public String getMessage() {
20 | return message;
21 | }
22 |
23 | public void setMessage(String message) {
24 | this.message = message;
25 | }
26 |
27 | public int getErrorCode() {
28 | return errorCode;
29 | }
30 |
31 | public void setErrorCode(int errorCode) {
32 | this.errorCode = errorCode;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/gserver-core/src/main/java/org/gserver/core/handler/IHandler.java:
--------------------------------------------------------------------------------
1 | package org.gserver.core.handler;
2 |
3 | import org.gserver.core.exception.GsException;
4 | import org.gserver.core.net.Message;
5 |
6 | import com.google.protobuf.InvalidProtocolBufferException;
7 |
8 | public interface IHandler {
9 | /**
10 | * 业务处理方法
11 | *
12 | * @param request
13 | * 客户端请求
14 | */
15 | abstract public void execute(Message request) throws GsException,
16 | InvalidProtocolBufferException;
17 | }
18 |
--------------------------------------------------------------------------------
/gserver-core/src/main/java/org/gserver/core/net/Header.java:
--------------------------------------------------------------------------------
1 | package org.gserver.core.net;
2 |
3 | /**
4 | * 请求和返回的头文件
5 | *
6 | * @author zhaohui
7 | *
8 | */
9 | public class Header implements Cloneable {
10 | /** 数据编码格式。已定义:0:UTF-8,1:GBK,2:GB2312,3:ISO8859-1 **/
11 | private byte encode;
12 | /** 加密类型。0表示不加密 **/
13 | private byte encrypt;
14 | /** 用于扩展协议。暂未定义任何值 **/
15 | private byte extend1;
16 | /** 用于扩展协议。暂未定义任何值 **/
17 | private byte extend2;
18 | /** 会话ID **/
19 | private int sessionId;
20 | /** 数据包长 **/
21 | private int length;
22 | /** 命令 **/
23 | private int commandId;
24 |
25 | @Override
26 | public Header clone() {
27 | try {
28 | return (Header) super.clone();
29 | } catch (CloneNotSupportedException e) {
30 | e.printStackTrace();
31 | }
32 | return null;
33 | }
34 |
35 | public Header() {
36 |
37 | }
38 |
39 | public Header(int sessionid, int commandId) {
40 | this.encode = 0;
41 | this.encrypt = 0;
42 | this.sessionId = sessionid;
43 | this.commandId = commandId;
44 | }
45 |
46 | public Header(byte encode, byte encrypt, byte extend1, byte extend2,
47 | int sessionId, int length, int commandId) {
48 | this.encode = encode;
49 | this.encrypt = encrypt;
50 | this.extend1 = extend1;
51 | this.extend2 = extend2;
52 | this.sessionId = sessionId;
53 | this.length = length;
54 | this.commandId = commandId;
55 | }
56 |
57 | public byte getEncode() {
58 | return encode;
59 | }
60 |
61 | public void setEncode(byte encode) {
62 | this.encode = encode;
63 | }
64 |
65 | public byte getEncrypt() {
66 | return encrypt;
67 | }
68 |
69 | public void setEncrypt(byte encrypt) {
70 | this.encrypt = encrypt;
71 | }
72 |
73 | public byte getExtend1() {
74 | return extend1;
75 | }
76 |
77 | public void setExtend1(byte extend1) {
78 | this.extend1 = extend1;
79 | }
80 |
81 | public byte getExtend2() {
82 | return extend2;
83 | }
84 |
85 | public void setExtend2(byte extend2) {
86 | this.extend2 = extend2;
87 | }
88 |
89 | public int getSessionId() {
90 | return sessionId;
91 | }
92 |
93 | public void setSessionId(int sessionId) {
94 | this.sessionId = sessionId;
95 | }
96 |
97 | public int getLength() {
98 | return length;
99 | }
100 |
101 | public void setLength(int length) {
102 | this.length = length;
103 | }
104 |
105 | public int getCommandId() {
106 | return commandId;
107 | }
108 |
109 | public void setCommandId(int commandId) {
110 | this.commandId = commandId;
111 | }
112 |
113 | @Override
114 | public String toString() {
115 | return "header [encode=" + encode + ",encrypt=" + encrypt + ",extend1="
116 | + extend1 + ",extend2=" + extend2 + ",sessionid=" + sessionId
117 | + ",length=" + length + ",commandId=" + commandId + "]";
118 | }
119 |
120 | }
121 |
--------------------------------------------------------------------------------
/gserver-core/src/main/java/org/gserver/core/net/Message.java:
--------------------------------------------------------------------------------
1 | package org.gserver.core.net;
2 |
3 | /**
4 | * 消息
5 | *
6 | * @author zhaohui
7 | *
8 | */
9 | public class Message {
10 | /** 头消息 **/
11 | private Header header;
12 | /** 数据 **/
13 | private Object data;
14 |
15 | public Message() {
16 |
17 | }
18 |
19 | public Message(Header header) {
20 | this.header = header;
21 | }
22 |
23 | public Message(Header header, Object data) {
24 | this.header = header;
25 | this.data = data;
26 | }
27 |
28 | public void setContent(int commandId, byte[] data) {
29 | header.setCommandId(commandId);
30 | this.data = data;
31 | }
32 |
33 | public int getSessionId() {
34 | return header.getSessionId();
35 | }
36 |
37 | public Object getData() {
38 | return data;
39 | }
40 |
41 | public void setData(Object data) {
42 | this.data = data;
43 | }
44 |
45 | public Header getHeader() {
46 | return header;
47 | }
48 |
49 | public void setHeader(Header header) {
50 | this.header = header;
51 | }
52 |
53 | public int getCommand() {
54 | return getHeader().getCommandId();
55 | }
56 |
57 | }
58 |
--------------------------------------------------------------------------------
/gserver-core/src/main/java/org/gserver/core/net/codec/Decoder.java:
--------------------------------------------------------------------------------
1 | package org.gserver.core.net.codec;
2 |
3 | import org.gserver.core.net.Message;
4 | import org.jboss.netty.channel.Channel;
5 | import org.jboss.netty.channel.ChannelHandlerContext;
6 | import org.jboss.netty.handler.codec.oneone.OneToOneDecoder;
7 |
8 | /**
9 | * 解码器
10 | *
11 | * 将二进制数据转换成需要的业务逻辑对象
12 | * @author zhaohui
13 | *
14 | */
15 | public abstract class Decoder extends OneToOneDecoder {
16 |
17 | @Override
18 | protected Object decode(ChannelHandlerContext ctx, Channel channel,
19 | Object msg) throws Exception {
20 | if (!(msg instanceof Message)) {
21 | return msg;
22 | }
23 | Message message = (Message) msg;
24 | Object logicObj = transformData(message.getData());
25 | message.setData(logicObj);
26 | return message;
27 | }
28 |
29 | /**
30 | * 将二进制数据转换成逻辑对象
31 | *
32 | * @param msg
33 | * 请求对象
34 | * @throws Exception
35 | */
36 | protected abstract Object transformData(Object msg) throws Exception;
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/gserver-core/src/main/java/org/gserver/core/net/codec/Encoder.java:
--------------------------------------------------------------------------------
1 | package org.gserver.core.net.codec;
2 |
3 | import org.gserver.core.net.Message;
4 | import org.jboss.netty.channel.Channel;
5 | import org.jboss.netty.channel.ChannelHandlerContext;
6 | import org.jboss.netty.handler.codec.oneone.OneToOneEncoder;
7 |
8 | /**
9 | * 编码器
10 | * @author zhaohui
11 | *
12 | */
13 | public abstract class Encoder extends OneToOneEncoder {
14 |
15 | @Override
16 | protected Object encode(ChannelHandlerContext ctx, Channel channel,
17 | Object msg) throws Exception {
18 | Message message = (Message) msg;
19 | Object buffer = transformData(message.getData());
20 | message.setData(buffer);
21 | return msg;
22 | }
23 |
24 | /**
25 | * 将逻辑对象转换成二进制数据
26 | * @param msg
27 | * @throws Exception
28 | */
29 | protected abstract Object transformData(Object msg) throws Exception;
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/gserver-core/src/main/java/org/gserver/core/net/codec/HeaderDecoder.java:
--------------------------------------------------------------------------------
1 | package org.gserver.core.net.codec;
2 |
3 | import org.gserver.core.net.Header;
4 | import org.gserver.core.net.Message;
5 | import org.jboss.netty.buffer.ChannelBuffer;
6 | import org.jboss.netty.channel.Channel;
7 | import org.jboss.netty.channel.ChannelHandlerContext;
8 | import org.jboss.netty.handler.codec.frame.CorruptedFrameException;
9 | import org.jboss.netty.handler.codec.frame.FrameDecoder;
10 |
11 | /**
12 | * 对包的头文件进行解码
13 | * header协议格式:
14 | * {
15 | * tag byte 协议头标志位
16 | * encode byte
17 | * encrypt byte
18 | * extend1 byte
19 | * extend2 byte
20 | * sessionid int
21 | * length int
22 | * commandId int
23 | * }
24 | *
25 | * @author zhaohui
26 | *
27 | */
28 | public class HeaderDecoder extends FrameDecoder {
29 |
30 | /**头文件长度**/
31 | public static final int HEAD_LENGHT = 17;
32 | /** 包头标志 **/
33 | public static final byte PACKAGE_TAG = 0x01;
34 |
35 | @Override
36 | protected Object decode(ChannelHandlerContext ctx, Channel channel,
37 | ChannelBuffer buffer) throws Exception {
38 | if (buffer.readableBytes() < HEAD_LENGHT) {
39 | return null;
40 | }
41 | buffer.markReaderIndex();
42 | byte tag = buffer.readByte();
43 | if (tag != PACKAGE_TAG) {
44 | throw new CorruptedFrameException("非法协议包");
45 | }
46 | byte encode = buffer.readByte();
47 | byte encrypt = buffer.readByte();
48 | byte extend1 = buffer.readByte();
49 | byte extend2 = buffer.readByte();
50 | int sessionid = buffer.readInt();
51 | int length = buffer.readInt();
52 | int commandId = buffer.readInt();
53 |
54 | if (buffer.readableBytes() < length) {
55 | buffer.resetReaderIndex();
56 | return null;
57 | }
58 |
59 | Header header = new Header(encode, encrypt, extend1, extend2,
60 | sessionid, length, commandId);
61 | Message message = new Message(header, buffer.readBytes(length).array());
62 |
63 | return message;
64 | }
65 |
66 | }
67 |
--------------------------------------------------------------------------------
/gserver-core/src/main/java/org/gserver/core/net/codec/HeaderEncoder.java:
--------------------------------------------------------------------------------
1 | package org.gserver.core.net.codec;
2 |
3 | import org.gserver.core.net.Header;
4 | import org.gserver.core.net.Message;
5 | import org.jboss.netty.buffer.ChannelBuffer;
6 | import org.jboss.netty.buffer.ChannelBuffers;
7 | import org.jboss.netty.channel.Channel;
8 | import org.jboss.netty.channel.ChannelHandlerContext;
9 | import org.jboss.netty.handler.codec.oneone.OneToOneEncoder;
10 |
11 | /**
12 | * 对包的头文件进行编码
13 | *
14 | * @author zhaohui
15 | *
16 | */
17 | public class HeaderEncoder extends OneToOneEncoder {
18 |
19 | @Override
20 | protected Object encode(ChannelHandlerContext ctx, Channel channel,
21 | Object msg) throws Exception {
22 | if (!(msg instanceof Message)) {
23 | return msg;
24 | }
25 |
26 | Message message = (Message) msg;
27 | byte[] buffer = (byte[]) message.getData();
28 | Header header = message.getHeader();
29 |
30 | ChannelBuffer allBuffer = ChannelBuffers.dynamicBuffer();
31 | allBuffer.writeByte(HeaderDecoder.PACKAGE_TAG);
32 | allBuffer.writeByte(header.getEncode());
33 | allBuffer.writeByte(header.getEncrypt());
34 | allBuffer.writeByte(header.getExtend1());
35 | allBuffer.writeByte(header.getExtend2());
36 | allBuffer.writeInt(header.getSessionId());
37 | allBuffer.writeInt(buffer.length);
38 | allBuffer.writeInt(header.getCommandId());
39 | allBuffer.writeBytes(buffer);
40 | return allBuffer;
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/gserver-core/src/main/java/org/gserver/core/net/codec/decoder/ProtobufDecoder.java:
--------------------------------------------------------------------------------
1 | package org.gserver.core.net.codec.decoder;
2 |
3 | import org.gserver.core.net.codec.Decoder;
4 | import org.jboss.netty.buffer.ChannelBuffer;
5 | import org.jboss.netty.buffer.ChannelBufferInputStream;
6 |
7 | import com.google.protobuf.ExtensionRegistry;
8 | import com.google.protobuf.MessageLite;
9 |
10 | /**
11 | * pb格式数据转换成业务逻辑对象
12 | *
13 | * @author zhaohui
14 | *
15 | */
16 | public class ProtobufDecoder extends Decoder {
17 |
18 | private final MessageLite prototype;
19 | private final ExtensionRegistry extensionRegistry;
20 |
21 | public ProtobufDecoder(MessageLite prototype) {
22 | this(prototype, null);
23 | }
24 |
25 | public ProtobufDecoder(MessageLite prototype,
26 | ExtensionRegistry extensionRegistry) {
27 | if (prototype == null) {
28 | throw new NullPointerException("prototype");
29 | }
30 | this.prototype = prototype.getDefaultInstanceForType();
31 | this.extensionRegistry = extensionRegistry;
32 | }
33 |
34 | @Override
35 | protected Object transformData(Object msg) throws Exception {
36 | if (!(msg instanceof ChannelBuffer)) {
37 | return msg;
38 | }
39 |
40 | ChannelBuffer buf = (ChannelBuffer) msg;
41 | if (buf.hasArray()) {
42 | final int offset = buf.readerIndex();
43 | if (extensionRegistry == null) {
44 | return prototype
45 | .newBuilderForType()
46 | .mergeFrom(buf.array(), buf.arrayOffset() + offset,
47 | buf.readableBytes()).build();
48 | } else {
49 | return prototype
50 | .newBuilderForType()
51 | .mergeFrom(buf.array(), buf.arrayOffset() + offset,
52 | buf.readableBytes(), extensionRegistry).build();
53 | }
54 | } else {
55 | if (extensionRegistry == null) {
56 | return prototype
57 | .newBuilderForType()
58 | .mergeFrom(
59 | new ChannelBufferInputStream(
60 | (ChannelBuffer) msg)).build();
61 | } else {
62 | return prototype
63 | .newBuilderForType()
64 | .mergeFrom(
65 | new ChannelBufferInputStream(
66 | (ChannelBuffer) msg), extensionRegistry)
67 | .build();
68 | }
69 | }
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/gserver-core/src/main/java/org/gserver/core/net/codec/encoder/ProtobufEncoder.java:
--------------------------------------------------------------------------------
1 | package org.gserver.core.net.codec.encoder;
2 |
3 | import static org.jboss.netty.buffer.ChannelBuffers.wrappedBuffer;
4 |
5 | import org.gserver.core.net.codec.Encoder;
6 |
7 | import com.google.protobuf.MessageLite;
8 |
9 |
10 | /**
11 | * 业务逻辑对象转换成二进制数据
12 | * @author zhaohui
13 | *
14 | */
15 | public class ProtobufEncoder extends Encoder {
16 |
17 | @Override
18 | protected Object transformData(Object msg) throws Exception {
19 | if (msg instanceof MessageLite) {
20 | return wrappedBuffer(((MessageLite) msg).toByteArray());
21 | }
22 | if (msg instanceof MessageLite.Builder) {
23 | return wrappedBuffer(((MessageLite.Builder) msg).build()
24 | .toByteArray());
25 | }
26 | return msg;
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/gserver-core/src/main/java/org/gserver/core/server/AbstractServer.java:
--------------------------------------------------------------------------------
1 | package org.gserver.core.server;
2 |
3 | import org.apache.log4j.Logger;
4 | import org.gserver.core.server.config.Config;
5 |
6 | public abstract class AbstractServer implements Runnable {
7 | private int server_id;
8 | private String server_name;
9 | protected Config config;
10 |
11 | protected AbstractServer(Config serverConfig) {
12 | this.config = serverConfig;
13 | if (this.config != null) {
14 | init();
15 | }
16 | }
17 |
18 | protected void init() {
19 | this.server_name = this.config.getName();
20 | this.server_id = this.config.getId();
21 | }
22 |
23 | @Override
24 | public void run() {
25 | Runtime.getRuntime().addShutdownHook(
26 | new Thread(new CloseByExit(this.server_name)));
27 | }
28 |
29 | public String getServerName() {
30 | return server_name;
31 | }
32 |
33 | public int getServerId() {
34 | return server_id;
35 | }
36 |
37 | protected abstract void stop();
38 |
39 | /**
40 | * 服务器关闭的钩子
41 | *
42 | * @author zhaohui
43 | *
44 | */
45 | private class CloseByExit implements Runnable {
46 | private Logger log = Logger.getLogger(CloseByExit.class);
47 | private String server_name;
48 |
49 | public CloseByExit(String server_name) {
50 | this.server_name = server_name;
51 | }
52 |
53 | @Override
54 | public void run() {
55 | AbstractServer.this.stop();
56 | log.info(this.server_name + " Stop!");
57 | }
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/gserver-core/src/main/java/org/gserver/core/server/config/ClientServerConfig.java:
--------------------------------------------------------------------------------
1 | package org.gserver.core.server.config;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | /**
7 | * 客戶端server
8 | *
9 | * 逻辑服务器经常去连的服务器:gateServer,worldServer,publicServer 此时逻辑服务器被称为clientServer
10 | *
11 | * @author zhaohui
12 | *
13 | */
14 | public class ClientServerConfig extends Config {
15 |
16 | private List connectServers = new ArrayList();
17 |
18 | public List getConnectServers() {
19 | return connectServers;
20 | }
21 |
22 | public void setConnectServers(List connectServers) {
23 | this.connectServers = connectServers;
24 | }
25 |
26 | }
27 |
--------------------------------------------------------------------------------
/gserver-core/src/main/java/org/gserver/core/server/config/Config.java:
--------------------------------------------------------------------------------
1 | package org.gserver.core.server.config;
2 |
3 | /**
4 | * 服务器配置
5 | *
6 | * @author zhaohui
7 | *
8 | */
9 | public abstract class Config {
10 | private String name;
11 | private int id;
12 |
13 | public String getName() {
14 | return this.name;
15 | }
16 |
17 | public void setName(String name) {
18 | this.name = name;
19 | }
20 |
21 | public int getId() {
22 | return this.id;
23 | }
24 |
25 | public void setId(int id) {
26 | this.id = id;
27 | }
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/gserver-core/src/main/java/org/gserver/core/server/config/ServerConfig.java:
--------------------------------------------------------------------------------
1 | package org.gserver.core.server.config;
2 |
3 | public class ServerConfig extends Config {
4 |
5 | private int port;
6 |
7 | public int getPort() {
8 | return this.port;
9 | }
10 |
11 | public void setPort(int port) {
12 | this.port = port;
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/gserver-core/src/main/java/org/gserver/core/server/config/ServerInfo.java:
--------------------------------------------------------------------------------
1 | package org.gserver.core.server.config;
2 |
3 | public class ServerInfo {
4 | /** 唯一编号 **/
5 | private int id;
6 | /** ip **/
7 | private String ip;
8 | /** 端口 **/
9 | private int port;
10 | /** 建立连接的数量 **/
11 | private int connectNum;
12 |
13 | public int getId() {
14 | return this.id;
15 | }
16 |
17 | public void setId(int id) {
18 | this.id = id;
19 | }
20 |
21 | public String getIp() {
22 | return this.ip;
23 | }
24 |
25 | public void setIp(String ip) {
26 | this.ip = ip;
27 | }
28 |
29 | public int getPort() {
30 | return this.port;
31 | }
32 |
33 | public void setPort(int port) {
34 | this.port = port;
35 | }
36 |
37 | public int getConnectNum() {
38 | return connectNum;
39 | }
40 |
41 | public void setConnectNum(int connectNum) {
42 | this.connectNum = connectNum;
43 | }
44 |
45 | }
46 |
--------------------------------------------------------------------------------
/gserver-core/src/main/java/org/gserver/core/server/impl/ClientServer.java:
--------------------------------------------------------------------------------
1 | package org.gserver.core.server.impl;
2 |
3 | import java.net.InetSocketAddress;
4 | import java.util.ArrayList;
5 | import java.util.HashMap;
6 | import java.util.List;
7 | import java.util.Map;
8 | import java.util.Random;
9 | import java.util.Set;
10 | import java.util.concurrent.CountDownLatch;
11 | import java.util.concurrent.Executors;
12 | import java.util.concurrent.TimeUnit;
13 |
14 | import org.apache.log4j.Logger;
15 | import org.gserver.core.net.Message;
16 | import org.gserver.core.server.AbstractServer;
17 | import org.gserver.core.server.config.ClientServerConfig;
18 | import org.gserver.core.server.config.ServerInfo;
19 | import org.gserver.core.server.loader.ClientServerConfigXmlLoader;
20 | import org.jboss.netty.bootstrap.ClientBootstrap;
21 | import org.jboss.netty.channel.Channel;
22 | import org.jboss.netty.channel.ChannelFuture;
23 | import org.jboss.netty.channel.ChannelFutureListener;
24 | import org.jboss.netty.channel.ChannelPipelineFactory;
25 | import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory;
26 |
27 | /**
28 | * 客户端服务器经常去连其他服务器,比如逻辑服务器连接网关服务器
29 | *
30 | * @author zhaohui
31 | *
32 | */
33 | public abstract class ClientServer extends AbstractServer {
34 |
35 | private Logger log = Logger.getLogger(ClientServer.class);
36 |
37 | protected ClientBootstrap bootstrap = null;
38 | protected Map> connectSessions = new HashMap>();
39 | protected List channelList = new ArrayList();
40 |
41 | protected ClientServer(String serverConfig) {
42 | super(new ClientServerConfigXmlLoader().load(serverConfig));
43 | }
44 |
45 | @Override
46 | public void run() {
47 | try {
48 | super.run();
49 | createBootStrap();
50 | ClientServerConfig config = (ClientServerConfig) this.config;
51 | if (config != null) {
52 | List connectServers = config.getConnectServers();
53 | if (connectServers != null) {
54 | for (ServerInfo serverInfo : connectServers) {
55 | initConnect(serverInfo);
56 | }
57 | }
58 |
59 | Set keySet = connectSessions.keySet();
60 | for (int key : keySet) {
61 | channelList.addAll(connectSessions.get(key));
62 | }
63 | }
64 | } catch (Exception e) {
65 | log.error(e);
66 | }
67 |
68 | }
69 |
70 | private void createBootStrap() {
71 | bootstrap = new ClientBootstrap(new NioClientSocketChannelFactory(
72 | Executors.newCachedThreadPool(),
73 | Executors.newCachedThreadPool()));
74 | bootstrap.setPipelineFactory(createPipelineFactory());
75 | }
76 |
77 | protected abstract ChannelPipelineFactory createPipelineFactory();
78 |
79 | /**
80 | * 初始化clientServer和其他服务器建立连接
81 | *
82 | * @param serverInfo
83 | * @throws InterruptedException
84 | */
85 | private void initConnect(ServerInfo serverInfo) throws InterruptedException {
86 | int connected = 0;
87 | while (connected < serverInfo.getConnectNum()) {
88 | ChannelFuture fapp = bootstrap.connect(new InetSocketAddress(
89 | serverInfo.getIp(), serverInfo.getPort()));
90 | Channel channel = fapp.getChannel();
91 | CountDownLatch countLatch = new CountDownLatch(1);
92 | fapp.addListener(new ChannelListener(countLatch));
93 | if (!channel.isConnected()) {
94 | countLatch.await(2000, TimeUnit.MILLISECONDS);
95 | }
96 |
97 | if (!channel.isConnected()) {
98 | log.info("not connect ip:" + serverInfo.getIp() + ",port:"
99 | + serverInfo.getPort());
100 | try {
101 | fapp.cancel();
102 | Thread.sleep(5000L);
103 | } catch (Exception e) {
104 | this.log.error(e, e);
105 | }
106 | } else {
107 | log.info("connect ip:" + serverInfo.getIp() + ",port:"
108 | + serverInfo.getPort());
109 | add(channel, serverInfo.getId());
110 | connected++;
111 | }
112 | }
113 | }
114 |
115 | /**
116 | * 添加channel
117 | *
118 | * @param channel
119 | * @param id
120 | */
121 | public void add(Channel channel, int id) {
122 | synchronized (this.connectSessions) {
123 | List sessions = this.connectSessions.get(Integer
124 | .valueOf(id));
125 | if (sessions == null) {
126 | sessions = new ArrayList();
127 | this.connectSessions.put(Integer.valueOf(id), sessions);
128 | }
129 | sessions.add(channel);
130 | }
131 | }
132 |
133 | public List getChannelList(int serverId) {
134 | return connectSessions.get(serverId);
135 | }
136 |
137 | private Channel getChannel() {
138 | return channelList.get(new Random().nextInt(channelList.size() - 1));
139 | }
140 |
141 | public void write(Message message) {
142 | Channel channel = getChannel();
143 | channel.write(message);
144 | }
145 |
146 | }
147 |
148 | class ChannelListener implements ChannelFutureListener {
149 |
150 | private CountDownLatch countlatch;
151 |
152 | public ChannelListener(CountDownLatch countlatch) {
153 | this.countlatch = countlatch;
154 | }
155 |
156 | @Override
157 | public void operationComplete(ChannelFuture future) throws Exception {
158 | if (future.getChannel().isConnected()) {
159 | countlatch.countDown();
160 | }
161 | }
162 |
163 | }
164 |
--------------------------------------------------------------------------------
/gserver-core/src/main/java/org/gserver/core/server/impl/Server.java:
--------------------------------------------------------------------------------
1 | package org.gserver.core.server.impl;
2 |
3 | import java.net.InetSocketAddress;
4 |
5 | import org.apache.log4j.Logger;
6 | import org.gserver.core.server.AbstractServer;
7 | import org.gserver.core.server.config.ServerConfig;
8 | import org.gserver.core.server.loader.ServerConfigXmlLoader;
9 | import org.jboss.netty.bootstrap.ServerBootstrap;
10 | import org.jboss.netty.channel.ChannelPipelineFactory;
11 | import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
12 |
13 | /**
14 | * 服务器
15 | *
16 | * @author zhaohui
17 | *
18 | */
19 | public abstract class Server extends AbstractServer {
20 | private Logger log = Logger.getLogger(Server.class);
21 |
22 | protected ServerBootstrap bootstrap;
23 | private int port;
24 |
25 | protected Server(String serverConfig) {
26 | super(new ServerConfigXmlLoader().load(serverConfig));
27 | port = ((ServerConfig) config).getPort();
28 | }
29 |
30 | @Override
31 | public void run() {
32 | super.run();
33 | bootstrap = new ServerBootstrap(new NioServerSocketChannelFactory());
34 | bootstrap.setPipelineFactory(createPipelineFactory());
35 | bootstrap.bind(new InetSocketAddress(port));
36 | log.info("Server " + getServerName() + " Start At Port " + port);
37 | }
38 |
39 | protected abstract ChannelPipelineFactory createPipelineFactory();
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/gserver-core/src/main/java/org/gserver/core/server/loader/ClientServerConfigXmlLoader.java:
--------------------------------------------------------------------------------
1 | package org.gserver.core.server.loader;
2 |
3 | import java.io.FileInputStream;
4 | import java.io.IOException;
5 | import java.io.InputStream;
6 |
7 | import javax.xml.parsers.DocumentBuilder;
8 | import javax.xml.parsers.DocumentBuilderFactory;
9 |
10 | import org.apache.log4j.Logger;
11 | import org.gserver.core.server.config.ClientServerConfig;
12 | import org.gserver.core.server.config.ServerInfo;
13 | import org.w3c.dom.Document;
14 | import org.w3c.dom.Node;
15 | import org.w3c.dom.NodeList;
16 |
17 | /**
18 | * 加载clientServer配置xml
19 | *
20 | * @author zhaohui
21 | *
22 | */
23 | public class ClientServerConfigXmlLoader {
24 |
25 | private Logger log = Logger.getLogger(ClientServerConfigXmlLoader.class);
26 |
27 | public ClientServerConfig load(String file) {
28 | InputStream in = null;
29 | try {
30 | DocumentBuilder builder = DocumentBuilderFactory.newInstance()
31 | .newDocumentBuilder();
32 | in = new FileInputStream(file);
33 | Document doc = builder.parse(in);
34 | NodeList list = doc.getElementsByTagName("server");
35 |
36 | ClientServerConfig config = new ClientServerConfig();
37 | if (list.getLength() > 0) {
38 | Node node = list.item(0);
39 | NodeList childs = node.getChildNodes();
40 |
41 | for (int j = 0; j < childs.getLength(); j++) {
42 | if ("server-name".equals(childs.item(j).getNodeName())) {
43 | config.setName(childs.item(j).getTextContent());
44 | } else if ("server-id".equals(childs.item(j).getNodeName())) {
45 | config.setId(Integer.parseInt(childs.item(j)
46 | .getTextContent()));
47 | } else if ("connect-servers".equals(childs.item(j)
48 | .getNodeName())) {
49 | NodeList servers = childs.item(j).getChildNodes();
50 | for (int k = 0; k < servers.getLength(); k++)
51 | if ("connect-server".equals(servers.item(k)
52 | .getNodeName())) {
53 | Node line = servers.item(k);
54 | ServerInfo info = new ServerInfo();
55 | NodeList attrs = line.getChildNodes();
56 | for (int l = 0; l < attrs.getLength(); l++) {
57 | String nodeName = attrs.item(l)
58 | .getNodeName();
59 | String textContent = attrs.item(l)
60 | .getTextContent();
61 | if ("server-id".equals(nodeName)) {
62 | info.setId(Integer
63 | .parseInt(textContent));
64 | } else if ("server-ip".equals(nodeName)) {
65 | info.setIp(textContent);
66 | } else if ("server-port".equals(nodeName)) {
67 | info.setPort(Integer
68 | .parseInt(textContent));
69 | } else if ("connect-num".equals(nodeName)) {
70 | info.setConnectNum(Integer
71 | .parseInt(textContent));
72 | }
73 | }
74 |
75 | config.getConnectServers().add(info);
76 | }
77 | }
78 | }
79 | }
80 |
81 | in.close();
82 |
83 | log.info("load server config !");
84 | return config;
85 | } catch (Exception e) {
86 | this.log.error(e, e);
87 | } finally {
88 | if (in != null) {
89 | try {
90 | in.close();
91 | } catch (IOException e) {
92 | }
93 | }
94 | }
95 | return null;
96 | }
97 | }
98 |
--------------------------------------------------------------------------------
/gserver-core/src/main/java/org/gserver/core/server/loader/ServerConfigXmlLoader.java:
--------------------------------------------------------------------------------
1 | package org.gserver.core.server.loader;
2 |
3 | import java.io.FileInputStream;
4 | import java.io.IOException;
5 | import java.io.InputStream;
6 |
7 | import javax.xml.parsers.DocumentBuilder;
8 | import javax.xml.parsers.DocumentBuilderFactory;
9 |
10 | import org.apache.log4j.Logger;
11 | import org.gserver.core.server.config.ServerConfig;
12 | import org.w3c.dom.Document;
13 | import org.w3c.dom.Node;
14 | import org.w3c.dom.NodeList;
15 |
16 | /**
17 | * 加载Server配置xml
18 | *
19 | * @author zhaohui
20 | *
21 | */
22 | public class ServerConfigXmlLoader {
23 | private Logger log = Logger.getLogger(ServerConfigXmlLoader.class);
24 |
25 | public ServerConfig load(String file) {
26 | InputStream in = null;
27 | try {
28 | DocumentBuilder builder = DocumentBuilderFactory.newInstance()
29 | .newDocumentBuilder();
30 | in = new FileInputStream(file);
31 | Document doc = builder.parse(in);
32 | NodeList list = doc.getElementsByTagName("server");
33 |
34 | ServerConfig config = new ServerConfig();
35 | if (list.getLength() > 0) {
36 | Node node = list.item(0);
37 | NodeList childs = node.getChildNodes();
38 |
39 | for (int j = 0; j < childs.getLength(); j++) {
40 | if ("server-name".equals(childs.item(j).getNodeName()))
41 | config.setName(childs.item(j).getTextContent());
42 | else if ("server-id".equals(childs.item(j).getNodeName()))
43 | config.setId(Integer.parseInt(childs.item(j)
44 | .getTextContent()));
45 | else if ("server-port".equals(childs.item(j).getNodeName())) {
46 | config.setPort(Integer.parseInt(childs.item(j)
47 | .getTextContent()));
48 | }
49 | }
50 | }
51 |
52 | log.info("load server config !");
53 | return config;
54 | } catch (Exception e) {
55 | this.log.error(e);
56 | } finally {
57 | if (in != null) {
58 | try {
59 | in.close();
60 | } catch (IOException e) {
61 | }
62 | }
63 | }
64 | return null;
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/gserver-core/src/main/java/org/gserver/core/threadPool/AbstractWork.java:
--------------------------------------------------------------------------------
1 | package org.gserver.core.threadPool;
2 |
3 | import org.gserver.core.threadPool.struts.TasksQueue;
4 |
5 | public abstract class AbstractWork implements Runnable {
6 |
7 | private TasksQueue tasksQueue;
8 |
9 | public TasksQueue getTasksQueue() {
10 | return tasksQueue;
11 | }
12 |
13 | public void setTasksQueue(TasksQueue tasksQueue) {
14 | this.tasksQueue = tasksQueue;
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/gserver-core/src/main/java/org/gserver/core/threadPool/executor/NonOrderedQueuePoolExecutor.java:
--------------------------------------------------------------------------------
1 | package org.gserver.core.threadPool.executor;
2 |
3 | import java.util.concurrent.LinkedBlockingQueue;
4 | import java.util.concurrent.ThreadPoolExecutor;
5 | import java.util.concurrent.TimeUnit;
6 |
7 | import org.gserver.core.threadPool.AbstractWork;
8 |
9 | /**
10 | * 无序队列线程池
11 | * @author zhaohui
12 | *
13 | */
14 | public class NonOrderedQueuePoolExecutor extends ThreadPoolExecutor {
15 |
16 | public NonOrderedQueuePoolExecutor(int corePoolSize) {
17 | super(corePoolSize, corePoolSize, 30, TimeUnit.SECONDS,
18 | new LinkedBlockingQueue());
19 | }
20 |
21 | public void execute(AbstractWork work) {
22 | execute(work);
23 | }
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/gserver-core/src/main/java/org/gserver/core/threadPool/executor/OrderedQueuePoolExecutor.java:
--------------------------------------------------------------------------------
1 | package org.gserver.core.threadPool.executor;
2 |
3 | import java.util.concurrent.LinkedBlockingQueue;
4 | import java.util.concurrent.ThreadPoolExecutor;
5 | import java.util.concurrent.TimeUnit;
6 |
7 | import org.apache.log4j.Logger;
8 | import org.gserver.core.threadPool.AbstractWork;
9 | import org.gserver.core.threadPool.struts.OrderedQueuePool;
10 | import org.gserver.core.threadPool.struts.TasksQueue;
11 |
12 | /**
13 | * 有序的队列线程池
14 | * @author zhaohui
15 | *
16 | */
17 | public class OrderedQueuePoolExecutor extends ThreadPoolExecutor {
18 |
19 | protected static Logger log = Logger
20 | .getLogger(OrderedQueuePoolExecutor.class);
21 |
22 | private OrderedQueuePool pool = new OrderedQueuePool();
23 |
24 | private String name;
25 | private int maxQueueSize;
26 |
27 | public OrderedQueuePoolExecutor(String name, int corePoolSize,
28 | int maxQueueSize) {
29 | super(corePoolSize, 2 * corePoolSize, 30, TimeUnit.SECONDS,
30 | new LinkedBlockingQueue());
31 | this.name = name;
32 | this.maxQueueSize = maxQueueSize;
33 | }
34 |
35 | public OrderedQueuePoolExecutor(int corePoolSize) {
36 | this("queue-pool", corePoolSize, 10000);
37 | }
38 |
39 | /**
40 | * 增加执行任务
41 | * @param key
42 | * @param value
43 | * @return
44 | */
45 | public boolean addTask(Integer key, AbstractWork task) {
46 | TasksQueue queue = pool.getTasksQueue(key);
47 | boolean run = false;
48 | boolean result = false;
49 | synchronized (queue) {
50 | if (maxQueueSize > 0) {
51 | if (queue.size() > maxQueueSize) {
52 | log.error("队列" + name + "(" + key + ")" + "抛弃指令!");
53 | queue.clear();
54 | }
55 | }
56 | result = queue.add(task);
57 | if (result) {
58 | task.setTasksQueue(queue);
59 | {
60 | if (queue.isProcessingCompleted()) {
61 | queue.setProcessingCompleted(false);
62 | run = true;
63 | }
64 | }
65 | } else {
66 | log.error("队列添加任务失败");
67 | }
68 | }
69 | if (run) {
70 | execute(queue.poll());
71 | }
72 | return result;
73 | }
74 |
75 | @Override
76 | protected void afterExecute(Runnable r, Throwable t) {
77 | super.afterExecute(r, t);
78 |
79 | AbstractWork work = (AbstractWork) r;
80 | TasksQueue queue = work.getTasksQueue();
81 | if (queue != null) {
82 | AbstractWork afterWork = null;
83 | synchronized (queue) {
84 | afterWork = queue.poll();
85 | if (afterWork == null) {
86 | queue.setProcessingCompleted(true);
87 | }
88 | }
89 | if (afterWork != null) {
90 | execute(afterWork);
91 | }
92 | } else {
93 | log.error("执行队列为空");
94 | }
95 | }
96 |
97 | }
98 |
--------------------------------------------------------------------------------
/gserver-core/src/main/java/org/gserver/core/threadPool/struts/OrderedQueuePool.java:
--------------------------------------------------------------------------------
1 | package org.gserver.core.threadPool.struts;
2 |
3 | import java.util.concurrent.ConcurrentHashMap;
4 |
5 | public class OrderedQueuePool {
6 |
7 | ConcurrentHashMap> map = new ConcurrentHashMap>();
8 |
9 | /**
10 | * 获得任务队列
11 | * @param key
12 | * @return
13 | */
14 | public TasksQueue getTasksQueue(K key) {
15 | synchronized (map) {
16 | TasksQueue queue = map.get(key);
17 |
18 | if (queue == null) {
19 | queue = new TasksQueue();
20 | map.put(key, queue);
21 | }
22 |
23 | return queue;
24 | }
25 | }
26 |
27 | /**
28 | * 获得全部任务队列
29 | * @param key
30 | * @return
31 | */
32 | public ConcurrentHashMap> getTasksQueues() {
33 | return map;
34 | }
35 |
36 | /**
37 | * 移除任务队列
38 | * @param key
39 | * @return
40 | */
41 | public void removeTasksQueue(K key) {
42 | map.remove(key);
43 | }
44 | }
--------------------------------------------------------------------------------
/gserver-core/src/main/java/org/gserver/core/threadPool/struts/TasksQueue.java:
--------------------------------------------------------------------------------
1 | package org.gserver.core.threadPool.struts;
2 |
3 | import java.util.ArrayDeque;
4 | import java.util.concurrent.locks.Lock;
5 | import java.util.concurrent.locks.ReentrantLock;
6 |
7 | public class TasksQueue {
8 |
9 | private Lock lock = new ReentrantLock();
10 | /**
11 | * 命令队列
12 | */
13 | private final ArrayDeque tasksQueue = new ArrayDeque();
14 |
15 | private boolean processingCompleted = true;
16 |
17 | /**
18 | * 下一执行命令
19 | *
20 | * @return
21 | */
22 | public V poll() {
23 | try {
24 | lock.lock();
25 | return tasksQueue.poll();
26 | } finally {
27 | lock.unlock();
28 | }
29 | }
30 |
31 | /**
32 | * 增加执行指令
33 | *
34 | * @param command
35 | * @return
36 | */
37 | public boolean add(V value) {
38 | try {
39 | lock.lock();
40 | return tasksQueue.add(value);
41 | } finally {
42 | lock.unlock();
43 | }
44 | }
45 |
46 | /**
47 | * 清理
48 | */
49 | public void clear() {
50 | try {
51 | lock.lock();
52 | tasksQueue.clear();
53 | } finally {
54 | lock.unlock();
55 | }
56 | }
57 |
58 | /**
59 | * 获取指令数量
60 | *
61 | * @return
62 | */
63 | public int size() {
64 | return tasksQueue.size();
65 | }
66 |
67 | public boolean isProcessingCompleted() {
68 | return processingCompleted;
69 | }
70 |
71 | public void setProcessingCompleted(boolean processingCompleted) {
72 | this.processingCompleted = processingCompleted;
73 | }
74 |
75 | }
--------------------------------------------------------------------------------
/gserver-core/src/main/java/org/gserver/core/util/ChannelPoolManager.java:
--------------------------------------------------------------------------------
1 | package org.gserver.core.util;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 | import java.util.Random;
6 |
7 | import org.jboss.netty.channel.Channel;
8 |
9 | /**
10 | * 内部服务器建立的连接池
11 | *
12 | * @author zhaohui
13 | *
14 | */
15 | public class ChannelPoolManager {
16 |
17 | private List channelPool = new ArrayList();
18 |
19 | private static ChannelPoolManager poolManager = new ChannelPoolManager();
20 |
21 | public static ChannelPoolManager getInstance() {
22 | return poolManager;
23 | }
24 |
25 | public void addChannel(Channel channel) {
26 | channelPool.add(channel);
27 | }
28 |
29 | public void removeChannel(Channel channel) {
30 | channelPool.remove(channel);
31 | }
32 |
33 | /**
34 | * 随机获取一个连接
35 | *
36 | * @return
37 | */
38 | public Channel getChannel() {
39 | Channel channel = channelPool.get(new Random().nextInt(channelPool
40 | .size()));
41 | if (channel == null || channel.isConnected() == false) {
42 | throw new RuntimeException("no channel is connected channel:"
43 | + channel);
44 | }
45 | return channel;
46 | }
47 |
48 | }
49 |
--------------------------------------------------------------------------------
/gserver-core/src/main/java/org/gserver/core/util/SessionChannelManager.java:
--------------------------------------------------------------------------------
1 | package org.gserver.core.util;
2 |
3 | import java.util.Map;
4 | import java.util.concurrent.ConcurrentHashMap;
5 | import org.jboss.netty.channel.Channel;
6 |
7 | /**
8 | * session和channel关系管理器
9 | *
10 | * @author zhaohui
11 | *
12 | */
13 | public class SessionChannelManager {
14 |
15 | public static SessionChannelManager instance = new SessionChannelManager();
16 |
17 | private Map sessionChannelMap = new ConcurrentHashMap();
18 | private Map channelSessionMap = new ConcurrentHashMap();
19 |
20 | public static SessionChannelManager getInstance() {
21 | return instance;
22 | }
23 |
24 | public void addChannle(Integer sessionId, Channel channel) {
25 | synchronized (this) {
26 | sessionChannelMap.put(sessionId, channel);
27 | channelSessionMap.put(channel, sessionId);
28 | }
29 | }
30 |
31 | /**
32 | * 获取指定session的channel
33 | *
34 | * @param sessionId
35 | * @return
36 | */
37 | public Channel getChannel(Integer sessionId) {
38 | return sessionChannelMap.get(sessionId);
39 | }
40 |
41 | /**
42 | * 获取指定channel的sessionId
43 | *
44 | * @param channel
45 | * @return
46 | */
47 | public Integer getSessionId(Channel channel) {
48 | return channelSessionMap.get(channel);
49 | }
50 |
51 | /**
52 | * 移除指定session和channel
53 | *
54 | * @param sessionId
55 | */
56 | public void removeChannel(int sessionId) {
57 | synchronized (this) {
58 | Channel channel = sessionChannelMap.get(sessionId);
59 | if (channel != null) {
60 | channelSessionMap.remove(channel);
61 | }
62 | sessionChannelMap.remove(sessionId);
63 | }
64 | }
65 |
66 | public void removeChannel(Channel channel) {
67 | synchronized (this) {
68 | Integer sessionId = channelSessionMap.get(channel);
69 | if (sessionId != null) {
70 | sessionChannelMap.remove(sessionId);
71 | }
72 | channelSessionMap.remove(channel);
73 | }
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/gserver-core/src/main/java/org/gserver/core/util/SessionUtil.java:
--------------------------------------------------------------------------------
1 | package org.gserver.core.util;
2 |
3 | import java.security.MessageDigest;
4 | import java.security.NoSuchAlgorithmException;
5 | import java.security.SecureRandom;
6 | import java.util.HashMap;
7 | import java.util.Map;
8 | import java.util.Random;
9 |
10 | public class SessionUtil {
11 |
12 | private static final int SESSION_ID_BYTES = 16;
13 |
14 | /**
15 | * 生成sessionId
16 | *
17 | * @return
18 | */
19 | public static synchronized String generateSessionId() {
20 | Random random = new SecureRandom();
21 | byte bytes[] = new byte[SESSION_ID_BYTES];
22 | random.nextBytes(bytes);
23 | bytes = getDigest().digest(bytes);
24 |
25 | StringBuffer result = new StringBuffer();
26 | for (int i = 0; i < bytes.length; i++) {
27 | byte b1 = (byte) ((bytes[i] & 0xf0) >> 4);
28 | byte b2 = (byte) (bytes[i] & 0x0f);
29 | if (b1 < 10) {
30 | result.append((char) ('0' + b1));
31 | } else {
32 | result.append((char) ('A' + (b1 - 10)));
33 | }
34 |
35 | if (b2 < 10) {
36 | result.append((char) ('0' + b2));
37 | } else {
38 | result.append((char) ('A' + (b2 - 10)));
39 | }
40 | }
41 |
42 | return (result.toString());
43 | }
44 |
45 | private static MessageDigest getDigest() {
46 | try {
47 | MessageDigest md = MessageDigest.getInstance("MD5");
48 | return md;
49 | } catch (NoSuchAlgorithmException e) {
50 | e.printStackTrace();
51 | }
52 | return null;
53 | }
54 |
55 | public static void main(String[] args) {
56 | String sid = SessionUtil.generateSessionId();
57 | System.out.println("jsessionid=" + sid);
58 | System.out.println("sid.lengh=" + sid.length());
59 | String s = "CAB541D43210B989EE5696CDC5DEA456";
60 | System.out.println(s.length());
61 | Map v = new HashMap();
62 | for (int i = 0; i < 100000; i++) {
63 | String xx = SessionUtil.generateSessionId();
64 | if (v.containsKey(xx)) {
65 | System.err.println("xxxxxxxxxxxxxxxxxxx");
66 | } else {
67 | v.put(xx, 0);
68 | }
69 | }
70 | }
71 |
72 | }
73 |
--------------------------------------------------------------------------------
/gserver-core/src/main/resources/log4j.properties:
--------------------------------------------------------------------------------
1 | log4j.rootLogger=INFO,fileA,consoleA
2 |
3 | log4j.appender.fileA=org.apache.log4j.DailyRollingFileAppender
4 | log4j.appender.fileA.File=./logs/gameserver.log
5 | log4j.appender.fileA.append=true
6 | log4j.appender.fileA.ImmediateFlush=true
7 | log4j.appender.fileA.layout=org.apache.log4j.PatternLayout
8 | log4j.appender.fileA.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} [%t] %L::: %-5p %C - %m%n
9 |
10 | log4j.appender.consoleA=org.apache.log4j.ConsoleAppender
11 | log4j.appender.consoleA.layout=org.apache.log4j.PatternLayout
12 | log4j.appender.consoleA.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} - %m%n
--------------------------------------------------------------------------------
/gserver-db/.gitignore:
--------------------------------------------------------------------------------
1 | /target
2 | /logs
3 | /.settings
--------------------------------------------------------------------------------
/gserver-db/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | com.gserver
8 | gserver
9 | 0.0.1-SNAPSHOT
10 |
11 | gserver-db
12 | gserver-db
13 | http://maven.apache.org
14 |
15 | UTF-8
16 |
17 |
18 |
19 |
20 | mysql
21 | mysql-connector-java
22 | 5.1.23
23 |
24 |
25 | commons-dbcp
26 | commons-dbcp
27 | 1.4
28 |
29 |
30 | commons-dbutils
31 | commons-dbutils
32 | 1.6
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/gserver-db/src/main/java/org/gserver/db/IMysqlJdbcTemplate.java:
--------------------------------------------------------------------------------
1 | package org.gserver.db;
2 |
3 | import java.util.List;
4 | import java.util.Map;
5 | import java.util.Set;
6 |
7 | public interface IMysqlJdbcTemplate {
8 |
9 | public T queryBean(Class type, long id);
10 |
11 | public List batchQueryBean(Class type, Set ids);
12 |
13 | public int insert(Class type, Map beanMap);
14 |
15 | public int update(Class type, long id, Map updateMap);
16 |
17 | public void delete(Class type, long id);
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/gserver-db/src/main/java/org/gserver/db/MysqlJdbcTemplate.java:
--------------------------------------------------------------------------------
1 | package org.gserver.db;
2 |
3 | import java.util.List;
4 | import java.util.Map;
5 | import java.util.Set;
6 |
7 | import org.gserver.db.accessor.IMysqlAccessor;
8 | import org.gserver.db.accessor.SQLUtil;
9 |
10 | public class MysqlJdbcTemplate implements IMysqlJdbcTemplate {
11 |
12 | private IMysqlAccessor accessor;
13 |
14 | @Override
15 | public T queryBean(Class type, long id) {
16 | return null;
17 | }
18 |
19 | @Override
20 | public List batchQueryBean(Class type, Set ids) {
21 | return null;
22 | }
23 |
24 | @Override
25 | public int insert(Class type, Map beanMap) {
26 | String insertSql = SQLUtil.insert(beanMap, type.getSimpleName());
27 | return accessor.insert(insertSql);
28 | }
29 |
30 | @Override
31 | public int update(Class type, long id, Map updateMap) {
32 | return 0;
33 | }
34 |
35 | @Override
36 | public void delete(Class type, long id) {
37 |
38 | }
39 |
40 | public void setAccessor(IMysqlAccessor accessor) {
41 | this.accessor = accessor;
42 | }
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/gserver-db/src/main/java/org/gserver/db/accessor/AbstractMysqlAccessor.java:
--------------------------------------------------------------------------------
1 | package org.gserver.db.accessor;
2 |
3 | import java.sql.Connection;
4 | import java.sql.SQLException;
5 |
6 | public abstract class AbstractMysqlAccessor {
7 |
8 | private JdbcFactory jdbcFactory;
9 |
10 | protected T execute(SimpleJdbcCallback action) {
11 | return execute(action, true);
12 | }
13 |
14 | private T execute(SimpleJdbcCallback action, boolean flag) {
15 | Connection conn = null;
16 | try {
17 | conn = jdbcFactory.getConnection();
18 | T result = action.doIt(conn);
19 | conn.close();
20 | return result;
21 | } catch (Exception e) {
22 | throw new RuntimeException(e.getMessage(), e);
23 | } finally {
24 | try {
25 | if (conn != null)
26 | conn.close();
27 | } catch (SQLException e) {
28 | e.printStackTrace();
29 | }
30 | }
31 | }
32 |
33 | public void setJdbcFactory(JdbcFactory jdbcFactory) {
34 | this.jdbcFactory = jdbcFactory;
35 | }
36 |
37 | }
38 |
39 | interface SimpleJdbcCallback {
40 | T doIt(Connection conn) throws SQLException;
41 | }
42 |
--------------------------------------------------------------------------------
/gserver-db/src/main/java/org/gserver/db/accessor/IMysqlAccessor.java:
--------------------------------------------------------------------------------
1 | package org.gserver.db.accessor;
2 |
3 | import java.util.List;
4 | import java.util.Set;
5 |
6 | public interface IMysqlAccessor {
7 |
8 | public T queryBean(Class type, long id);
9 |
10 | public List batchQueryBean(Class type, Set ids);
11 |
12 | public int insert(String sql, Object... args);
13 |
14 | public int update(String sql, Object... args);
15 |
16 | public void delete(String sql, Object... args);
17 |
18 | public int executeUpdate(String sql, Object... args);
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/gserver-db/src/main/java/org/gserver/db/accessor/JdbcFactory.java:
--------------------------------------------------------------------------------
1 | package org.gserver.db.accessor;
2 |
3 | import java.sql.Connection;
4 | import java.sql.SQLException;
5 |
6 | import javax.sql.DataSource;
7 |
8 | import org.apache.log4j.Logger;
9 |
10 | public class JdbcFactory {
11 |
12 | private static final Logger logger = Logger.getLogger(JdbcFactory.class);
13 |
14 | protected DataSource datasource;
15 |
16 | public void setDatasource(DataSource datasource) {
17 | this.datasource = datasource;
18 | }
19 |
20 | public Connection getConnection() {
21 | try {
22 | return datasource.getConnection();
23 | } catch (SQLException e) {
24 | logger.error("getConnection error", e);
25 | }
26 | return null;
27 | }
28 |
29 | }
30 |
--------------------------------------------------------------------------------
/gserver-db/src/main/java/org/gserver/db/accessor/MysqlAccessor.java:
--------------------------------------------------------------------------------
1 | package org.gserver.db.accessor;
2 |
3 | import java.sql.Connection;
4 | import java.sql.SQLException;
5 | import java.util.List;
6 | import java.util.Set;
7 |
8 | import org.apache.commons.dbutils.QueryRunner;
9 |
10 | public class MysqlAccessor extends AbstractMysqlAccessor implements
11 | IMysqlAccessor {
12 |
13 | private QueryRunner queryRunner;
14 |
15 | public MysqlAccessor() {
16 | queryRunner = new QueryRunner();
17 | }
18 |
19 | @Override
20 | public T queryBean(Class type, long id) {
21 | return null;
22 | }
23 |
24 | @Override
25 | public List batchQueryBean(Class type, Set ids) {
26 | return null;
27 | }
28 |
29 | @Override
30 | public int insert(String sql, Object... args) {
31 | return executeUpdate(sql, args);
32 | }
33 |
34 | @Override
35 | public int update(String sql, Object... args) {
36 | return executeUpdate(sql, args);
37 | }
38 |
39 | @Override
40 | public void delete(String sql, Object... args) {
41 | executeUpdate(sql, args);
42 | }
43 |
44 | @Override
45 | public int executeUpdate(final String sql, final Object... args) {
46 | return execute(new SimpleJdbcCallback() {
47 | @Override
48 | public Integer doIt(Connection conn) throws SQLException {
49 | return queryRunner.update(conn, sql, args);
50 | }
51 | });
52 | }
53 |
54 | }
55 |
--------------------------------------------------------------------------------
/gserver-db/src/main/java/org/gserver/db/accessor/SQLUtil.java:
--------------------------------------------------------------------------------
1 | package org.gserver.db.accessor;
2 |
3 | import java.util.Map;
4 | import java.util.Set;
5 |
6 | /**
7 | * 生成sql助手类
8 | *
9 | * @author zhaohui
10 | *
11 | */
12 | public class SQLUtil {
13 |
14 | public final static String insert_into = "insert ignore into ";
15 | public final static String values = " VALUES ";
16 | public final static String set = " set ";
17 | public final static String empty_string = "";
18 | public final static String blank_string = " ";
19 | public final static String nil_string = "null";
20 | public final static String equals_string = " = ";
21 | public final static String quota_string = "'";
22 | public final static String comma_string = ",";
23 | public final static String left_Brackets = " (";
24 | public final static String right_Brackets = " )";
25 | public final static String end_string = ";";
26 | public final static String in = "in";
27 | public final static String caseS = " CASE ";
28 | public final static String end = " end ";
29 |
30 | public final static String update_table = "update ";
31 | public final static String delete_from = "delete from ";
32 | public final static String where_id = " where id ";
33 | public static final String id = "id";
34 | public static final String where = " where ";
35 |
36 | public static String insert(Map beanMap, String tableName) {
37 | if (beanMap == null || beanMap.size() <= 0) {
38 | return "";
39 | }
40 | StringBuilder buffer = new StringBuilder();
41 | buffer.append(insert_into).append(tableName);
42 |
43 | StringBuffer keyStr = new StringBuffer(left_Brackets);
44 | StringBuffer valueStr = new StringBuffer(left_Brackets);
45 |
46 | Set keySet = beanMap.keySet();
47 | int index = 0;
48 | for (String key : keySet) {
49 | String value = beanMap.get(key);
50 | if (index != keySet.size() - 1) {
51 | keyStr.append(key).append(comma_string);
52 | valueStr.append(value).append(comma_string);
53 | } else {
54 | keyStr.append(key);
55 | valueStr.append(value);
56 | }
57 | index++;
58 | }
59 | keyStr.append(right_Brackets);
60 | valueStr.append(right_Brackets);
61 |
62 | buffer.append(keyStr).append(values).append(valueStr)
63 | .append(end_string);
64 | return buffer.toString();
65 | }
66 |
67 | public String update(Map updateBean, String tableName) {
68 | if (updateBean == null || updateBean.size() <= 0) {
69 | return "";
70 | }
71 | StringBuilder buffer = new StringBuilder();
72 | buffer.append(update_table).append(tableName).append(set);
73 |
74 | Set keySet = updateBean.keySet();
75 | int index = 0;
76 | for (String key : keySet) {
77 | String value = updateBean.get(key);
78 | if (index != keySet.size() - 1) {
79 | buffer.append(key).append(equals_string).append(value)
80 | .append(comma_string);
81 | } else {
82 | buffer.append(key).append(equals_string).append(value);
83 | }
84 | index++;
85 | }
86 | return buffer.toString();
87 | }
88 |
89 | public String delete(Map params, String tableName) {
90 | StringBuilder buffer = new StringBuilder();
91 | return buffer.toString();
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/gserver-db/src/main/resources/gs-mysql.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/gserver-distribution/.gitignore:
--------------------------------------------------------------------------------
1 | /target
2 | /logs
3 | /.settings
--------------------------------------------------------------------------------
/gserver-distribution/assembly.xml:
--------------------------------------------------------------------------------
1 |
2 | bin
3 |
4 |
5 | zip
6 |
7 |
8 |
9 |
10 |
11 |
12 | false
13 | lib
14 | false
15 |
16 |
17 | com.gserver:gserver-logic
18 | com.gserver:gserver-gate
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 | ../gserver-logic/shell
27 |
28 |
29 | *
30 |
31 |
32 |
33 | ../gserver-gate/shell
34 |
35 |
36 | *
37 |
38 |
39 |
40 | ../gserver-distribution/shell
41 |
42 |
43 | *
44 |
45 |
46 |
47 |
48 | ../gserver-logic/target
49 |
50 |
51 | *.jar
52 |
53 |
54 |
55 | ../gserver-gate/target
56 |
57 |
58 | *.jar
59 |
60 |
61 |
62 |
63 | ../gserver-logic/logic-config
64 | logic-config
65 |
66 | *
67 |
68 |
69 |
70 | ../gserver-gate/gate-config
71 | gate-config
72 |
73 | *
74 |
75 |
76 |
77 |
--------------------------------------------------------------------------------
/gserver-distribution/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | com.gserver
8 | gserver
9 | 0.0.1-SNAPSHOT
10 |
11 | gserver-distribution
12 | gserver-distribution
13 | http://maven.apache.org
14 |
15 | UTF-8
16 |
17 |
18 |
19 |
20 |
21 | org.apache.maven.plugins
22 | maven-assembly-plugin
23 | 2.4
24 |
25 |
26 | assembly.xml
27 |
28 |
29 |
30 |
31 | make-assembly
32 | package
33 |
34 | single
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 | com.gserver
45 | gserver-logic
46 | 0.0.1-SNAPSHOT
47 |
48 |
49 | com.gserver
50 | gserver-gate
51 | 0.0.1-SNAPSHOT
52 |
53 |
54 |
55 |
--------------------------------------------------------------------------------
/gserver-distribution/shell/all-shutdown.bat:
--------------------------------------------------------------------------------
1 | taskkill /f /t /im cmd.exe
--------------------------------------------------------------------------------
/gserver-distribution/shell/all-startup.bat:
--------------------------------------------------------------------------------
1 | echo .| start logic-startup.bat
2 | echo .| start gate-startup.bat
--------------------------------------------------------------------------------
/gserver-distribution/src/main/java/org/gserver/distribution/App.java:
--------------------------------------------------------------------------------
1 | package org.gserver.distribution;
2 |
3 | /**
4 | * Hello world!
5 | *
6 | */
7 | public class App
8 | {
9 | public static void main( String[] args )
10 | {
11 | System.out.println( "Hello World!" );
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/gserver-gate/.gitignore:
--------------------------------------------------------------------------------
1 | /target
2 | /logs
3 | /.settings
--------------------------------------------------------------------------------
/gserver-gate/gate-config/connect-app-config.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Gate1
5 | 1000
6 |
7 |
8 | 2000
9 | 127.0.0.1
10 | 8021
11 | 5
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/gserver-gate/gate-config/server-config.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Gate1
5 | 30000
6 | 8000
7 |
8 |
--------------------------------------------------------------------------------
/gserver-gate/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | com.gserver
8 | gserver
9 | 0.0.1-SNAPSHOT
10 |
11 | gserver-gate
12 | gserver-gate
13 | http://maven.apache.org
14 |
15 | UTF-8
16 |
17 |
18 |
19 |
20 |
21 | org.apache.maven.plugins
22 | maven-jar-plugin
23 | 2.3.2
24 |
25 |
26 | false
27 |
28 | true
29 | lib/
30 | org.gserver.GateStart
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 | com.gserver
41 | gserver-services
42 | 0.0.1-SNAPSHOT
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/gserver-gate/shell/gate-startup.bat:
--------------------------------------------------------------------------------
1 | @echo off
2 | java -jar gserver-gate-0.0.1-SNAPSHOT.jar
3 | pause
--------------------------------------------------------------------------------
/gserver-gate/src/main/java/org/gserver/GateStart.java:
--------------------------------------------------------------------------------
1 | package org.gserver;
2 |
3 | import org.gserver.gate.GateServer;
4 | import org.gserver.gate.clientServer.ConnectAppServer;
5 |
6 | public class GateStart {
7 | public static void main(String[] args) {
8 | new Thread((Runnable) GateServer.getInstance()).start();
9 | new Thread((Runnable) ConnectAppServer.getInstance()).start();
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/gserver-gate/src/main/java/org/gserver/gate/ChannelCloseListener.java:
--------------------------------------------------------------------------------
1 | package org.gserver.gate;
2 |
3 | import org.apache.log4j.Logger;
4 | import org.gserver.core.util.SessionChannelManager;
5 | import org.gserver.services.SessionService;
6 | import org.jboss.netty.channel.Channel;
7 | import org.jboss.netty.channel.ChannelFuture;
8 | import org.jboss.netty.channel.ChannelFutureListener;
9 |
10 | /**
11 | * 监听channel的关闭
12 | *
13 | * @author zhaohui
14 | *
15 | */
16 | public class ChannelCloseListener implements ChannelFutureListener {
17 |
18 | private final static Logger logger = Logger
19 | .getLogger(ChannelCloseListener.class);
20 |
21 | private SessionService sessionService;
22 |
23 | /**
24 | * channel关闭处理: 1.移除sessionId和channel的关系 2.移除公共缓存中sessionId和roleId的关系
25 | */
26 | @Override
27 | public void operationComplete(ChannelFuture future) throws Exception {
28 | Channel channel = future.getChannel();
29 | logger.info("close channle:" + channel);
30 | Integer sessionId = SessionChannelManager.getInstance().getSessionId(
31 | channel);
32 | SessionChannelManager.getInstance().removeChannel(sessionId);
33 | sessionService.removeSession(sessionId);
34 | }
35 |
36 | public void setSessionService(SessionService sessionService) {
37 | this.sessionService = sessionService;
38 | }
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/gserver-gate/src/main/java/org/gserver/gate/GateHandler.java:
--------------------------------------------------------------------------------
1 | package org.gserver.gate;
2 |
3 | import org.apache.log4j.Logger;
4 | import org.gserver.core.net.Message;
5 | import org.gserver.core.threadPool.AbstractWork;
6 | import org.gserver.core.threadPool.executor.OrderedQueuePoolExecutor;
7 | import org.gserver.core.util.SessionChannelManager;
8 | import org.gserver.gate.clientServer.ConnectAppServer;
9 | import org.gserver.util.CommandEnumUtil;
10 | import org.gserver.util.SpringContainer;
11 | import org.jboss.netty.channel.Channel;
12 | import org.jboss.netty.channel.ChannelHandlerContext;
13 | import org.jboss.netty.channel.ChannelStateEvent;
14 | import org.jboss.netty.channel.ExceptionEvent;
15 | import org.jboss.netty.channel.MessageEvent;
16 | import org.jboss.netty.channel.SimpleChannelHandler;
17 |
18 | /**
19 | * 协议处理器 1.创建sessionID 2.接受客户端的消息进行转发
20 | *
21 | * @author zhaohui
22 | *
23 | */
24 | public class GateHandler extends SimpleChannelHandler {
25 |
26 | private final static Logger logger = Logger.getLogger(GateHandler.class);
27 | private OrderedQueuePoolExecutor recvExcutor = new OrderedQueuePoolExecutor(
28 | "消息接收队列", 100, 10000);
29 |
30 | @Override
31 | public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e)
32 | throws Exception {
33 | Channel channel = e.getChannel();
34 | logger.info("channelConnected:" + channel);
35 | SessionChannelManager.getInstance()
36 | .addChannle(channel.getId(), channel);
37 |
38 | ChannelCloseListener listener = (ChannelCloseListener) SpringContainer
39 | .getInstance().getBeanById("channelCloseListener");
40 | channel.getCloseFuture().addListener(listener);
41 | }
42 |
43 | @Override
44 | public void messageReceived(ChannelHandlerContext ctx, MessageEvent e)
45 | throws Exception {
46 | Message request = (Message) e.getMessage();
47 | if (!CommandEnumUtil.isValid(request.getCommand())) {
48 | return;
49 | }
50 | int sessionId = SessionChannelManager.getInstance().getSessionId(
51 | e.getChannel());
52 | request.getHeader().setSessionId(sessionId);
53 | recvExcutor.addTask(sessionId, new MWork(request));
54 | }
55 |
56 | class MWork extends AbstractWork {
57 | /** 消息 **/
58 | private Message request;
59 |
60 | public MWork(Message request) {
61 | this.request = request;
62 | }
63 |
64 | @Override
65 | public void run() {
66 | try {
67 | ConnectAppServer.getInstance().write(request);
68 | } catch (Exception ex) {
69 | logger.error("gate forward error", ex);
70 | }
71 | }
72 | }
73 |
74 | @Override
75 | public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e)
76 | throws Exception {
77 | logger.info("channel is closed" + e.getChannel());
78 | }
79 |
80 | @Override
81 | public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) {
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/gserver-gate/src/main/java/org/gserver/gate/GatePipelineFactory.java:
--------------------------------------------------------------------------------
1 | package org.gserver.gate;
2 |
3 | import org.gserver.core.net.codec.HeaderDecoder;
4 | import org.gserver.core.net.codec.HeaderEncoder;
5 | import org.jboss.netty.channel.ChannelPipeline;
6 | import org.jboss.netty.channel.ChannelPipelineFactory;
7 | import org.jboss.netty.channel.Channels;
8 |
9 | public class GatePipelineFactory implements ChannelPipelineFactory {
10 |
11 | @Override
12 | public ChannelPipeline getPipeline() throws Exception {
13 | final GateHandler handler = new GateHandler();
14 | ChannelPipeline pipeline = Channels.pipeline();
15 | pipeline.addLast("decoder", new HeaderDecoder());
16 | pipeline.addLast("encoder", new HeaderEncoder());
17 | pipeline.addLast("handler", handler);
18 | return pipeline;
19 | }
20 |
21 | }
22 |
--------------------------------------------------------------------------------
/gserver-gate/src/main/java/org/gserver/gate/GateServer.java:
--------------------------------------------------------------------------------
1 | package org.gserver.gate;
2 |
3 | import org.gserver.core.server.impl.Server;
4 | import org.gserver.util.ServerType;
5 | import org.gserver.util.SpringContainer;
6 | import org.jboss.netty.channel.ChannelPipelineFactory;
7 |
8 | /**
9 | * 网关服务器
10 | *
11 | * @author zhaohui
12 | *
13 | */
14 | public class GateServer extends Server {
15 |
16 | private static final String DEFUALT_SERVER_CONFIG = "gate-config/server-config.xml";
17 |
18 | private static GateServer gateServer = new GateServer();
19 |
20 | public static GateServer getInstance() {
21 | return gateServer;
22 | }
23 |
24 | private GateServer() {
25 | this(DEFUALT_SERVER_CONFIG);
26 | }
27 |
28 | public GateServer(String serverConfig) {
29 | super(serverConfig);
30 | }
31 |
32 | @Override
33 | protected void init() {
34 | super.init();
35 | SpringContainer.getInstance().loadSpring(ServerType.GATE);
36 | }
37 |
38 | @Override
39 | protected ChannelPipelineFactory createPipelineFactory() {
40 | return new GatePipelineFactory();
41 | }
42 |
43 | @Override
44 | protected void stop() {
45 |
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/gserver-gate/src/main/java/org/gserver/gate/clientServer/ConnectAppServer.java:
--------------------------------------------------------------------------------
1 | package org.gserver.gate.clientServer;
2 |
3 | import org.gserver.core.server.impl.ClientServer;
4 | import org.jboss.netty.channel.ChannelPipelineFactory;
5 |
6 | /**
7 | * 连接app服务器
8 | *
9 | * @author zhaohui
10 | *
11 | */
12 | public class ConnectAppServer extends ClientServer {
13 |
14 | private static final String DEFUALT_SERVER_CONFIG = "gate-config/connect-app-config.xml";
15 |
16 | private static ConnectAppServer connectAppServer = new ConnectAppServer();
17 |
18 | public static ConnectAppServer getInstance() {
19 | return connectAppServer;
20 | }
21 |
22 | private ConnectAppServer() {
23 | super(DEFUALT_SERVER_CONFIG);
24 | }
25 |
26 | @Override
27 | protected ChannelPipelineFactory createPipelineFactory() {
28 | return new ConnectPipelineFactory();
29 | }
30 |
31 | @Override
32 | protected void stop() {
33 |
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/gserver-gate/src/main/java/org/gserver/gate/clientServer/ConnectHandler.java:
--------------------------------------------------------------------------------
1 | package org.gserver.gate.clientServer;
2 |
3 | import org.apache.log4j.Logger;
4 | import org.gserver.core.net.Message;
5 | import org.gserver.core.threadPool.AbstractWork;
6 | import org.gserver.core.threadPool.executor.OrderedQueuePoolExecutor;
7 | import org.gserver.core.util.SessionChannelManager;
8 | import org.jboss.netty.channel.Channel;
9 | import org.jboss.netty.channel.ChannelHandlerContext;
10 | import org.jboss.netty.channel.ChannelStateEvent;
11 | import org.jboss.netty.channel.ExceptionEvent;
12 | import org.jboss.netty.channel.MessageEvent;
13 | import org.jboss.netty.channel.SimpleChannelHandler;
14 |
15 | /**
16 | * 协议处理器 1.创建sessionID 2.接受客户端的消息进行转发
17 | *
18 | * @author zhaohui
19 | *
20 | */
21 | public class ConnectHandler extends SimpleChannelHandler {
22 |
23 | private final static Logger logger = Logger.getLogger(ConnectHandler.class);
24 | private OrderedQueuePoolExecutor recvExcutor = new OrderedQueuePoolExecutor(
25 | "消息接收队列", 100, 10000);
26 |
27 | @Override
28 | public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e)
29 | throws Exception {
30 | }
31 |
32 | @Override
33 | public void messageReceived(ChannelHandlerContext ctx, MessageEvent e)
34 | throws Exception {
35 | Message request = (Message) e.getMessage();
36 | int sessionId = request.getHeader().getSessionId();
37 | Channel channel = SessionChannelManager.getInstance().getChannel(
38 | sessionId);
39 | recvExcutor.addTask(sessionId, new MWork(request, channel));
40 | }
41 |
42 | class MWork extends AbstractWork {
43 | /** 消息 **/
44 | private Message request;
45 | /** 消息队列 **/
46 | private Channel channel;
47 |
48 | public MWork(Message request, Channel channel) {
49 | this.request = request;
50 | this.channel = channel;
51 | }
52 |
53 | @Override
54 | public void run() {
55 | try {
56 | channel.write(request);
57 | } catch (Exception e) {
58 | logger.error("connect forward error", e);
59 | }
60 | }
61 | }
62 |
63 | @Override
64 | public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e)
65 | throws Exception {
66 | logger.info("channelClosed:" + e.getChannel());
67 | }
68 |
69 | @Override
70 | public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) {
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/gserver-gate/src/main/java/org/gserver/gate/clientServer/ConnectPipelineFactory.java:
--------------------------------------------------------------------------------
1 | package org.gserver.gate.clientServer;
2 |
3 | import org.gserver.core.net.codec.HeaderDecoder;
4 | import org.gserver.core.net.codec.HeaderEncoder;
5 | import org.jboss.netty.channel.ChannelPipeline;
6 | import org.jboss.netty.channel.ChannelPipelineFactory;
7 | import org.jboss.netty.channel.Channels;
8 |
9 | public class ConnectPipelineFactory implements ChannelPipelineFactory {
10 |
11 | @Override
12 | public ChannelPipeline getPipeline() throws Exception {
13 | final ConnectHandler handler = new ConnectHandler();
14 | ChannelPipeline pipeline = Channels.pipeline();
15 | pipeline.addLast("decoder", new HeaderDecoder());
16 | pipeline.addLast("encoder", new HeaderEncoder());
17 | pipeline.addLast("handler", handler);
18 | return pipeline;
19 | }
20 |
21 | }
22 |
--------------------------------------------------------------------------------
/gserver-gate/src/main/resources/gs-application.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/gserver-gate/src/main/resources/log4j.properties:
--------------------------------------------------------------------------------
1 | log4j.rootLogger=INFO,fileA,consoleA
2 |
3 | log4j.appender.fileA=org.apache.log4j.DailyRollingFileAppender
4 | log4j.appender.fileA.File=./logs/gate.log
5 | log4j.appender.fileA.append=true
6 | log4j.appender.fileA.ImmediateFlush=true
7 | log4j.appender.fileA.layout=org.apache.log4j.PatternLayout
8 | log4j.appender.fileA.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} [%t] %L::: %-5p %C - %m%n
9 |
10 | log4j.appender.consoleA=org.apache.log4j.ConsoleAppender
11 | log4j.appender.consoleA.layout=org.apache.log4j.PatternLayout
12 | log4j.appender.consoleA.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} - %m%n
--------------------------------------------------------------------------------
/gserver-gate/src/test/java/org/gserver/test/Client.java:
--------------------------------------------------------------------------------
1 | package org.gserver.test;
2 |
3 | import java.net.InetSocketAddress;
4 | import java.util.concurrent.Executors;
5 |
6 | import org.gserver.core.net.codec.HeaderDecoder;
7 | import org.gserver.core.net.codec.HeaderEncoder;
8 | import org.gserver.core.net.codec.encoder.ProtobufEncoder;
9 | import org.jboss.netty.bootstrap.ClientBootstrap;
10 | import org.jboss.netty.channel.ChannelFuture;
11 | import org.jboss.netty.channel.ChannelPipeline;
12 | import org.jboss.netty.channel.ChannelPipelineFactory;
13 | import org.jboss.netty.channel.Channels;
14 | import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory;
15 |
16 | public class Client {
17 |
18 | public static void main(String[] args) {
19 | ClientBootstrap cbApp = new ClientBootstrap(
20 | new NioClientSocketChannelFactory(
21 | Executors.newCachedThreadPool(),
22 | Executors.newCachedThreadPool()));
23 | final ClientHandler handler = new ClientHandler();
24 | cbApp.setPipelineFactory(new ChannelPipelineFactory() {
25 | public ChannelPipeline getPipeline() {
26 | ChannelPipeline pipeline = Channels.pipeline();
27 | pipeline.addLast("decoder", new HeaderDecoder());
28 | pipeline.addLast("hEncoder", new HeaderEncoder());
29 | pipeline.addLast("pEncoder", new ProtobufEncoder());
30 | pipeline.addLast("handler", handler);
31 | return pipeline;
32 | }
33 | });
34 | ChannelFuture future = cbApp.connect(new InetSocketAddress("localhost",
35 | 8000));
36 | future.getChannel().getCloseFuture().awaitUninterruptibly();
37 | cbApp.releaseExternalResources();
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/gserver-gate/src/test/java/org/gserver/test/ClientHandler.java:
--------------------------------------------------------------------------------
1 | package org.gserver.test;
2 |
3 | import org.gserver.core.net.Header;
4 | import org.gserver.core.net.Message;
5 | import org.gserver.util.CommandEnum;
6 | import org.jboss.netty.channel.ChannelHandlerContext;
7 | import org.jboss.netty.channel.ChannelStateEvent;
8 | import org.jboss.netty.channel.MessageEvent;
9 | import org.jboss.netty.channel.SimpleChannelHandler;
10 |
11 | import protocol.BaseType.PBLogin;
12 | import protocol.ClientServerProtocol.C2SLogin;
13 |
14 | public class ClientHandler extends SimpleChannelHandler {
15 |
16 | @Override
17 | public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e)
18 | throws Exception {
19 | PBLogin.Builder login = PBLogin.newBuilder();
20 | login.setUser("zhaohui");
21 | login.setPswd("11111111");
22 |
23 | C2SLogin.Builder c2sLogin = C2SLogin.newBuilder().setLogin(login);
24 |
25 | Header header = new Header();
26 | header.setSessionId(1);
27 | header.setCommandId(CommandEnum.C2S_LOGIN.getId());
28 | Message message = new Message(header, c2sLogin.build().toByteArray());
29 | e.getChannel().write(message);
30 | }
31 |
32 | @Override
33 | public void messageReceived(ChannelHandlerContext ctx, MessageEvent e)
34 | throws Exception {
35 | Message message = (Message) e.getMessage();
36 | System.out.println("cmd:" + message.getHeader().getCommandId());
37 | System.out.println(message.getData());
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/gserver-logic/.gitignore:
--------------------------------------------------------------------------------
1 | /target
2 | /logs
3 | /.settings
--------------------------------------------------------------------------------
/gserver-logic/logic-config/server-config.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | App1
5 | 2000
6 | 8021
7 |
8 |
--------------------------------------------------------------------------------
/gserver-logic/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | com.gserver
8 | gserver
9 | 0.0.1-SNAPSHOT
10 |
11 | gserver-logic
12 | gserver-logic
13 | http://maven.apache.org
14 |
15 | UTF-8
16 |
17 |
18 |
19 |
20 |
21 | org.apache.maven.plugins
22 | maven-jar-plugin
23 | 2.3.2
24 |
25 |
26 | false
27 |
28 | true
29 | lib/
30 | org.gserver.LogicStart
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 | com.gserver
41 | gserver-services
42 | 0.0.1-SNAPSHOT
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/gserver-logic/shell/logic-startup.bat:
--------------------------------------------------------------------------------
1 | @echo off
2 | java -jar gserver-logic-0.0.1-SNAPSHOT.jar
3 | pause
--------------------------------------------------------------------------------
/gserver-logic/src/main/java/org/gserver/LogicStart.java:
--------------------------------------------------------------------------------
1 | package org.gserver;
2 |
3 | import org.gserver.logic.LogicServer;
4 |
5 | public class LogicStart {
6 |
7 | public static void main(String[] args) {
8 | LogicServer logicServer = new LogicServer();
9 | new Thread((Runnable) logicServer).start();
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/gserver-logic/src/main/java/org/gserver/handler/Handler100001.java:
--------------------------------------------------------------------------------
1 | package org.gserver.handler;
2 |
3 | import org.gserver.core.exception.GsException;
4 | import org.gserver.core.net.Message;
5 | import org.gserver.util.CommandEnum;
6 |
7 | import protocol.ClientServerProtocol.C2SLogin;
8 | import protocol.ServerClientProtocol.S2CLogin;
9 |
10 | import com.google.protobuf.InvalidProtocolBufferException;
11 |
12 | public class Handler100001 extends AbstractHandler {
13 |
14 | @Override
15 | public void execute(Long roleId, Message request) throws GsException,
16 | InvalidProtocolBufferException {
17 | C2SLogin login = C2SLogin.parseFrom((byte[]) request.getData());
18 | System.out.println(login.toString());
19 |
20 | S2CLogin.Builder builder = S2CLogin.newBuilder();
21 | builder.setResult(1);
22 |
23 | sendMessage(request.getSessionId(), CommandEnum.S2C_LOGIN, builder
24 | .build().toByteArray());
25 | }
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/gserver-logic/src/main/java/org/gserver/logic/LogicHandler.java:
--------------------------------------------------------------------------------
1 | package org.gserver.logic;
2 |
3 | import org.apache.log4j.Logger;
4 | import org.gserver.core.exception.GsException;
5 | import org.gserver.core.handler.IHandler;
6 | import org.gserver.core.net.Message;
7 | import org.gserver.core.threadPool.AbstractWork;
8 | import org.gserver.core.threadPool.executor.OrderedQueuePoolExecutor;
9 | import org.gserver.core.util.ChannelPoolManager;
10 | import org.gserver.util.CommandEnum;
11 | import org.gserver.util.ErrorCode;
12 | import org.gserver.util.SpringContainer;
13 | import org.jboss.netty.channel.Channel;
14 | import org.jboss.netty.channel.ChannelHandlerContext;
15 | import org.jboss.netty.channel.ChannelStateEvent;
16 | import org.jboss.netty.channel.ExceptionEvent;
17 | import org.jboss.netty.channel.MessageEvent;
18 | import org.jboss.netty.channel.SimpleChannelHandler;
19 |
20 | import protocol.ServerClientProtocol.S2CErrorCode;
21 |
22 | /**
23 | * 协议处理器 1.创建sessionID // 2.接受客户端的消息进行转发 //
24 | *
25 | * @author zhaohui
26 | *
27 | */
28 | public class LogicHandler extends SimpleChannelHandler {
29 |
30 | private final static Logger logger = Logger.getLogger(LogicHandler.class);
31 | private OrderedQueuePoolExecutor recvExcutor = new OrderedQueuePoolExecutor(
32 | "消息接收队列", 100, 10000);
33 |
34 | @Override
35 | public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e)
36 | throws Exception {
37 | ChannelPoolManager.getInstance().addChannel(e.getChannel());
38 | logger.info("connected:" + e.getChannel().toString());
39 | }
40 |
41 | @Override
42 | public void messageReceived(ChannelHandlerContext ctx, MessageEvent e)
43 | throws Exception {
44 | Message request = (Message) e.getMessage();
45 | int sessionId = request.getHeader().getSessionId();
46 | recvExcutor.addTask(sessionId, new MWork(request, e.getChannel()));
47 | }
48 |
49 | class MWork extends AbstractWork {
50 | /** 消息 **/
51 | private Message request;
52 | /** 消息队列 **/
53 | private Channel channel;
54 |
55 | public MWork(Message request, Channel channel) {
56 | this.request = request;
57 | this.channel = channel;
58 | }
59 |
60 | @Override
61 | public void run() {
62 | channel.write(processRequest(request));
63 | }
64 | }
65 |
66 | /**
67 | * 处理请求
68 | *
69 | * @param request
70 | * 请求消息
71 | * @return
72 | */
73 | private Message processRequest(Message request) {
74 | int cmdId = getCommandId(request);
75 | Message response = new Message(request.getHeader().clone());
76 | try {
77 | IHandler handler = (IHandler) SpringContainer.getInstance()
78 | .getBeanById("handler" + cmdId);
79 | if (handler == null) {
80 | setErrorMsg(ErrorCode.PACKAGE_TAG_ERROR, response);
81 | return response;
82 | }
83 | handler.execute(request);
84 | } catch (GsException e) {
85 | setErrorMsg(e.getErrorCode(), response);
86 | } catch (Exception ex) {
87 | setErrorMsg(ErrorCode.SERVER_ERROR, response);
88 | logger.error("processRequest error", ex);
89 | }
90 | return response;
91 | }
92 |
93 | /**
94 | * 获取协议号
95 | *
96 | * @param message
97 | * 消息
98 | * @return
99 | */
100 | private int getCommandId(Message message) {
101 | return message.getHeader().getCommandId();
102 | }
103 |
104 | private void setErrorMsg(int errcode, Message response) {
105 | S2CErrorCode.Builder builder = S2CErrorCode.newBuilder();
106 | builder.setErrorCode(errcode);
107 | response.setContent(CommandEnum.S2C_ERROR_CODE.getId(), builder.build()
108 | .toByteArray());
109 | }
110 |
111 | @Override
112 | public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e)
113 | throws Exception {
114 | ChannelPoolManager.getInstance().removeChannel(e.getChannel());
115 | logger.info("channelClosed:" + e.getChannel().toString());
116 | }
117 |
118 | @Override
119 | public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) {
120 | }
121 | }
122 |
--------------------------------------------------------------------------------
/gserver-logic/src/main/java/org/gserver/logic/LogicPipelineFactory.java:
--------------------------------------------------------------------------------
1 | package org.gserver.logic;
2 |
3 | import org.gserver.core.net.codec.HeaderDecoder;
4 | import org.gserver.core.net.codec.HeaderEncoder;
5 | import org.gserver.core.net.codec.encoder.ProtobufEncoder;
6 | import org.jboss.netty.channel.ChannelPipeline;
7 | import org.jboss.netty.channel.ChannelPipelineFactory;
8 | import org.jboss.netty.channel.Channels;
9 |
10 | public class LogicPipelineFactory implements ChannelPipelineFactory {
11 |
12 | @Override
13 | public ChannelPipeline getPipeline() throws Exception {
14 | final LogicHandler handler = new LogicHandler();
15 |
16 | ChannelPipeline pipeline = Channels.pipeline();
17 | pipeline.addLast("decoder", new HeaderDecoder());
18 |
19 | pipeline.addLast("encoder", new HeaderEncoder());
20 | pipeline.addLast("pEncoder", new ProtobufEncoder());
21 | pipeline.addLast("handler", handler);
22 | return pipeline;
23 | }
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/gserver-logic/src/main/java/org/gserver/logic/LogicServer.java:
--------------------------------------------------------------------------------
1 | package org.gserver.logic;
2 |
3 | import org.gserver.core.server.impl.Server;
4 | import org.gserver.util.ServerType;
5 | import org.gserver.util.SpringContainer;
6 | import org.jboss.netty.channel.ChannelPipelineFactory;
7 |
8 | public class LogicServer extends Server {
9 |
10 | private static final String DEFUALT_SERVER_CONFIG = "logic-config/server-config.xml";
11 |
12 | public LogicServer() {
13 | this(DEFUALT_SERVER_CONFIG);
14 | }
15 |
16 | public LogicServer(String serverConfig) {
17 | super(serverConfig);
18 | }
19 |
20 | @Override
21 | protected void init() {
22 | super.init();
23 | SpringContainer.getInstance().loadSpring(ServerType.LOGIC);
24 | }
25 |
26 | @Override
27 | protected ChannelPipelineFactory createPipelineFactory() {
28 | return new LogicPipelineFactory();
29 | }
30 |
31 | @Override
32 | protected void stop() {
33 |
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/gserver-logic/src/main/resources/gs-handlers.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
6 |
--------------------------------------------------------------------------------
/gserver-logic/src/main/resources/log4j.properties:
--------------------------------------------------------------------------------
1 | log4j.rootLogger=INFO,fileA,consoleA
2 |
3 | log4j.appender.fileA=org.apache.log4j.DailyRollingFileAppender
4 | log4j.appender.fileA.File=./logs/logic.log
5 | log4j.appender.fileA.append=true
6 | log4j.appender.fileA.ImmediateFlush=true
7 | log4j.appender.fileA.layout=org.apache.log4j.PatternLayout
8 | log4j.appender.fileA.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} [%t] %L::: %-5p %C - %m%n
9 |
10 | log4j.appender.consoleA=org.apache.log4j.ConsoleAppender
11 | log4j.appender.consoleA.layout=org.apache.log4j.PatternLayout
12 | log4j.appender.consoleA.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} - %m%n
--------------------------------------------------------------------------------
/gserver-redis/.gitignore:
--------------------------------------------------------------------------------
1 | /target
2 |
--------------------------------------------------------------------------------
/gserver-redis/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | com.gserver
8 | gserver
9 | 0.0.1-SNAPSHOT
10 |
11 | gserver-redis
12 | gserver-redis
13 | http://maven.apache.org
14 |
15 | UTF-8
16 |
17 |
18 |
19 |
20 | redis.clients
21 | jedis
22 | 2.8.0
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/gserver-redis/src/main/java/org/gserver/redis/IRedisTemplateMethod.java:
--------------------------------------------------------------------------------
1 | package org.gserver.redis;
2 |
3 | import org.gserver.redis.persistence.AbstractRedisBean;
4 |
5 | /**
6 | * redis操作模板方法接口
7 | *
8 | * @author zhaohui
9 | *
10 | */
11 | public interface IRedisTemplateMethod {
12 |
13 | /**
14 | * 创建新对象
15 | *
16 | * @param bean
17 | * 实例对象
18 | * @return
19 | */
20 | public T create(T bean);
21 |
22 | public T create(String beanKey, T bean);
23 |
24 | /**
25 | * 查询对象
26 | *
27 | * @param key
28 | * 对象key
29 | * @param type
30 | * 对象类型
31 | * @return
32 | */
33 | public T query(String key, Class type);
34 |
35 | public T query(long beanId, Class type);
36 |
37 | /**
38 | * 更新对象
39 | *
40 | * @param id
41 | * @param bean
42 | */
43 | public void update(long id, AbstractRedisBean bean);
44 |
45 | public void update(String key, AbstractRedisBean bean);
46 |
47 | /**
48 | * 删除对象
49 | *
50 | * @param beanId
51 | * @param type
52 | */
53 | public void delete(long beanId, Class type);
54 |
55 | public void delete(String key);
56 |
57 | public Long hset(String key, String field, String value);
58 |
59 | public String hget(String key, String field);
60 |
61 | public Long hdel(final String key, final String field);
62 | }
63 |
--------------------------------------------------------------------------------
/gserver-redis/src/main/java/org/gserver/redis/RedisTemplateMethod.java:
--------------------------------------------------------------------------------
1 | package org.gserver.redis;
2 |
3 | import java.util.HashMap;
4 | import java.util.Map;
5 | import java.util.Map.Entry;
6 |
7 | import org.apache.log4j.Logger;
8 | import org.gserver.redis.accessor.IRedisAccessor;
9 | import org.gserver.redis.persistence.AbstractRedisBean;
10 | import org.gserver.redis.util.BeanUtil;
11 | import org.gserver.redis.util.KeyUtil;
12 |
13 | public class RedisTemplateMethod implements IRedisTemplateMethod {
14 |
15 | private static final Logger logger = Logger
16 | .getLogger(RedisTemplateMethod.class);
17 |
18 | private IRedisAccessor redisAccessor;
19 |
20 | @Override
21 | public T create(T bean) {
22 | long beanIncrId = redisAccessor.getSequence(bean.getClass().getName());
23 | bean.setId(beanIncrId);
24 | String beanKey = KeyUtil.getRedisBeanKey(bean.getClass(), beanIncrId);
25 | return createBean(beanKey, bean);
26 | }
27 |
28 | @Override
29 | public T create(String beanKey, T bean) {
30 | Long beanIncrId = redisAccessor.getSequence(bean.getClass().getName());
31 | bean.setId(beanIncrId);
32 | return createBean(beanKey, bean);
33 | }
34 |
35 | private T createBean(String beanKey, T bean) {
36 | Map beanMap = bean.transToMap();
37 | try {
38 | long startTime = System.currentTimeMillis();
39 | redisAccessor.setHashMapValue(beanKey, beanMap);
40 | long endTime = System.currentTimeMillis();
41 | logger.debug("【createBean】:" + beanKey + ",costTime:"
42 | + (endTime - startTime));
43 | } catch (Exception ex) {
44 | logger.error("createBean error", ex);
45 | }
46 | return bean;
47 | }
48 |
49 | @Override
50 | public void update(long id, AbstractRedisBean bean) {
51 | String key = KeyUtil.getRedisBeanKey(bean.getClass(), id);
52 | updateBean(key, bean);
53 | }
54 |
55 | @Override
56 | public void update(String key, AbstractRedisBean bean) {
57 | updateBean(key, bean);
58 | }
59 |
60 | private void updateBean(String key, AbstractRedisBean bean) {
61 | Map map = bean.getChangedMap();
62 | if (map.size() <= 0)
63 | return;
64 |
65 | Map updateMap = new HashMap();
66 | for (Entry param : map.entrySet()) {
67 | if (param.getValue() instanceof String) {
68 | updateMap.put(param.getKey(), param.getValue().toString());
69 | } else {
70 | updateMap.put(param.getKey(), String.valueOf(param.getValue()));
71 | }
72 | }
73 |
74 | try {
75 | redisAccessor.setHashMapValue(key, updateMap);
76 | bean.clearChangeMap();
77 | } catch (Exception ex) {
78 | logger.error("updateBean error", ex);
79 | }
80 | }
81 |
82 | @Override
83 | public T query(String key, Class type) {
84 | return queryBean(key, type);
85 | }
86 |
87 | @Override
88 | public T query(long beanId, Class type) {
89 | if (beanId <= 0)
90 | return null;
91 | String key = KeyUtil.getRedisBeanKey(type, beanId);
92 | return queryBean(key, type);
93 | }
94 |
95 | private T queryBean(String key, Class type) {
96 | Map beanMap = null;
97 | try {
98 | long startTime = System.currentTimeMillis();
99 | beanMap = redisAccessor.getHashMapValue(key);
100 | long endTime = System.currentTimeMillis();
101 | logger.debug("【queryBean】:" + key + ",costTime:"
102 | + (endTime - startTime));
103 | } catch (Exception ex) {
104 | logger.error("queryBean error", ex);
105 | }
106 | String checkedId = beanMap.get("id");
107 | if (checkedId != null && !checkedId.equals(""))
108 | return BeanUtil.reverse(beanMap, type);
109 | else {
110 | return null;
111 | }
112 | }
113 |
114 | public void setRedisAccessor(IRedisAccessor redisAccessor) {
115 | this.redisAccessor = redisAccessor;
116 | }
117 |
118 | @Override
119 | public void delete(long beanId, Class type) {
120 | String key = KeyUtil.getRedisBeanKey(type, beanId);
121 | delete(key);
122 | }
123 |
124 | @Override
125 | public void delete(String key) {
126 | redisAccessor.deleteKey(key);
127 | }
128 |
129 | @Override
130 | public Long hset(String key, String field, String value) {
131 | return redisAccessor.hset(key, field, value);
132 | }
133 |
134 | @Override
135 | public String hget(String key, String field) {
136 | return redisAccessor.hget(key, field);
137 | }
138 |
139 | @Override
140 | public Long hdel(String key, String field) {
141 | return redisAccessor.hdel(key, field);
142 | }
143 | }
144 |
--------------------------------------------------------------------------------
/gserver-redis/src/main/java/org/gserver/redis/accessor/AbstractRedisAccessor.java:
--------------------------------------------------------------------------------
1 | package org.gserver.redis.accessor;
2 |
3 | import org.apache.log4j.Logger;
4 |
5 | import redis.clients.jedis.Jedis;
6 |
7 | public abstract class AbstractRedisAccessor {
8 |
9 | private static final Logger logger = Logger
10 | .getLogger(AbstractRedisAccessor.class);
11 |
12 | private RedisFactory redisFactory;
13 |
14 | protected T execute(RedisCallback action) {
15 | T result = null;
16 | Jedis jedis = null;
17 | try {
18 | jedis = redisFactory.getJedis();
19 | result = action.doIt(jedis);
20 | } catch (Exception e) {
21 | logger.error("redis doIt error", e);
22 | } finally {
23 | if (jedis != null) {
24 | redisFactory.close(jedis);
25 | }
26 | }
27 | return result;
28 | }
29 |
30 | public RedisFactory getRedisFactory() {
31 | return redisFactory;
32 | }
33 |
34 | public void setRedisFactory(RedisFactory redisFactory) {
35 | this.redisFactory = redisFactory;
36 | }
37 |
38 | }
39 |
40 | interface RedisCallback {
41 | T doIt(Jedis jedis);
42 | }
43 |
--------------------------------------------------------------------------------
/gserver-redis/src/main/java/org/gserver/redis/accessor/IRedisAccessor.java:
--------------------------------------------------------------------------------
1 | package org.gserver.redis.accessor;
2 |
3 | import java.util.Map;
4 |
5 | import redis.clients.jedis.JedisPubSub;
6 |
7 | /**
8 | * redis连接器
9 | *
10 | * @author zhaohui
11 | *
12 | */
13 | public interface IRedisAccessor {
14 |
15 | public Integer setHashMapValue(String key, Map values);
16 |
17 | public Map getHashMapValue(String key);
18 |
19 | /**
20 | * 获取指定key的序列号
21 | *
22 | * @param key
23 | * @return
24 | */
25 | public long getSequence(final String key);
26 |
27 | /**
28 | * 删除指定的key
29 | *
30 | * @param keys
31 | */
32 | public void deleteKey(final String... keys);
33 |
34 | /**
35 | * 发布消息
36 | *
37 | * @param channel
38 | * @param message
39 | * @return
40 | */
41 | public Long publishMessage(final String channel, final String message);
42 |
43 | /**
44 | * 订阅消息
45 | *
46 | * @param listener
47 | * @param channels
48 | */
49 | public void subscribe(final JedisPubSub listener, final String... channels);
50 |
51 | public Long hset(String key, String field, String value);
52 |
53 | public String hget(String key, String field);
54 |
55 | public Long hdel(final String key, final String field);
56 |
57 | }
58 |
--------------------------------------------------------------------------------
/gserver-redis/src/main/java/org/gserver/redis/accessor/RedisAccessor.java:
--------------------------------------------------------------------------------
1 | package org.gserver.redis.accessor;
2 |
3 | import java.util.Map;
4 |
5 | import redis.clients.jedis.Jedis;
6 | import redis.clients.jedis.JedisPubSub;
7 |
8 | public class RedisAccessor extends AbstractRedisAccessor implements
9 | IRedisAccessor {
10 |
11 | @Override
12 | public Integer setHashMapValue(final String key,
13 | final Map values) {
14 | return execute(new RedisCallback() {
15 | @Override
16 | public Integer doIt(Jedis jedis) {
17 | jedis.hmset(key, values);
18 | return 1;
19 | }
20 | });
21 | }
22 |
23 | @Override
24 | public Map getHashMapValue(final String key) {
25 | return execute(new RedisCallback