# Summer
**Repository Path**: mingshashan/Summer
## Basic Information
- **Project Name**: Summer
- **Description**: 这是一个支持分布式和集群的java游戏服务器框架,可用于开发棋牌、回合制等游戏。基于netty实现高性能通讯,支持tcp、http、websocket等协议。支持消息加解密、攻击拦截、黑白名单机制。封装了redis缓存、mysql数据库的连接与使用。轻量级,便于上手。
- **Primary Language**: Java
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 3
- **Forks**: 2
- **Created**: 2020-03-20
- **Last Updated**: 2023-05-11
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# Summer
这是一个支持分布式和集群的java游戏服务器框架,可用于开发棋牌、回合制等游戏。基于netty实现高性能通讯,支持tcp、http、websocket等协议。支持消息加解密、攻击拦截、黑白名单机制。封装了redis缓存、mysql数据库的连接与使用。轻量级,便于上手。
## 目录
- 前言
- 环境介绍与安装说明
- 快捷上手
- 创建项目
- 项目结构
- 运行项目
- 框架介绍
- 组件介绍
- 注解介绍
- 核心方法介绍
- 异常介绍
- 协议介绍
- Web介绍
- 运行机制
- 其他介绍
## 前言
## 更新
### 2019.02.20
1. 新增Summer.getServerEventLoopGroup,用于获取服务器业务线程池
2. 新增Summer.getSessionQueueSize,用于获取会话队列长度
3. 优化SessionQueue、SingleQueue队列,不再分配新线程,将以队列的形式逐个提交到服务器业务线程中(在此特别感谢一位大哥的支持与协助)
### 2019.02.17
1. ClientRemote类,新增rsyncRemote方法,调用接口超时将自动重试直到成功为止。
2. ClientRemote类,新增getServerName方法,用于获取连接其他服务器的节点名称。
3. 新增Summer.getRemoteInvokeObjectWithRetry、Summer.getRandomRemoteInvokeObjectWithRetry,用于获取连接其他服务器的远程调用接口代理对象,超时将自动重试直到成功为止。
### 2019.01.28
1. 修复了,服务器之间远程调用可能出现丢包的问题,原因是消息id不能正确的递增,解决办法是修改了消息id的判断。
2. 当作为web服务器时,若接口返回的类型不是WebView,则将返数据序列化成Json,并返回TextView。
## 环境介绍与安装说明
JDK 1.8 以上
MySql 5.7 (仅供参考)
Redis 5.0 (仅供参考)
IDE: eclipse (仅供参考)
将SummerServer库添加至UserLibraries
#### SummerServer库
asm-6.2.jar
cglib-3.2.7.jar
commons-dbutils-1.7.jar
commons-pool2-2.4.2.jar
druid-1.1.10.jar
fastjson-1.2.47.jar
freemarker-2.3.23.jar
javassist-3.22.0-GA.jar
jedis-2.9.0.jar
log4j-1.2.17.jar
mysql-connector-java-5.1.20-bin.jar
netty-all-4.1.23.Final.jar
quartz-2.3.0.jar
slf4j-api-1.7.25.jar
slf4j-log4j12-1.7.25.jar
## 快捷上手
### 创建项目
1. 创建普通的java project项目
2. 为当前项目添加SummerServer库
### 项目结构
- src
- lib
- config
- Template #Web项目
- WebContent #Web项目
#### src
##### 包结构
- com.test.summerDemo
- bean #实体
- constant #常量
- dao #数据库操作
- service #业务逻辑
- event #事件触发器
- handler #服务器会话回调
- push #推送接口
- remote #远程接口
- task #定时任务
- exception #异常信息
- manager #对象管理
- util #工具
- SummerDemoApp.java #启动类
##### 启动类
```java
package com.test.summerDemo;
import com.swingfrog.summer.app.Summer;
import com.swingfrog.summer.app.SummerApp;
public class SummerDemoApp implements SummerApp {
@Override
public void init() {
}
@Override
public void start() {
}
@Override
public void stop() {
}
public static void main(String[] args) throws Exception {
Summer.hot(new SummerDemoApp());
}
}
```
##### 其余的组件将在下文逐一介绍
#### lib
引用外部jar包请放在此目录下,并添加引用。
引用Summer.jar,此jar包依赖SummerServer库。
#### config
- db.properties #数据库配置文件
- redis.properties #缓存配置文件
- log.properties #日志配置文件
- task.properties #任务配置文件
- server.properties #服务器配置文件
##### db.properties (druid的配置文件)
```properties
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/db_test?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull
username=root
password=123456
filters=stat
initialSize=2
maxActive=300
maxWait=60000
timeBetweenEvictionRunsMillis=60000
minEvictableIdleTimeMillis=300000
validationQuery=SELECT 1
testWhileIdle=true
testOnBorrow=false
testOnReturn=false
poolPreparedStatements=false
maxPoolPreparedStatementPerConnectionSize=200
```
##### redis.properties (jedis配置文件)
```properties
url=127.0.0.1
port=6379
timeout=3000
password=123456
blockWhenExhausted=true
evictionPolicyClassName=org.apache.commons.pool2.impl.DefaultEvictionPolicy
jmxEnabled=true
maxIdle=8
maxTotal=200
maxWaitMillis=100000
testOnBorrow=true
```
##### log.properties (log4j配置文件)
```properties
log4j.rootLogger=DEBUG,C
log4j.logger.org.quartz=OFF
log4j.logger.com.alibaba.druid=DEBUG
log4j.logger.io.netty=OFF
log4j.appender.C=org.apache.log4j.ConsoleAppender
log4j.appender.C.Target=System.out
log4j.appender.C.layout=com.swingfrog.summer.log.ColorPatternLayout
log4j.appender.C.layout.ConversionPattern=%-d{yyyy-MM-dd HH\:mm\:ss\:SSS} [%t] %p [] %m %n
log4j.appender.F=org.apache.log4j.DailyRollingFileAppender
log4j.appender.F.File=log/container
log4j.appender.F.Append=true
log4j.appender.F.DatePattern='.'yyyy-MM-dd
log4j.appender.F.layout=com.swingfrog.summer.log.ColorPatternLayout
log4j.appender.F.layout.ConversionPattern=%-d{yyyy-MM-dd HH\:mm\:ss\:SSS} [%t] %p [] %m %n
```
##### task.properties (quartz配置文件)
```properties
org.quartz.scheduler.instanceName=Task
org.quartz.scheduler.rmi.export=false
org.quartz.scheduler.rmi.proxy=false
org.quartz.scheduler.wrapJobExecutionInUserTransaction=false
org.quartz.threadPool.class=org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount=10
org.quartz.threadPool.threadPriority=5
org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread=true
org.quartz.jobStore.misfireThreshold=60000
org.quartz.jobStore.class=org.quartz.simpl.RAMJobStore
```
##### server.properties (服务器配置文件)
```properties
#服务器集群名称
server.cluster=Gate
#服务器节点名称
server.serverName=gate_s1
#绑定地址
server.address=127.0.0.1
#绑定端口
server.port=8828
#通讯协议
server.protocol=Http
#消息编码
server.charset=UTF-8
#消息密码
server.password=123456
#侦听线程数
server.bossThread=0
#读写线程数
server.workerThread=0
#业务线程数
server.eventThread=0
#消息最大长度 单位字节
server.msgLength=1024000
#心跳时间 单位秒
server.heartSec=40
#请求的间隔时间
server.coldDownMs=10
#是否开启连接白名单
server.allowAddressEnable=true
#白名单允许连接的地址
server.allowAddressList=127.0.0.1,127.0.0.2
#连接其他服务器的列表
server.clientList=account_s1,account_s2
#其他服务器的集群名称
client.account_s1.cluster=Account
#其他服务器的节点名称
client.account_s1.serverName=account_s1
#连接地址
client.account_s1.address=127.0.0.1
#连接端口
client.account_s1.port=8828
#通讯协议
client.account_s1.protocol=StringLine
#消息编码
client.account_s1.charset=UTF-8
#消息密码
client.account_s1.password=123456
#读写线程数
client.account_s1.workerThread=0
#业务线程数
client.account_s1.eventThread=0
#消息最大长度 单位字节
client.account_s1.msgLength=1024
#心跳时间 单位秒
client.account_s1.heartSec=20
#断线重连间隔时间 单位毫秒
client.account_s1.reconnectMs=100
#远程调用超时时间 单位毫秒
client.account_s1.syncRemoteTimeOutMs=5000
#连接数
client.account_s1.connectNum=1
client.account_s2.cluster=Account
client.account_s2.serverName=account_s2
client.account_s2.address=127.0.0.1
client.account_s2.port=8828
client.account_s2.protocol=StringLine
client.account_s2.charset=UTF-8
client.account_s2.password=123456
client.account_s2.workerThread=0
client.account_s2.eventThread=0
client.account_s2.msgLength=1024
client.account_s2.heartSec=20
client.account_s2.reconnectMs=100
client.account_s2.syncRemoteTimeOutMs=5000
client.account_s2.connectNum=1
```
### 运行项目
#### 开发环境
在eclipse中可直接运行或调试,启动类为SummerDemoApp.class
#### 生产环境
##### 打包
在Options中勾选Add directory entries。
注意,不要导出可运行的jar文件,因为会把lib中引用的jar和引用的库打包进jar中,造成jar体积巨大。
##### 项目结构
- SummerDemo
- SummerDemo.jar
- lib
- config
- Template
- WebContent
- SummerRuntime.jar
##### 使用SummerRuntime.jar运行
java -jar SummerRuntime.jar SummerDemo/SummerDemo.jar com.test.summerDemo.SummerDemoApp
## 框架介绍
### 组件介绍
SummerApp由辅助组件和主要组件组成,其中bean、constant、manager、util、exception为辅助组件,dao、service、event、handler、push、remote、task、app为主要组件。
#### bean
javabean、数据表的实体映射
#### constant
常量声明
#### manager
对象管理,使用时在类上方使用注解@Bean
```java
@Bean
public class LoginManager {
private ConcurrentHashMap accountIdMap = new ConcurrentHashMap<>();
private ConcurrentHashMap sessionContextMap = new ConcurrentHashMap<>();
//省略...
}
```
#### util
工具类
#### exception
异常信息声明
#### dao
数据库操作,类需继承BaseDao并使用注解@Dao
```java
@Dao
public class AccountDao extends BaseDao {
public Account getById(int id) {
return getBean("select * from t_account where id = ?", id);
}
}
```
```java
public abstract class BaseDao {
protected int update(String sql, Object... args){}
protected Long insertAndGetGeneratedKeys(String sql, Object... args){}
protected T getBean(String sql, Object... args) {}
protected List listBean(String sql, Object... args) {}
protected E getValue(String sql, Object... args) {}
protected List listValue(String sql, Object... args) {}
protected Map getMap(String sql, Object... args) {}
protected List