├── readme.doc ├── README.md ├── .gitignore ├── ALBasicProtocolPack ├── src │ └── ALBasicProtocolPack │ │ ├── BasicObj │ │ ├── _IALProtocolReceiver.java │ │ ├── _AALBasicProtocolSubOrderDealer.java │ │ ├── ALBasicProtocolDispather.java │ │ └── _AALBasicProtocolMainOrderDealer.java │ │ ├── _IALProtocolStructure.java │ │ └── ALProtocolCommon.java ├── .project └── .classpath ├── ALServerLog ├── conf │ └── ALServerLog.properties ├── .classpath ├── .project └── src │ └── ALServerLog │ └── ALServerLog.java ├── ALBasicClient ├── conf │ ├── ALServerLog.properties │ └── ALBasicClientConf.properties ├── .project ├── .classpath └── src │ └── ALBasicClient │ ├── ALBasicClientSendThreadMgr.java │ ├── ALBasicClient.java │ ├── CosClientSocketSendThread.java │ ├── ALBasicSendingClientManager.java │ ├── _AALBasicClientListener.java │ ├── ALBasicClientConf.java │ ├── ALBasicClientRecThread.java │ └── ALBasicClientSocket.java ├── ALBasicServer ├── conf │ ├── ALServerLog.properties │ └── ALBasicServerConf.properties ├── src │ ├── ALBasicServer │ │ ├── ALBasicMutex │ │ │ ├── MutexAtom.java │ │ │ ├── MutexManager.java │ │ │ ├── MutexObject.java │ │ │ └── MutexInstance.java │ │ ├── ALTask │ │ │ ├── _AALAsynCallAndBackTask.java │ │ │ ├── _IALAsynRunnableTask.java │ │ │ ├── _IALSynTask.java │ │ │ ├── _IALAsynCallTask.java │ │ │ └── _IALAsynCallBackTask.java │ │ ├── ALVerifyObj │ │ │ ├── _IALVerifyFun.java │ │ │ ├── SynCheckVerifyLoginTimeOutTask.java │ │ │ ├── ALVerifyDealerObj.java │ │ │ ├── AsynRun_UserLoginTask.java │ │ │ └── ALVerifyObjMgr.java │ │ ├── ALServerCmd │ │ │ ├── _IALBasicServerCmdDealer.java │ │ │ ├── ALSynCmdDealTask.java │ │ │ ├── ALCmdLineReadThread.java │ │ │ └── ALCmdDealerManager.java │ │ ├── ALSocket │ │ │ ├── SynDelaySendTask.java │ │ │ ├── SynReceiveMessageTask.java │ │ │ ├── SynDisconnectTask.java │ │ │ ├── ALServerSocketSendThread.java │ │ │ ├── ALServerSendSocketMgr.java │ │ │ ├── _AALBasicServerSocketListener.java │ │ │ ├── ALServerSocketMgr.java │ │ │ ├── ALServerSocketListenFunction.java │ │ │ └── ALBasicServerSocket.java │ │ ├── ALServerAsynTask │ │ │ ├── SynAsynCallBackTask.java │ │ │ ├── ALAsynTaskThread.java │ │ │ ├── ALAsynTaskInfo.java │ │ │ ├── ALAsynThreadTaskManager.java │ │ │ └── ALAsynTaskManager.java │ │ ├── ALServerSynTask │ │ │ ├── ALSynTimingTaskCheckThread.java │ │ │ ├── ALSynTimingTaskNodeFarDelayTaskInfo.java │ │ │ ├── ALSynTaskDealThread.java │ │ │ ├── ALSynTimingTaskNode.java │ │ │ └── ALSynTaskManager.java │ │ ├── ALThread │ │ │ ├── ALMutexInfo.java │ │ │ ├── ALMutex.java │ │ │ ├── ALThreadManager.java │ │ │ └── ALThreadMutexMgr.java │ │ ├── ALBasicServer.java │ │ └── ALBasicServerConf.java │ └── ALBasicClient │ │ ├── ALSynServerClientDealMessageTask.java │ │ └── _AALBasicServerClientListener.java ├── .project └── .classpath ├── ExampleClient ├── conf │ ├── ALServerLog.properties │ └── ALBasicClientConf.properties ├── .project ├── src │ └── ExampleClient │ │ ├── ExampleClient.java │ │ └── ExampleClientConnecter.java └── .classpath ├── ExampleServer ├── conf │ ├── ALServerLog.properties │ └── ALBasicServerConf.properties ├── src │ └── ExampleServer │ │ ├── ExampleSynTask.java │ │ ├── ExampleDelaySynTask.java │ │ ├── ExampleAsynRunTask.java │ │ ├── ExampleAsynCallTask.java │ │ ├── ExampleServer.java │ │ ├── ExampleAsynCallbackTask.java │ │ ├── ExampleServerVerifyObj.java │ │ └── ExampleServerSocketListener.java ├── .project └── .classpath ├── ALBasicCommon ├── .classpath ├── src │ └── ALBasicCommon │ │ ├── ALBasicEnum.java │ │ ├── _AALBasicThread.java │ │ ├── ALConfReader.java │ │ └── ALBasicCommonFun.java └── .project └── ALBasicProtocol ├── .classpath ├── .project └── src └── BasicServer ├── S2C_BasicClientVerifyResult.java └── C2S_BasicClientVerifyInfo.java /readme.doc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alzq-zhf/ALBasicServer/HEAD/readme.doc -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ALBasicServer 2 | ============= 3 | 4 | Java基础服务器底层架构。 -- made by alzq.zhf 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .settings 2 | ./*/bin 3 | 4 | *.class 5 | 6 | # Package Files # 7 | *.jar 8 | *.war 9 | *.ear 10 | *.fatjar 11 | -------------------------------------------------------------------------------- /ALBasicProtocolPack/src/ALBasicProtocolPack/BasicObj/_IALProtocolReceiver.java: -------------------------------------------------------------------------------- 1 | package ALBasicProtocolPack.BasicObj; 2 | 3 | public interface _IALProtocolReceiver 4 | { 5 | 6 | } 7 | -------------------------------------------------------------------------------- /ALServerLog/conf/ALServerLog.properties: -------------------------------------------------------------------------------- 1 | #Print Log Level 2 | # DEBUG, 3 | # INFO, 4 | # WARNING, 5 | # ERROR, 6 | # FATAL, 7 | ALServerLog.LogLevel = INFO 8 | 9 | -------------------------------------------------------------------------------- /ALBasicClient/conf/ALServerLog.properties: -------------------------------------------------------------------------------- 1 | #Print Log Level 2 | # DEBUG, 3 | # INFO, 4 | # WARNING, 5 | # ERROR, 6 | # FATAL, 7 | ALServerLog.LogLevel = INFO 8 | 9 | -------------------------------------------------------------------------------- /ALBasicServer/conf/ALServerLog.properties: -------------------------------------------------------------------------------- 1 | #Print Log Level 2 | # DEBUG, 3 | # INFO, 4 | # WARNING, 5 | # ERROR, 6 | # FATAL, 7 | ALServerLog.LogLevel = INFO 8 | 9 | -------------------------------------------------------------------------------- /ExampleClient/conf/ALServerLog.properties: -------------------------------------------------------------------------------- 1 | #Print Log Level 2 | # DEBUG, 3 | # INFO, 4 | # WARNING, 5 | # ERROR, 6 | # FATAL, 7 | ALServerLog.LogLevel = INFO 8 | 9 | -------------------------------------------------------------------------------- /ExampleServer/conf/ALServerLog.properties: -------------------------------------------------------------------------------- 1 | #Print Log Level 2 | # DEBUG, 3 | # INFO, 4 | # WARNING, 5 | # ERROR, 6 | # FATAL, 7 | ALServerLog.LogLevel = INFO 8 | 9 | -------------------------------------------------------------------------------- /ALBasicClient/conf/ALBasicClientConf.properties: -------------------------------------------------------------------------------- 1 | 2 | #消息发送线程的数量 3 | ALBasicClient.SendThreadNum = 1 4 | #缓冲区长度 5 | ALBasicClient.RecSocketBufLen = 131072 6 | 7 | ################以上为基本客户端相关配置####################### 8 | 9 | -------------------------------------------------------------------------------- /ExampleClient/conf/ALBasicClientConf.properties: -------------------------------------------------------------------------------- 1 | 2 | #消息发送线程的数量 3 | ALBasicClient.SendThreadNum = 1 4 | #缓冲区长度 5 | ALBasicClient.RecSocketBufLen = 131072 6 | 7 | ################以上为基本客户端相关配置####################### 8 | 9 | -------------------------------------------------------------------------------- /ALBasicServer/src/ALBasicServer/ALBasicMutex/MutexAtom.java: -------------------------------------------------------------------------------- 1 | package ALBasicServer.ALBasicMutex; 2 | 3 | import ALBasicServer.ALThread.ALMutex; 4 | 5 | public class MutexAtom extends ALMutex 6 | { 7 | 8 | public MutexAtom() 9 | { 10 | super(40); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /ALBasicServer/src/ALBasicServer/ALBasicMutex/MutexManager.java: -------------------------------------------------------------------------------- 1 | package ALBasicServer.ALBasicMutex; 2 | 3 | import ALBasicServer.ALThread.ALMutex; 4 | 5 | public class MutexManager extends ALMutex 6 | { 7 | public MutexManager() 8 | { 9 | super(20); 10 | } 11 | 12 | } 13 | -------------------------------------------------------------------------------- /ALBasicServer/src/ALBasicServer/ALBasicMutex/MutexObject.java: -------------------------------------------------------------------------------- 1 | package ALBasicServer.ALBasicMutex; 2 | 3 | import ALBasicServer.ALThread.ALMutex; 4 | 5 | public class MutexObject extends ALMutex 6 | { 7 | 8 | public MutexObject() 9 | { 10 | super(30); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /ALBasicServer/src/ALBasicServer/ALBasicMutex/MutexInstance.java: -------------------------------------------------------------------------------- 1 | package ALBasicServer.ALBasicMutex; 2 | 3 | import ALBasicServer.ALThread.ALMutex; 4 | 5 | 6 | public class MutexInstance extends ALMutex 7 | { 8 | public MutexInstance() 9 | { 10 | super(10); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /ALBasicCommon/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /ExampleServer/src/ExampleServer/ExampleSynTask.java: -------------------------------------------------------------------------------- 1 | package ExampleServer; 2 | 3 | import ALBasicServer.ALTask._IALSynTask; 4 | import ALServerLog.ALServerLog; 5 | 6 | public class ExampleSynTask implements _IALSynTask { 7 | 8 | @Override 9 | public void run() { 10 | ALServerLog.Error("syn task"); 11 | } 12 | 13 | 14 | } 15 | -------------------------------------------------------------------------------- /ExampleServer/src/ExampleServer/ExampleDelaySynTask.java: -------------------------------------------------------------------------------- 1 | package ExampleServer; 2 | 3 | import ALBasicServer.ALTask._IALSynTask; 4 | import ALServerLog.ALServerLog; 5 | 6 | public class ExampleDelaySynTask implements _IALSynTask { 7 | 8 | @Override 9 | public void run() { 10 | ALServerLog.Error("syn delay task"); 11 | } 12 | 13 | 14 | } 15 | -------------------------------------------------------------------------------- /ExampleServer/src/ExampleServer/ExampleAsynRunTask.java: -------------------------------------------------------------------------------- 1 | package ExampleServer; 2 | 3 | import ALBasicServer.ALTask._IALAsynRunnableTask; 4 | import ALServerLog.ALServerLog; 5 | 6 | public class ExampleAsynRunTask implements _IALAsynRunnableTask { 7 | 8 | @Override 9 | public void run() { 10 | ALServerLog.Error("asyn run task"); 11 | } 12 | 13 | 14 | } 15 | -------------------------------------------------------------------------------- /ExampleServer/src/ExampleServer/ExampleAsynCallTask.java: -------------------------------------------------------------------------------- 1 | package ExampleServer; 2 | 3 | import ALBasicServer.ALTask._IALAsynCallTask; 4 | import ALServerLog.ALServerLog; 5 | 6 | public class ExampleAsynCallTask implements _IALAsynCallTask { 7 | 8 | @Override 9 | public Integer dealAsynTask() { 10 | ALServerLog.Error("asyn task"); 11 | 12 | return 3; 13 | } 14 | 15 | 16 | } 17 | -------------------------------------------------------------------------------- /ALBasicServer/src/ALBasicServer/ALTask/_AALAsynCallAndBackTask.java: -------------------------------------------------------------------------------- 1 | package ALBasicServer.ALTask; 2 | 3 | /********************** 4 | * 服务器架构中异步任务的执行集成了处理和回调接口使用 5 | * 6 | * @author alzq.z 7 | * @email zhuangfan@vip.163.com 8 | * @time Feb 18, 2013 10:53:01 PM 9 | */ 10 | public abstract class _AALAsynCallAndBackTask implements _IALAsynCallTask, _IALAsynCallBackTask 11 | { 12 | } 13 | -------------------------------------------------------------------------------- /ALServerLog/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ALBasicCommon/src/ALBasicCommon/ALBasicEnum.java: -------------------------------------------------------------------------------- 1 | package ALBasicCommon; 2 | 3 | public class ALBasicEnum 4 | { 5 | /************ 6 | * 表示线程状态的枚举 7 | * 8 | * @author alzq.z 9 | * @email zhuangfan@vip.163.com 10 | * @time Feb 20, 2013 10:41:51 PM 11 | */ 12 | public static enum ThreadStat 13 | { 14 | INIT, 15 | RUNNING, 16 | STOP, 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /ALBasicProtocol/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ALBasicServer/src/ALBasicServer/ALTask/_IALAsynRunnableTask.java: -------------------------------------------------------------------------------- 1 | package ALBasicServer.ALTask; 2 | 3 | /***************** 4 | * 服务器架构中异步的执行类任务接口类 5 | * 6 | * @author alzq.z 7 | * @email zhuangfan@vip.163.com 8 | * @time Feb 18, 2013 10:52:27 PM 9 | */ 10 | public interface _IALAsynRunnableTask 11 | { 12 | /******************* 13 | * 异步处理函数中的执行函数 14 | */ 15 | public abstract void run(); 16 | } 17 | -------------------------------------------------------------------------------- /ALBasicServer/src/ALBasicServer/ALTask/_IALSynTask.java: -------------------------------------------------------------------------------- 1 | package ALBasicServer.ALTask; 2 | 3 | /******************** 4 | * 服务器架构中的逻辑任务接口对象,需要进行任务操作的对象通过实现本接口的函数实现具体的函数操作过程。 5 | * 6 | * @author alzq.z 7 | * @email zhuangfan@vip.163.com 8 | * @time Feb 18, 2013 10:50:58 PM 9 | */ 10 | public interface _IALSynTask 11 | { 12 | /***************** 13 | * 任务的执行函数 14 | */ 15 | public void run(); 16 | } 17 | -------------------------------------------------------------------------------- /ALServerLog/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | ALServerLog 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.jdt.core.javanature 16 | 17 | 18 | -------------------------------------------------------------------------------- /ExampleServer/src/ExampleServer/ExampleServer.java: -------------------------------------------------------------------------------- 1 | package ExampleServer; 2 | 3 | import ALBasicServer.ALBasicServer; 4 | 5 | public class ExampleServer { 6 | 7 | /** 8 | * 示例服务器的开启主函数 9 | * @param args 10 | */ 11 | public static void main(String[] args) { 12 | //初始化基本服务器配置,并开启1个异步任务处理线程 13 | ALBasicServer.initBasicServer(1); 14 | 15 | //开始进行监听操作 16 | ALBasicServer.startListener(1001, 131072, new ExampleServerVerifyObj()); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /ALBasicClient/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | ALBasicClient 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.jdt.core.javanature 16 | 17 | 18 | -------------------------------------------------------------------------------- /ALBasicCommon/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | ALBasicCommon 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.jdt.core.javanature 16 | 17 | 18 | -------------------------------------------------------------------------------- /ALBasicServer/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | ALBasicServer 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.jdt.core.javanature 16 | 17 | 18 | -------------------------------------------------------------------------------- /ExampleClient/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | ExampleClient 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.jdt.core.javanature 16 | 17 | 18 | -------------------------------------------------------------------------------- /ExampleServer/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | ExampleServer 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.jdt.core.javanature 16 | 17 | 18 | -------------------------------------------------------------------------------- /ALBasicProtocol/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | ALBasicProtocol 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.jdt.core.javanature 16 | 17 | 18 | -------------------------------------------------------------------------------- /ALBasicServer/src/ALBasicServer/ALTask/_IALAsynCallTask.java: -------------------------------------------------------------------------------- 1 | package ALBasicServer.ALTask; 2 | 3 | /********************** 4 | * 服务器架构中异步任务的执行接口类,需要与回调配套使用 5 | * 6 | * @author alzq.z 7 | * @email zhuangfan@vip.163.com 8 | * @time Feb 18, 2013 10:53:01 PM 9 | */ 10 | public interface _IALAsynCallTask 11 | { 12 | /************************** 13 | * 异步任务中处理实际逻辑的处理函数 14 | * @return 15 | */ 16 | public abstract T dealAsynTask(); 17 | } 18 | -------------------------------------------------------------------------------- /ALBasicProtocolPack/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | ALBasicProtocolPack 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.jdt.core.javanature 16 | 17 | 18 | -------------------------------------------------------------------------------- /ALBasicServer/src/ALBasicServer/ALVerifyObj/_IALVerifyFun.java: -------------------------------------------------------------------------------- 1 | package ALBasicServer.ALVerifyObj; 2 | 3 | public interface _IALVerifyFun 4 | { 5 | /******************* 6 | * 验证用户身份并返回身份标识对象,此函数在异步处理中调用 7 | * 8 | * @author alzq.z 9 | * @time Feb 19, 2013 4:18:12 PM 10 | */ 11 | public abstract void verifyIdentity(ALVerifyDealerObj _verifyDealer, int _clientType, String _userName 12 | , String _userPassword, String _customMsg); 13 | } 14 | -------------------------------------------------------------------------------- /ExampleClient/src/ExampleClient/ExampleClient.java: -------------------------------------------------------------------------------- 1 | package ExampleClient; 2 | 3 | import ALBasicClient.ALBasicClient; 4 | 5 | public class ExampleClient { 6 | 7 | /** 8 | * @param args 9 | */ 10 | public static void main(String[] args) { 11 | //初始化基本客户端配置相关 12 | ALBasicClient.init(); 13 | 14 | //创建客户端对象并进行连接 15 | ExampleClientConnecter connecter = new ExampleClientConnecter("127.0.0.1", 1001); 16 | connecter.login(1, "", "", "custom msg ...~"); 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /ALBasicProtocolPack/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ALBasicServer/conf/ALBasicServerConf.properties: -------------------------------------------------------------------------------- 1 | #服务器标志字符串 2 | ALBasicServer.ServerTag = ALBasicServer 3 | #同步任务执行的线程数量 4 | ALBasicServer.SynTaskDealThreadNum = 4 5 | #Socket信息发送线程数量 6 | ALBasicServer.ServerSendBackDealThreadNum = 1 7 | #定时任务的时间精度 8 | ALBasicServer.TimerCheckTime = 20 9 | #定时任务的大区间长度,根据精度和长度可以决定一个区间的时间跨度 10 | ALBasicServer.TimerCheckAreaSize = 5000 11 | #是否检测线程加锁等级合法性 12 | ALBasicServer.CheckMutex = true 13 | 14 | ################以上为ALBasicServer服务器基础配置####################### 15 | 16 | 17 | -------------------------------------------------------------------------------- /ExampleServer/src/ExampleServer/ExampleAsynCallbackTask.java: -------------------------------------------------------------------------------- 1 | package ExampleServer; 2 | 3 | import ALBasicServer.ALTask._IALAsynCallBackTask; 4 | import ALServerLog.ALServerLog; 5 | 6 | public class ExampleAsynCallbackTask implements _IALAsynCallBackTask { 7 | 8 | @Override 9 | public void dealFail() { 10 | ALServerLog.Error("asyn task fail"); 11 | } 12 | 13 | @Override 14 | public void dealSuc(Integer arg0) { 15 | ALServerLog.Error("asyn task suc: " + arg0); 16 | } 17 | 18 | 19 | } 20 | -------------------------------------------------------------------------------- /ALBasicServer/src/ALBasicServer/ALServerCmd/_IALBasicServerCmdDealer.java: -------------------------------------------------------------------------------- 1 | package ALBasicServer.ALServerCmd; 2 | 3 | /******************** 4 | * 接收系统命令行处输入的文字,并进行相关处理的处理类 5 | * 6 | * @author alzq.z 7 | * @email zhuangfan@vip.163.com 8 | * @time Oct 5, 2013 11:04:32 AM 9 | */ 10 | public interface _IALBasicServerCmdDealer 11 | { 12 | /********************* 13 | * 根据输入的命令行进行处理 14 | * 15 | * @author alzq.z 16 | * @time Oct 5, 2013 11:05:24 AM 17 | */ 18 | public abstract void dealCmd(String _cmd); 19 | } 20 | -------------------------------------------------------------------------------- /ExampleServer/conf/ALBasicServerConf.properties: -------------------------------------------------------------------------------- 1 | #服务器标志字符串 2 | ALBasicServer.ServerTag = ALBasicServer 3 | #同步任务执行的线程数量 4 | ALBasicServer.SynTaskDealThreadNum = 4 5 | #Socket信息发送线程数量 6 | ALBasicServer.ServerSendBackDealThreadNum = 1 7 | #定时任务的时间精度 8 | ALBasicServer.TimerCheckTime = 50 9 | #是否检测线程加锁等级合法性 10 | ALBasicServer.CheckMutex = true 11 | #服务器开启监听端口 12 | ALBasicServer.ServerPort = 1001 13 | #服务器Socket端口接收缓冲区字节长度 14 | ALBasicServer.ServerSocketBufLen = 131072 15 | 16 | ################以上为ALBasicServer服务器基础配置####################### 17 | 18 | 19 | -------------------------------------------------------------------------------- /ALBasicServer/src/ALBasicServer/ALServerCmd/ALSynCmdDealTask.java: -------------------------------------------------------------------------------- 1 | package ALBasicServer.ALServerCmd; 2 | 3 | import ALBasicServer.ALTask._IALSynTask; 4 | 5 | /********************* 6 | * 处理命令行中输入的命令的具体执行任务 7 | * 8 | * @author alzq.z 9 | * @email zhuangfan@vip.163.com 10 | * @time Oct 5, 2013 11:25:03 AM 11 | */ 12 | public class ALSynCmdDealTask implements _IALSynTask 13 | { 14 | 15 | @Override 16 | public void run() 17 | { 18 | //执行命令行的处理操作 19 | ALCmdDealerManager.getInstance()._dealCmd(); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /ALBasicServer/src/ALBasicServer/ALSocket/SynDelaySendTask.java: -------------------------------------------------------------------------------- 1 | package ALBasicServer.ALSocket; 2 | 3 | import ALBasicServer.ALTask._IALSynTask; 4 | 5 | /****************** 6 | * 当对应Socket无法发送数据时,使用此任务延迟加入发送队列 7 | * @author alzq 8 | * 9 | */ 10 | public class SynDelaySendTask implements _IALSynTask 11 | { 12 | private ALBasicServerSocket socket; 13 | 14 | public SynDelaySendTask(ALBasicServerSocket _socket) 15 | { 16 | socket = _socket; 17 | } 18 | 19 | @Override 20 | public void run() 21 | { 22 | ALServerSendSocketMgr.getInstance().addSendSocket(socket); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /ALBasicClient/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /ALBasicServer/src/ALBasicServer/ALTask/_IALAsynCallBackTask.java: -------------------------------------------------------------------------------- 1 | package ALBasicServer.ALTask; 2 | 3 | 4 | /****************** 5 | * 服务器架构中异步任务的回调执行接口类,需要与异步任务的执行接口类一同使用 6 | * 7 | * @author alzq.z 8 | * @email zhuangfan@vip.163.com 9 | * @time Feb 18, 2013 10:54:14 PM 10 | */ 11 | public interface _IALAsynCallBackTask 12 | { 13 | /**************** 14 | * 异步成功后的回调处理函数 15 | * 16 | * @author alzq.z 17 | * @time Feb 18, 2013 10:54:44 PM 18 | */ 19 | public abstract void dealSuc(T _obj); 20 | 21 | /***************** 22 | * 异步处理失败后的回调处理函数 23 | * @param _obj 24 | */ 25 | public abstract void dealFail(); 26 | } 27 | -------------------------------------------------------------------------------- /ExampleServer/src/ExampleServer/ExampleServerVerifyObj.java: -------------------------------------------------------------------------------- 1 | package ExampleServer; 2 | 3 | import ALBasicServer.ALVerifyObj.ALVerifyDealerObj; 4 | import ALBasicServer.ALVerifyObj._IALVerifyFun; 5 | import ALServerLog.ALServerLog; 6 | 7 | public class ExampleServerVerifyObj implements _IALVerifyFun { 8 | 9 | @Override 10 | public void verifyIdentity(ALVerifyDealerObj _verifyDealer, int _clientType, String _userName 11 | , String _userPassword, String _customMsg) { 12 | 13 | ALServerLog.Error("Rec Verify Custom Message: " + _customMsg); 14 | 15 | //示例不进行验证,直接返回客户端处理对象 16 | _verifyDealer.comfirmResult(new ExampleServerSocketListener()); 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /ALBasicServer/src/ALBasicServer/ALSocket/SynReceiveMessageTask.java: -------------------------------------------------------------------------------- 1 | package ALBasicServer.ALSocket; 2 | 3 | import ALBasicServer.ALTask._IALSynTask; 4 | 5 | 6 | public class SynReceiveMessageTask implements _IALSynTask 7 | { 8 | private ALBasicServerSocket _m_csSocket; 9 | 10 | public SynReceiveMessageTask(ALBasicServerSocket _socket) 11 | { 12 | _m_csSocket = _socket; 13 | } 14 | 15 | @Override 16 | public void run() 17 | { 18 | if(null == _m_csSocket) 19 | return ; 20 | 21 | //处理消息队列中第一个消息 22 | //在任务中处理不占用发送接收线程 23 | //同时不事先把消息取出可以保证消息处理的有序性 24 | _m_csSocket._dealRecMessage(); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /ALBasicServer/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /ALBasicServer/src/ALBasicServer/ALVerifyObj/SynCheckVerifyLoginTimeOutTask.java: -------------------------------------------------------------------------------- 1 | package ALBasicServer.ALVerifyObj; 2 | 3 | import ALBasicServer.ALTask._IALSynTask; 4 | 5 | /******************* 6 | * 验证指定验证序列号的验证操作是否完成,未完成则直接按照失败处理 7 | * 8 | * @author alzq.z 9 | * @email zhuangfan@vip.163.com 10 | * @time Feb 19, 2013 2:41:06 PM 11 | */ 12 | public class SynCheckVerifyLoginTimeOutTask implements _IALSynTask 13 | { 14 | private int serialize; 15 | 16 | public SynCheckVerifyLoginTimeOutTask(int _serialize) 17 | { 18 | serialize = _serialize; 19 | } 20 | 21 | @Override 22 | public void run() 23 | { 24 | ALVerifyObjMgr.getInstance()._comfirmVerifyResult(serialize, null); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /ALBasicServer/src/ALBasicClient/ALSynServerClientDealMessageTask.java: -------------------------------------------------------------------------------- 1 | package ALBasicClient; 2 | 3 | import ALBasicServer.ALTask._IALSynTask; 4 | 5 | /**************** 6 | * 客户端消息接收对象的消息处理任务对象 7 | * 8 | * @author alzq.z 9 | * @email zhuangfan@vip.163.com 10 | * @time Mar 4, 2013 10:28:39 PM 11 | */ 12 | public class ALSynServerClientDealMessageTask implements _IALSynTask 13 | { 14 | private _AALBasicServerClientListener clientListener; 15 | 16 | public ALSynServerClientDealMessageTask(_AALBasicServerClientListener _clientListener) 17 | { 18 | clientListener = _clientListener; 19 | } 20 | 21 | @Override 22 | public void run() 23 | { 24 | if(null == clientListener) 25 | return ; 26 | 27 | clientListener.dealMessage(); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /ALBasicServer/src/ALBasicServer/ALSocket/SynDisconnectTask.java: -------------------------------------------------------------------------------- 1 | package ALBasicServer.ALSocket; 2 | 3 | import ALBasicServer.ALTask._IALSynTask; 4 | 5 | public class SynDisconnectTask implements _IALSynTask 6 | { 7 | private ALBasicServerSocket _m_csSocket; 8 | 9 | public SynDisconnectTask(ALBasicServerSocket _socket) 10 | { 11 | _m_csSocket = _socket; 12 | } 13 | 14 | @Override 15 | public void run() 16 | { 17 | if(null == _m_csSocket) 18 | return ; 19 | 20 | _AALBasicServerSocketListener listener = _m_csSocket.getListener(); 21 | 22 | if(null == listener) 23 | return ; 24 | 25 | listener.disconnect(); 26 | 27 | //设置Socket为NULL 28 | listener.setSocket(null); 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /ExampleClient/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /ExampleServer/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /ALBasicServer/src/ALBasicServer/ALVerifyObj/ALVerifyDealerObj.java: -------------------------------------------------------------------------------- 1 | package ALBasicServer.ALVerifyObj; 2 | 3 | import ALBasicServer.ALSocket._AALBasicServerSocketListener; 4 | 5 | /******************** 6 | * 处理结果的对象,用户可以不必了解内部机制的序列号等对象直接操作一个函数确认验证结果 7 | * 8 | * @author alzq.z 9 | * @email zhuangfan@vip.163.com 10 | * @time Feb 19, 2013 4:20:56 PM 11 | */ 12 | public class ALVerifyDealerObj 13 | { 14 | private int verifySerialize; 15 | 16 | public ALVerifyDealerObj(int _serialize) 17 | { 18 | verifySerialize = _serialize; 19 | } 20 | 21 | /****************** 22 | * 确认结果 23 | * 24 | * @author alzq.z 25 | * @time Feb 19, 2013 4:20:44 PM 26 | */ 27 | public void comfirmResult(_AALBasicServerSocketListener _listener) 28 | { 29 | ALVerifyObjMgr.getInstance()._comfirmVerifyResult(verifySerialize, _listener); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /ALBasicProtocolPack/src/ALBasicProtocolPack/_IALProtocolStructure.java: -------------------------------------------------------------------------------- 1 | package ALBasicProtocolPack; 2 | 3 | import java.nio.ByteBuffer; 4 | 5 | /**************** 6 | * 协议处理的消息类对象的接口类 7 | * 8 | * @author alzq.z 9 | * @time Feb 19, 2013 10:51:53 AM 10 | */ 11 | public interface _IALProtocolStructure 12 | { 13 | /****************** 14 | * 获取主协议编号 15 | * 16 | * @author alzq.z 17 | * @time Jan 15, 2013 9:53:29 PM 18 | */ 19 | public byte getMainOrder(); 20 | /******************* 21 | * 获取副协议编号 22 | * 23 | * @author alzq.z 24 | * @time Jan 15, 2013 9:53:41 PM 25 | */ 26 | public byte getSubOrder(); 27 | 28 | public int GetUnzipBufSize(); 29 | 30 | public int GetZipBufSize(); 31 | 32 | /********** 33 | * 创建完整的数据包,包含协议处理编号部分 34 | * 35 | * @author alzq.z 36 | * @time Feb 25, 2013 10:56:58 PM 37 | */ 38 | public ByteBuffer makeFullPackage(); 39 | public ByteBuffer makePackage(); 40 | public void readPackage(ByteBuffer _buf); 41 | } 42 | -------------------------------------------------------------------------------- /ALBasicServer/src/ALBasicServer/ALServerAsynTask/SynAsynCallBackTask.java: -------------------------------------------------------------------------------- 1 | package ALBasicServer.ALServerAsynTask; 2 | 3 | import ALBasicServer.ALTask._IALAsynCallBackTask; 4 | import ALBasicServer.ALTask._IALSynTask; 5 | 6 | public class SynAsynCallBackTask implements _IALSynTask 7 | { 8 | private T _m_OBJ; 9 | private _IALAsynCallBackTask _m_CallBackTask; 10 | 11 | public SynAsynCallBackTask(T _obj, _IALAsynCallBackTask _callBackTask) 12 | { 13 | _m_OBJ = _obj; 14 | _m_CallBackTask = _callBackTask; 15 | } 16 | 17 | @Override 18 | public void run() 19 | { 20 | if(null == _m_OBJ) 21 | _m_CallBackTask.dealFail(); 22 | else 23 | { 24 | try 25 | { 26 | _m_CallBackTask.dealSuc(_m_OBJ); 27 | } 28 | catch (Exception e) 29 | { 30 | //回调过程中错误则当作失败处理 31 | e.printStackTrace(); 32 | _m_CallBackTask.dealFail(); 33 | } 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /ALBasicClient/src/ALBasicClient/ALBasicClientSendThreadMgr.java: -------------------------------------------------------------------------------- 1 | package ALBasicClient; 2 | 3 | 4 | /*********************** 5 | * 客户端对象发送消息的线程控制管理对象 6 | * 7 | * @author alzq.z 8 | * @email zhuangfan@vip.163.com 9 | * @time Feb 19, 2013 9:53:09 PM 10 | */ 11 | public class ALBasicClientSendThreadMgr 12 | { 13 | private static ALBasicClientSendThreadMgr g_instance = new ALBasicClientSendThreadMgr(); 14 | 15 | public static ALBasicClientSendThreadMgr getInstance() 16 | { 17 | if(null == g_instance) 18 | g_instance = new ALBasicClientSendThreadMgr(); 19 | 20 | return g_instance; 21 | } 22 | 23 | protected ALBasicClientSendThreadMgr() 24 | { 25 | } 26 | 27 | /*************** 28 | * 开启Socket发送线程 29 | * 30 | * @author alzq.z 31 | * @time Feb 19, 2013 9:53:49 PM 32 | */ 33 | public void createSocketSendThread() 34 | { 35 | CosClientSocketSendThread socketSendThread = new CosClientSocketSendThread(); 36 | //开启线程 37 | socketSendThread.start(); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /ExampleClient/src/ExampleClient/ExampleClientConnecter.java: -------------------------------------------------------------------------------- 1 | package ExampleClient; 2 | 3 | import java.nio.ByteBuffer; 4 | 5 | import ALBasicClient._AALBasicServerClientListener; 6 | import ALBasicCommon.ALBasicCommonFun; 7 | import ALServerLog.ALServerLog; 8 | 9 | public class ExampleClientConnecter extends _AALBasicServerClientListener { 10 | 11 | public ExampleClientConnecter(String _serverIP, int _serverPort) { 12 | super(_serverIP, _serverPort); 13 | } 14 | 15 | @Override 16 | public void ConnectFail() { 17 | ALServerLog.Error("ConnectFail"); 18 | } 19 | 20 | @Override 21 | public void Disconnect() { 22 | ALServerLog.Error("Disconnect"); 23 | } 24 | 25 | @Override 26 | public void LoginFail() { 27 | ALServerLog.Error("LoginFail"); 28 | } 29 | 30 | @Override 31 | public void LoginSuc(String _customMsg) { 32 | ALServerLog.Error("LoginSuc"); 33 | 34 | //send test msg 35 | send(ALBasicCommonFun.getStringBuf("client message")); 36 | } 37 | 38 | @Override 39 | public void _dealMes(ByteBuffer _msg) 40 | { 41 | ALServerLog.Error("receiveMes: " + ALBasicCommonFun.getString(_msg)); 42 | } 43 | 44 | 45 | } 46 | -------------------------------------------------------------------------------- /ALBasicCommon/src/ALBasicCommon/_AALBasicThread.java: -------------------------------------------------------------------------------- 1 | package ALBasicCommon; 2 | 3 | import ALBasicCommon.ALBasicEnum.ThreadStat; 4 | 5 | /******************** 6 | * 本函数包中基本的线程类对象 7 | * 8 | * @author alzq.z 9 | * @email zhuangfan@vip.163.com 10 | * @time Feb 20, 2013 10:44:51 PM 11 | */ 12 | public abstract class _AALBasicThread extends Thread 13 | { 14 | /** 线程状态 */ 15 | private ThreadStat _m_eThreadStat; 16 | 17 | public _AALBasicThread() 18 | { 19 | _m_eThreadStat = ThreadStat.INIT; 20 | } 21 | 22 | public ThreadStat getThreadStat() {return _m_eThreadStat;} 23 | 24 | /****************** 25 | * 线程执行函数 26 | * 27 | * @author alzq.z 28 | * @time Feb 20, 2013 10:46:17 PM 29 | */ 30 | public final void run() 31 | { 32 | _m_eThreadStat = ThreadStat.RUNNING; 33 | 34 | _run(); 35 | 36 | _m_eThreadStat = ThreadStat.STOP; 37 | } 38 | 39 | /**************** 40 | * 需要重载的线程执行体 41 | * 42 | * @author alzq.z 43 | * @time Feb 20, 2013 10:46:45 PM 44 | */ 45 | protected abstract void _run(); 46 | } 47 | -------------------------------------------------------------------------------- /ALBasicServer/src/ALBasicServer/ALSocket/ALServerSocketSendThread.java: -------------------------------------------------------------------------------- 1 | package ALBasicServer.ALSocket; 2 | 3 | import ALBasicCommon._AALBasicThread; 4 | 5 | 6 | 7 | /************************ 8 | * 端口发送线程对象 9 | * @author alzq 10 | * 11 | */ 12 | public class ALServerSocketSendThread extends _AALBasicThread 13 | { 14 | /** 线程是否退出 */ 15 | private boolean _m_bThreadExit; 16 | 17 | public ALServerSocketSendThread() 18 | { 19 | _m_bThreadExit = false; 20 | } 21 | 22 | public void ExitThread() 23 | { 24 | _m_bThreadExit = true; 25 | } 26 | 27 | /****************** 28 | * 线程执行函数 29 | * 30 | * @author alzq.z 31 | * @time Feb 20, 2013 11:05:14 PM 32 | */ 33 | protected void _run() 34 | { 35 | while(!_m_bThreadExit) 36 | { 37 | //循环获取对象发送 38 | ALBasicServerSocket socket = ALServerSendSocketMgr.getInstance().popSendSocket(); 39 | 40 | if(null != socket) 41 | { 42 | //发送 43 | socket._realSendMessage(); 44 | } 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /ALBasicClient/src/ALBasicClient/ALBasicClient.java: -------------------------------------------------------------------------------- 1 | package ALBasicClient; 2 | 3 | import ALServerLog.ALServerLog; 4 | 5 | public class ALBasicClient 6 | { 7 | /** 是否成功初始化 */ 8 | private static boolean g_inited = false; 9 | 10 | /************************ 11 | * 初始化相关客户端环境 12 | */ 13 | public static void init() 14 | { 15 | if(g_inited) 16 | { 17 | ALServerLog.Fatal("Please don't try to repeat init AL Basic Client model!!"); 18 | new Exception().printStackTrace(); 19 | return ; 20 | } 21 | 22 | g_inited = true; 23 | 24 | if(ALBasicClientConf.getInstance().init()) 25 | { 26 | //初始化日志配置 27 | ALServerLog.initALServerLog(); 28 | 29 | //开启对应的端口发送执行线程 30 | ALServerLog.Fatal("Start Client Socket Send Thread Count - " + ALBasicClientConf.getInstance().getSendThreadNum()); 31 | for(int i = 0; i < ALBasicClientConf.getInstance().getSendThreadNum(); i++) 32 | { 33 | ALBasicClientSendThreadMgr.getInstance().createSocketSendThread(); 34 | } 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /ALBasicServer/src/ALBasicServer/ALVerifyObj/AsynRun_UserLoginTask.java: -------------------------------------------------------------------------------- 1 | package ALBasicServer.ALVerifyObj; 2 | 3 | import ALBasicServer.ALSocket.ALBasicServerSocket; 4 | import ALBasicServer.ALTask._IALAsynRunnableTask; 5 | 6 | 7 | /**************** 8 | * 用户登录的异步处理函数 9 | * @author alzq 10 | * 11 | */ 12 | public class AsynRun_UserLoginTask implements _IALAsynRunnableTask 13 | { 14 | private ALVerifyDealerObj _m_vdVerifyDealer; 15 | private ALBasicServerSocket _m_ssSocketObj; 16 | 17 | public AsynRun_UserLoginTask(int _serialize, ALBasicServerSocket _socketObj) 18 | { 19 | _m_vdVerifyDealer = new ALVerifyDealerObj(_serialize); 20 | _m_ssSocketObj = _socketObj; 21 | } 22 | 23 | @Override 24 | public void run() 25 | { 26 | //获取验证对象 27 | _IALVerifyFun verifyFun = ALVerifyObjMgr.getInstance().getVerifyObj(_m_ssSocketObj.getVerifyObjIdx()); 28 | if(null == verifyFun) 29 | return ; 30 | 31 | verifyFun.verifyIdentity(_m_vdVerifyDealer, _m_ssSocketObj.getLoginClientType(), _m_ssSocketObj.getUserName() 32 | , _m_ssSocketObj.getUserPassword(), _m_ssSocketObj.getLoginCustomMsg()); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /ALBasicClient/src/ALBasicClient/CosClientSocketSendThread.java: -------------------------------------------------------------------------------- 1 | package ALBasicClient; 2 | 3 | import ALBasicCommon._AALBasicThread; 4 | 5 | /************************ 6 | * 消息发送线程对象 7 | * 8 | * @author alzq.z 9 | * @email zhuangfan@vip.163.com 10 | * @time Feb 19, 2013 9:54:05 PM 11 | */ 12 | public class CosClientSocketSendThread extends _AALBasicThread 13 | { 14 | /** 线程是否退出 */ 15 | private boolean _m_bThreadExit; 16 | 17 | public CosClientSocketSendThread() 18 | { 19 | _m_bThreadExit = false; 20 | } 21 | 22 | public void ExitThread() 23 | { 24 | _m_bThreadExit = true; 25 | } 26 | 27 | /****************** 28 | * 线程执行函数 29 | * 30 | * @author alzq.z 31 | * @time Feb 20, 2013 11:04:34 PM 32 | */ 33 | @Override 34 | protected void _run() 35 | { 36 | while(!_m_bThreadExit) 37 | { 38 | //循环获取对象发送 39 | ALBasicClientSocket socket = ALBasicSendingClientManager.getInstance().popSendSocket(); 40 | 41 | if(null != socket) 42 | { 43 | //发送 44 | socket._realSendMessage(); 45 | } 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /ALBasicServer/src/ALBasicServer/ALServerCmd/ALCmdLineReadThread.java: -------------------------------------------------------------------------------- 1 | package ALBasicServer.ALServerCmd; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.IOException; 5 | import java.io.InputStreamReader; 6 | 7 | import ALBasicCommon._AALBasicThread; 8 | 9 | /********************** 10 | * 命令行的读取线程 11 | * 12 | * @author alzq.z 13 | * @email zhuangfan@vip.163.com 14 | * @time Oct 5, 2013 12:15:14 PM 15 | */ 16 | public class ALCmdLineReadThread extends _AALBasicThread 17 | { 18 | /****************** 19 | * 线程执行函数 20 | * 21 | * @author alzq.z 22 | * @time Feb 20, 2013 11:05:54 PM 23 | */ 24 | @Override 25 | protected void _run() 26 | { 27 | //获取读取对象 28 | BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); 29 | String cmd = null; 30 | 31 | while(true) 32 | { 33 | try 34 | { 35 | cmd = reader.readLine(); 36 | } 37 | catch (IOException e) 38 | { 39 | e.printStackTrace(); 40 | continue; 41 | } 42 | 43 | //添加处理对象 44 | ALCmdDealerManager.getInstance().addCmd(cmd); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /ExampleServer/src/ExampleServer/ExampleServerSocketListener.java: -------------------------------------------------------------------------------- 1 | package ExampleServer; 2 | 3 | import java.nio.ByteBuffer; 4 | 5 | import ALBasicCommon.ALBasicCommonFun; 6 | import ALBasicServer.ALServerAsynTask.ALAsynTaskManager; 7 | import ALBasicServer.ALServerSynTask.ALSynTaskManager; 8 | import ALBasicServer.ALSocket._AALBasicServerSocketListener; 9 | import ALServerLog.ALServerLog; 10 | 11 | public class ExampleServerSocketListener extends _AALBasicServerSocketListener { 12 | 13 | @Override 14 | public void disconnect() { 15 | ALServerLog.Error("disconnect"); 16 | } 17 | 18 | @Override 19 | public void login() { 20 | ALServerLog.Error("login"); 21 | } 22 | 23 | @Override 24 | public void receiveMsg(ByteBuffer arg0) { 25 | ALServerLog.Error("receiveMsg: " + ALBasicCommonFun.getString(arg0)); 26 | 27 | //开启逻辑任务 28 | ALSynTaskManager.getInstance().regTask(new ExampleSynTask()); 29 | 30 | //开启延迟逻辑任务 31 | ALSynTaskManager.getInstance().regTask(new ExampleDelaySynTask(), 3000); 32 | 33 | //开启异步任务,2种方式 34 | ALAsynTaskManager.getInstance().regTask(0, new ExampleAsynRunTask()); 35 | ALAsynTaskManager.getInstance().regTask(0, new ExampleAsynCallTask(), new ExampleAsynCallbackTask()); 36 | 37 | //返回消息 38 | send(ALBasicCommonFun.getStringBuf("server message")); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /ALBasicServer/src/ALBasicServer/ALServerSynTask/ALSynTimingTaskCheckThread.java: -------------------------------------------------------------------------------- 1 | package ALBasicServer.ALServerSynTask; 2 | 3 | import java.util.LinkedList; 4 | 5 | import ALBasicCommon._AALBasicThread; 6 | import ALBasicServer.ALTask._IALSynTask; 7 | 8 | public class ALSynTimingTaskCheckThread extends _AALBasicThread 9 | { 10 | /** 线程是否退出 */ 11 | private boolean _m_bThreadExit; 12 | private int _m_iCheckTime; 13 | 14 | public ALSynTimingTaskCheckThread() 15 | { 16 | _m_bThreadExit = false; 17 | _m_iCheckTime = ALSynTaskManager.getInstance().getTaskCheckTime(); 18 | } 19 | 20 | public void exitThread() 21 | { 22 | _m_bThreadExit = true; 23 | } 24 | 25 | /****************** 26 | * 线程执行函数 27 | * 28 | * @author alzq.z 29 | * @time Feb 20, 2013 11:05:35 PM 30 | */ 31 | @Override 32 | protected void _run() 33 | { 34 | //用于存放需要处理的任务的队列 35 | LinkedList<_IALSynTask> popTaskList = new LinkedList<_IALSynTask>(); 36 | 37 | while(!_m_bThreadExit) 38 | { 39 | //获取需要处理的所有任务队列的队列 40 | ALSynTaskManager.getInstance()._popTimerTask(popTaskList); 41 | 42 | //逐个任务的插入到当前任务队列中 43 | ALSynTaskManager.getInstance()._registerTaskList(popTaskList); 44 | 45 | //休眠指定精度时间 46 | try { 47 | sleep(_m_iCheckTime); 48 | } catch (InterruptedException e) {} 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /ALBasicServer/src/ALBasicServer/ALThread/ALMutexInfo.java: -------------------------------------------------------------------------------- 1 | package ALBasicServer.ALThread; 2 | 3 | public class ALMutexInfo 4 | { 5 | /** 对应锁的对象 */ 6 | private ALMutex _m_iCosObject; 7 | /** 加锁次数 */ 8 | private int _m_iLockTime; 9 | 10 | public ALMutexInfo(ALMutex _cosObj) 11 | { 12 | _m_iCosObject = _cosObj; 13 | _m_iLockTime = 0; 14 | } 15 | 16 | /************* 17 | * 获取锁等级 18 | * @return 19 | */ 20 | public int getMutexPriority() 21 | { 22 | return _m_iCosObject.getPriority(); 23 | } 24 | 25 | /************* 26 | * 获取锁次数 27 | * @return 28 | */ 29 | public int getLockTime() 30 | { 31 | return _m_iLockTime; 32 | } 33 | 34 | /************** 35 | * 增加锁次数 36 | */ 37 | public void addLockTime() 38 | { 39 | _m_iLockTime++; 40 | } 41 | 42 | /************** 43 | * 减少锁次数 44 | */ 45 | public void reduceLockTime() 46 | { 47 | _m_iLockTime--; 48 | } 49 | 50 | /*************** 51 | * 根据记录释放所有锁 52 | */ 53 | public void releaseAllLock() 54 | { 55 | while(_m_iLockTime > 0) 56 | { 57 | if(null != _m_iCosObject) 58 | _m_iCosObject.unlock(); 59 | 60 | reduceLockTime(); 61 | } 62 | } 63 | 64 | /************** 65 | * 获取加锁对象 66 | * @return 67 | */ 68 | public ALMutex getObj() 69 | { 70 | return _m_iCosObject; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /ALBasicServer/src/ALBasicServer/ALServerAsynTask/ALAsynTaskThread.java: -------------------------------------------------------------------------------- 1 | package ALBasicServer.ALServerAsynTask; 2 | 3 | import ALBasicCommon._AALBasicThread; 4 | 5 | 6 | /************************ 7 | * 异步任务处理线程函数体 8 | * @author alzq 9 | * 10 | */ 11 | public class ALAsynTaskThread extends _AALBasicThread 12 | { 13 | /** 线程是否退出 */ 14 | private boolean _m_bThreadExit; 15 | /** 本线程内任务处理对象 */ 16 | private ALAsynThreadTaskManager _m_tmTaskManager; 17 | 18 | public ALAsynTaskThread() 19 | { 20 | _m_bThreadExit = false; 21 | _m_tmTaskManager = new ALAsynThreadTaskManager(); 22 | } 23 | 24 | public void exitThread() 25 | { 26 | _m_bThreadExit = true; 27 | } 28 | 29 | /************* 30 | * 获取任务管理对象 31 | * 32 | * @author alzq.z 33 | * @time Feb 20, 2013 10:43:20 PM 34 | */ 35 | protected ALAsynThreadTaskManager _getTaskManager() 36 | { 37 | return _m_tmTaskManager; 38 | } 39 | 40 | /****************** 41 | * 线程执行函数 42 | * 43 | * @author alzq.z 44 | * @time Feb 20, 2013 10:48:09 PM 45 | */ 46 | @Override 47 | protected void _run() 48 | { 49 | while(!_m_bThreadExit) 50 | { 51 | //每次获取第一个可执行任务进行处理 52 | @SuppressWarnings("rawtypes") 53 | ALAsynTaskInfo info = _m_tmTaskManager.popFirstAsynTask(); 54 | 55 | if(null != info) 56 | { 57 | info.run(); 58 | } 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /ALBasicServer/src/ALBasicServer/ALServerSynTask/ALSynTimingTaskNodeFarDelayTaskInfo.java: -------------------------------------------------------------------------------- 1 | package ALBasicServer.ALServerSynTask; 2 | 3 | import java.util.LinkedList; 4 | 5 | import ALBasicServer.ALTask._IALSynTask; 6 | 7 | /******************* 8 | * 定时任务的划片集合节点中,不再本回合区域内的任务节点集合信息 9 | * 10 | * @author alzq.z 11 | * @email zhuangfan@vip.163.com 12 | * @time Jul 16, 2015 10:57:02 PM 13 | */ 14 | public class ALSynTimingTaskNodeFarDelayTaskInfo 15 | { 16 | /** 对应回合标记 */ 17 | private int _m_iRound; 18 | /** 任务对象 */ 19 | private LinkedList<_IALSynTask> _m_stSynTaskList; 20 | 21 | public ALSynTimingTaskNodeFarDelayTaskInfo(int _round) 22 | { 23 | _m_iRound = _round; 24 | _m_stSynTaskList = new LinkedList<_IALSynTask>(); 25 | } 26 | 27 | public int getRound() {return _m_iRound;} 28 | 29 | /*************** 30 | * 向本节点中插入任务 31 | * 32 | * @author alzq.z 33 | * @time Jul 16, 2015 11:41:12 PM 34 | */ 35 | public void addSynTask(_IALSynTask _task) 36 | { 37 | if(null == _task) 38 | return ; 39 | 40 | _m_stSynTaskList.addLast(_task); 41 | } 42 | 43 | /*************** 44 | * 将所有延迟任务放入到接收队列中 45 | * 46 | * @author alzq.z 47 | * @time Jul 16, 2015 11:39:28 PM 48 | */ 49 | public void popAllSynTask(LinkedList<_IALSynTask> _recList) 50 | { 51 | if(null == _recList) 52 | return ; 53 | 54 | while(!_m_stSynTaskList.isEmpty()) 55 | { 56 | _recList.addLast(_m_stSynTaskList.pop()); 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /ALBasicProtocolPack/src/ALBasicProtocolPack/BasicObj/_AALBasicProtocolSubOrderDealer.java: -------------------------------------------------------------------------------- 1 | package ALBasicProtocolPack.BasicObj; 2 | 3 | import java.nio.ByteBuffer; 4 | 5 | import ALBasicProtocolPack._IALProtocolStructure; 6 | 7 | 8 | /********************** 9 | * 协议处理类,使用模板方式定义,可直接生成对应的消息结构体并进行处理 10 | * 11 | * @author alzq.z 12 | * @email zhuangfan@vip.163.com 13 | * @time Feb 19, 2013 10:56:34 AM 14 | */ 15 | public abstract class _AALBasicProtocolSubOrderDealer 16 | { 17 | /** 实例化对象,用于获取信息使用 */ 18 | private T basicInfoObj; 19 | 20 | public _AALBasicProtocolSubOrderDealer() 21 | { 22 | basicInfoObj = _createProtocolObj(); 23 | } 24 | 25 | /********************* 26 | * 消息带入的处理函数,将协议从字节中读取出并带入实际处理函数 27 | * 28 | * @author alzq.z 29 | * @time Feb 19, 2013 10:52:19 AM 30 | */ 31 | public void dealProtocol(_IALProtocolReceiver _receiver, ByteBuffer _msgBuffer) 32 | { 33 | T protocolObj = _createProtocolObj(); 34 | protocolObj.readPackage(_msgBuffer); 35 | 36 | //处理数据,并返回结果 37 | _dealProtocol(_receiver, protocolObj); 38 | } 39 | 40 | /************ 41 | * 自动根据处理的消息对象获取本处理对象处理的协议主,副协议号 42 | * 43 | * @author alzq.z 44 | * @time Feb 19, 2013 11:36:41 AM 45 | */ 46 | public byte getMainOrder() {return basicInfoObj.getMainOrder();} 47 | public byte getSubOrder() {return basicInfoObj.getSubOrder();} 48 | 49 | /********************** 50 | * 创建消息结构体用于读取字节,并转化为消息对象 51 | * 52 | * @author alzq.z 53 | * @time Feb 19, 2013 10:52:25 AM 54 | */ 55 | protected abstract T _createProtocolObj(); 56 | 57 | /********************** 58 | * 消息处理函数,直接带入对应的消息结构体 59 | * 60 | * @author alzq.z 61 | * @time Feb 19, 2013 10:52:30 AM 62 | */ 63 | protected abstract void _dealProtocol(_IALProtocolReceiver _receiver, T _msg); 64 | } 65 | -------------------------------------------------------------------------------- /ALBasicServer/src/ALBasicServer/ALServerAsynTask/ALAsynTaskInfo.java: -------------------------------------------------------------------------------- 1 | package ALBasicServer.ALServerAsynTask; 2 | 3 | import ALBasicServer.ALServerSynTask.ALSynTaskManager; 4 | import ALBasicServer.ALTask._IALAsynCallBackTask; 5 | import ALBasicServer.ALTask._IALAsynCallTask; 6 | import ALBasicServer.ALTask._IALAsynRunnableTask; 7 | 8 | /********************* 9 | * 异步任务处理信息对象 10 | * 11 | * @author alzq.z 12 | * @email zhuangfan@vip.163.com 13 | * @time Feb 19, 2013 4:01:56 PM 14 | */ 15 | public class ALAsynTaskInfo 16 | { 17 | private _IALAsynCallTask _m_tCallObj; 18 | private _IALAsynCallBackTask _m_tCallBackObj; 19 | private _IALAsynRunnableTask _m_tRunObj; 20 | 21 | public ALAsynTaskInfo(_IALAsynCallTask _callObj, _IALAsynCallBackTask _callBackObj) 22 | { 23 | _m_tCallObj = _callObj; 24 | _m_tCallBackObj = _callBackObj; 25 | _m_tRunObj = null; 26 | } 27 | public ALAsynTaskInfo(_IALAsynRunnableTask _runObj) 28 | { 29 | _m_tCallObj = null; 30 | _m_tCallBackObj = null; 31 | _m_tRunObj = _runObj; 32 | } 33 | 34 | public void run() 35 | { 36 | if(null == _m_tRunObj) 37 | { 38 | //处理异步 39 | T object = null; 40 | try 41 | { 42 | if(null != _m_tCallObj) 43 | { 44 | object = _m_tCallObj.dealAsynTask(); 45 | } 46 | } 47 | catch (Exception e) 48 | { 49 | e.printStackTrace(); 50 | } 51 | 52 | //添加任务进行回调的处理 53 | if(null != _m_tCallBackObj) 54 | { 55 | ALSynTaskManager.getInstance().regTask(new SynAsynCallBackTask(object, _m_tCallBackObj)); 56 | } 57 | } 58 | else 59 | { 60 | try 61 | { 62 | _m_tRunObj.run(); 63 | } 64 | catch(Exception e) 65 | { 66 | e.printStackTrace(); 67 | } 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /ALBasicClient/src/ALBasicClient/ALBasicSendingClientManager.java: -------------------------------------------------------------------------------- 1 | package ALBasicClient; 2 | 3 | import java.util.LinkedList; 4 | import java.util.concurrent.Semaphore; 5 | import java.util.concurrent.locks.ReentrantLock; 6 | 7 | /********************* 8 | * 存储所有发送对象的队列,进行相关顺序的存储以及统一管理 9 | * @author alzq 10 | * 11 | */ 12 | public class ALBasicSendingClientManager 13 | { 14 | private static ALBasicSendingClientManager g_instance = new ALBasicSendingClientManager(); 15 | 16 | public static ALBasicSendingClientManager getInstance() 17 | { 18 | if(null == g_instance) 19 | g_instance = new ALBasicSendingClientManager(); 20 | 21 | return g_instance; 22 | } 23 | 24 | /** 存储Socket数量相关的信号量 */ 25 | private Semaphore _m_sSocketEvent; 26 | /** 发送端口队列锁 */ 27 | private ReentrantLock _m_rSocketLock; 28 | /** 需要发送的SocketList队列 */ 29 | private LinkedList _m_lSendSocketList; 30 | 31 | protected ALBasicSendingClientManager() 32 | { 33 | _m_sSocketEvent = new Semaphore(0); 34 | _m_rSocketLock = new ReentrantLock(); 35 | _m_lSendSocketList = new LinkedList(); 36 | } 37 | 38 | /***************** 39 | * 添加需要发送的Socket 40 | * 41 | * @author alzq.z 42 | * @time Feb 19, 2013 9:58:37 PM 43 | */ 44 | public void addSendSocket(ALBasicClientSocket _socket) 45 | { 46 | _lock(); 47 | 48 | _m_lSendSocketList.add(_socket); 49 | _m_sSocketEvent.release(); 50 | 51 | _unlock(); 52 | } 53 | 54 | /***************** 55 | * 取出一个Socket进行发送 56 | * 57 | * @author alzq.z 58 | * @time Feb 19, 2013 9:58:41 PM 59 | */ 60 | public ALBasicClientSocket popSendSocket() 61 | { 62 | _m_sSocketEvent.acquireUninterruptibly(); 63 | 64 | ALBasicClientSocket socket = null; 65 | _lock(); 66 | 67 | socket = _m_lSendSocketList.pop(); 68 | 69 | _unlock(); 70 | 71 | return socket; 72 | } 73 | 74 | protected void _lock() 75 | { 76 | _m_rSocketLock.lock(); 77 | } 78 | protected void _unlock() 79 | { 80 | _m_rSocketLock.unlock(); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /ALBasicProtocolPack/src/ALBasicProtocolPack/BasicObj/ALBasicProtocolDispather.java: -------------------------------------------------------------------------------- 1 | package ALBasicProtocolPack.BasicObj; 2 | 3 | import java.nio.ByteBuffer; 4 | 5 | import ALBasicCommon.ALBasicCommonFun; 6 | 7 | /************************ 8 | * 本类为消息处理注册对象,主协议号以byte定义,使用数组进行存储以增加查询速度 9 | * 10 | * @author alzq.z 11 | * @email zhuangfan@vip.163.com 12 | * @time Feb 19, 2013 10:57:07 AM 13 | */ 14 | public class ALBasicProtocolDispather 15 | { 16 | protected _AALBasicProtocolMainOrderDealer[] _m_lDealMap; 17 | 18 | public ALBasicProtocolDispather() 19 | { 20 | _m_lDealMap = new _AALBasicProtocolMainOrderDealer[256]; 21 | 22 | //初始化所有的256个处理对象队列 23 | for(int i = 0; i < 256; i ++) 24 | { 25 | _m_lDealMap[i] = null; 26 | } 27 | } 28 | 29 | /**************** 30 | * 注册主协议处理对象 31 | * 32 | * @author alzq.z 33 | * @time Feb 19, 2013 11:29:20 AM 34 | */ 35 | public void RegProtocol(_AALBasicProtocolMainOrderDealer _dispathRegister) 36 | { 37 | int i = ALBasicCommonFun.byte2int(_dispathRegister.getMainOrder()); 38 | _m_lDealMap[i] = _dispathRegister; 39 | } 40 | 41 | /********************** 42 | * 返回对应协议的处理对象 43 | * @company Isg @author alzq.zhf 44 | * 2014年11月15日 下午12:02:57 45 | */ 46 | public _AALBasicProtocolMainOrderDealer getDealer(byte _mainOrder) 47 | { 48 | int iIndex = ALBasicCommonFun.byte2int(_mainOrder); 49 | if(iIndex < 0 || iIndex >= _m_lDealMap.length) 50 | return null; 51 | 52 | return _m_lDealMap[iIndex]; 53 | } 54 | 55 | 56 | /*********************** 57 | * 协议处理函数 58 | * 59 | * @author alzq.z 60 | * @time Feb 19, 2013 11:31:49 AM 61 | */ 62 | public boolean DealProtocol(_IALProtocolReceiver _receiver, ByteBuffer _msg) 63 | { 64 | //获取主协议编号 65 | byte mainOrder = _msg.get(); 66 | 67 | //获取协议处理对象 68 | _AALBasicProtocolMainOrderDealer dealer = getDealer(mainOrder); 69 | 70 | if(null == dealer) 71 | return false; 72 | 73 | boolean res = false; 74 | try 75 | { 76 | res = dealer.dispathProtocol(_receiver, _msg); 77 | } 78 | catch (Exception e) 79 | { 80 | e.printStackTrace(); 81 | } 82 | 83 | return res; 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /ALBasicServer/src/ALBasicServer/ALSocket/ALServerSendSocketMgr.java: -------------------------------------------------------------------------------- 1 | package ALBasicServer.ALSocket; 2 | 3 | import java.util.LinkedList; 4 | import java.util.concurrent.Semaphore; 5 | import java.util.concurrent.locks.ReentrantLock; 6 | 7 | 8 | /********************* 9 | * 存储所有需要发送消息的Socket,并使用堆栈方式进行管理。
10 | * 逐个取出并进行发送处理 11 | * 12 | * @author alzq.z 13 | * @email zhuangfan@vip.163.com 14 | * @time Feb 19, 2013 1:42:56 PM 15 | */ 16 | public class ALServerSendSocketMgr 17 | { 18 | private static ALServerSendSocketMgr g_instance = new ALServerSendSocketMgr(); 19 | 20 | public static ALServerSendSocketMgr getInstance() 21 | { 22 | if(null == g_instance) 23 | g_instance = new ALServerSendSocketMgr(); 24 | 25 | return g_instance; 26 | } 27 | 28 | /** 存储Socket数量相关的信号量 */ 29 | private Semaphore _m_sSocketEvent; 30 | /** 发送端口队列锁 */ 31 | private ReentrantLock _m_rSocketLock; 32 | /** 需要发送的SocketList队列 */ 33 | private LinkedList _m_lSendSocketList; 34 | 35 | protected ALServerSendSocketMgr() 36 | { 37 | _m_sSocketEvent = new Semaphore(0); 38 | _m_rSocketLock = new ReentrantLock(); 39 | _m_lSendSocketList = new LinkedList(); 40 | } 41 | 42 | /***************** 43 | * 添加需要发送的Socket对象 44 | * 45 | * @author alzq.z 46 | * @time Feb 19, 2013 1:44:32 PM 47 | */ 48 | public void addSendSocket(ALBasicServerSocket _socket) 49 | { 50 | _lock(); 51 | 52 | _m_lSendSocketList.add(_socket); 53 | _m_sSocketEvent.release(); 54 | 55 | _unlock(); 56 | } 57 | 58 | /***************** 59 | * 取出第一个需要发送数据的Socket 60 | * 61 | * @author alzq.z 62 | * @time Feb 19, 2013 1:44:54 PM 63 | */ 64 | public ALBasicServerSocket popSendSocket() 65 | { 66 | _m_sSocketEvent.acquireUninterruptibly(); 67 | 68 | ALBasicServerSocket socket = null; 69 | _lock(); 70 | 71 | socket = _m_lSendSocketList.pop(); 72 | 73 | _unlock(); 74 | 75 | return socket; 76 | } 77 | 78 | //================= protected function 79 | protected void _lock() 80 | { 81 | _m_rSocketLock.lock(); 82 | } 83 | protected void _unlock() 84 | { 85 | _m_rSocketLock.unlock(); 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /ALBasicProtocol/src/BasicServer/S2C_BasicClientVerifyResult.java: -------------------------------------------------------------------------------- 1 | package BasicServer; 2 | 3 | import java.nio.ByteBuffer; 4 | public class S2C_BasicClientVerifyResult implements ALBasicProtocolPack._IALProtocolStructure { 5 | private Long socketID; 6 | private String customRetMsg; 7 | 8 | 9 | public S2C_BasicClientVerifyResult() { 10 | socketID = (long)0; 11 | customRetMsg = ""; 12 | } 13 | 14 | public final byte getMainOrder() { return (byte)0; } 15 | 16 | public final byte getSubOrder() { return (byte)0; } 17 | 18 | public long getSocketID() { return socketID; } 19 | public void setSocketID(long _socketID) { socketID = _socketID; } 20 | public String getCustomRetMsg() { return customRetMsg; } 21 | public void setCustomRetMsg(String _customRetMsg) { customRetMsg = _customRetMsg; } 22 | 23 | 24 | public final int GetUnzipBufSize() { 25 | int _size = 8; 26 | _size += ALBasicProtocolPack.ALProtocolCommon.GetStringBufSize(customRetMsg); 27 | 28 | return _size; 29 | } 30 | 31 | public final int GetZipBufSize() { 32 | int _size = 0; 33 | _size += ALBasicProtocolPack.ALProtocolCommon.GetLongZipSize(socketID); 34 | _size += ALBasicProtocolPack.ALProtocolCommon.GetStringBufSize(customRetMsg); 35 | 36 | return _size; 37 | } 38 | 39 | 40 | 41 | public final void ReadUnzipBuf(ByteBuffer _buf) { 42 | socketID = _buf.getLong(); 43 | customRetMsg = ALBasicProtocolPack.ALProtocolCommon.GetStringFromBuf(_buf); 44 | } 45 | 46 | public final void ReadZipBuf(ByteBuffer _buf) { 47 | socketID = ALBasicProtocolPack.ALProtocolCommon.ZipGetLongFromBuf(_buf); 48 | customRetMsg = ALBasicProtocolPack.ALProtocolCommon.GetStringFromBuf(_buf); 49 | } 50 | 51 | public final void PutUnzipBuf(ByteBuffer _buf) { 52 | _buf.putLong(socketID); 53 | ALBasicProtocolPack.ALProtocolCommon.PutStringIntoBuf(_buf, customRetMsg); 54 | } 55 | 56 | public final void PutZipBuf(ByteBuffer _buf) { 57 | ALBasicProtocolPack.ALProtocolCommon.ZipPutLongIntoBuf(_buf, socketID); 58 | ALBasicProtocolPack.ALProtocolCommon.PutStringIntoBuf(_buf, customRetMsg); 59 | } 60 | 61 | public final ByteBuffer makeFullPackage() { 62 | int _bufSize = GetUnzipBufSize() + 2; 63 | ByteBuffer _buf = ByteBuffer.allocate(_bufSize); 64 | _buf.put((byte)0); 65 | _buf.put((byte)0); 66 | PutUnzipBuf(_buf); 67 | _buf.flip(); 68 | return _buf; 69 | } 70 | public final ByteBuffer makePackage() { 71 | int _bufSize = GetUnzipBufSize(); 72 | ByteBuffer _buf = ByteBuffer.allocate(_bufSize); 73 | PutUnzipBuf(_buf); 74 | _buf.flip(); 75 | return _buf; 76 | } 77 | public final void readPackage(ByteBuffer _buf) { 78 | ReadUnzipBuf(_buf); 79 | } 80 | } 81 | 82 | -------------------------------------------------------------------------------- /ALBasicServer/src/ALBasicServer/ALSocket/_AALBasicServerSocketListener.java: -------------------------------------------------------------------------------- 1 | package ALBasicServer.ALSocket; 2 | 3 | import java.nio.ByteBuffer; 4 | 5 | import ALBasicProtocolPack._IALProtocolStructure; 6 | import ALBasicProtocolPack.BasicObj._IALProtocolReceiver; 7 | 8 | /*********************** 9 | * 服务器架构下的消息处理对象,作为带入到消息实际处理函数中的一个参数 10 | * 11 | * @author alzq.z 12 | * @email zhuangfan@vip.163.com 13 | * @time Feb 19, 2013 11:48:14 AM 14 | */ 15 | public abstract class _AALBasicServerSocketListener implements _IALProtocolReceiver 16 | { 17 | /** Socket对象 */ 18 | private ALBasicServerSocket _m_csSocket; 19 | 20 | /************ 21 | * 获取Socket对象ID 22 | * 23 | * @author alzq.z 24 | * @time Feb 19, 2013 11:49:51 AM 25 | */ 26 | public long getSocketID() 27 | { 28 | if(null == _m_csSocket) 29 | return 0; 30 | 31 | return _m_csSocket.getSocketID(); 32 | } 33 | public ALBasicServerSocket getSocket() {return _m_csSocket;} 34 | public boolean enable() {return (null != _m_csSocket);} 35 | 36 | //内部函数,设置Socket对象 37 | public void setSocket(ALBasicServerSocket _socket) {_m_csSocket = _socket;} 38 | 39 | /************** 40 | * 发送消息到对应的接收端 41 | * 42 | * @author alzq.z 43 | * @time Feb 19, 2013 11:52:17 AM 44 | */ 45 | public void send(ByteBuffer _buffer) 46 | { 47 | if(null == _m_csSocket || null == _buffer) 48 | return ; 49 | 50 | _m_csSocket.send(_buffer); 51 | } 52 | public void send(_IALProtocolStructure _protocolObj) 53 | { 54 | if(null == _m_csSocket || null == _protocolObj) 55 | return ; 56 | 57 | //协议打包主体 58 | ByteBuffer msg = _protocolObj.makeFullPackage(); 59 | 60 | _m_csSocket.send(msg); 61 | } 62 | 63 | /***************** 64 | * 断开Socket 65 | * 66 | * @author alzq.z 67 | * @time Feb 19, 2013 1:35:39 PM 68 | */ 69 | public void logout() 70 | { 71 | ALServerSocketMgr.getInstance().kickUser(_m_csSocket); 72 | } 73 | 74 | /****************** 75 | * 获取到相关消息并处理的函数 76 | * 77 | * @author alzq.z 78 | * @time Feb 19, 2013 1:36:05 PM 79 | */ 80 | public abstract void receiveMsg(ByteBuffer _buf); 81 | 82 | /******************* 83 | * 连接并验证成功时调用的函数 84 | * 85 | * @author alzq.z 86 | * @time Feb 19, 2013 1:36:37 PM 87 | */ 88 | public abstract void login(); 89 | 90 | /******************* 91 | * Socket断开连接时调用的函数 92 | * 93 | * @author alzq.z 94 | * @time Feb 19, 2013 1:37:13 PM 95 | */ 96 | public abstract void disconnect(); 97 | } 98 | -------------------------------------------------------------------------------- /ALBasicServer/src/ALBasicServer/ALServerAsynTask/ALAsynThreadTaskManager.java: -------------------------------------------------------------------------------- 1 | package ALBasicServer.ALServerAsynTask; 2 | 3 | import java.util.LinkedList; 4 | import java.util.concurrent.Semaphore; 5 | import java.util.concurrent.locks.ReentrantLock; 6 | 7 | import ALBasicServer.ALTask._IALAsynCallBackTask; 8 | import ALBasicServer.ALTask._IALAsynCallTask; 9 | import ALBasicServer.ALTask._IALAsynRunnableTask; 10 | 11 | /********************** 12 | * 异步任务处理线程中存放本线程需要处理的任务队列的对象 13 | * 14 | * @author alzq.z 15 | * @email zhuangfan@vip.163.com 16 | * @time Feb 20, 2013 10:37:01 PM 17 | */ 18 | @SuppressWarnings("rawtypes") 19 | public class ALAsynThreadTaskManager 20 | { 21 | private Semaphore _m_sSemaphore; 22 | private ReentrantLock _m_rMutex; 23 | /** 已经排入计划的异步任务处理对象 */ 24 | private LinkedList _m_lAsynTaskList; 25 | 26 | public ALAsynThreadTaskManager() 27 | { 28 | _m_sSemaphore = new Semaphore(0); 29 | _m_rMutex = new ReentrantLock(); 30 | _m_lAsynTaskList = new LinkedList(); 31 | } 32 | 33 | /*************** 34 | * 加入回调类型异步任务处理 35 | * 36 | * @author alzq.z 37 | * @time Feb 19, 2013 4:09:01 PM 38 | */ 39 | public void regTask(_IALAsynCallTask _callObj, _IALAsynCallBackTask _callBackObj) 40 | { 41 | ALAsynTaskInfo info = new ALAsynTaskInfo(_callObj, _callBackObj); 42 | 43 | _lock(); 44 | 45 | _m_lAsynTaskList.add(info); 46 | _m_sSemaphore.release(); 47 | 48 | _unlock(); 49 | } 50 | 51 | /***************** 52 | * 加入执行类异步任务处理 53 | * 54 | * @author alzq.z 55 | * @time Feb 19, 2013 4:09:29 PM 56 | */ 57 | public void regTask(_IALAsynRunnableTask _runTask) 58 | { 59 | ALAsynTaskInfo info = new ALAsynTaskInfo(_runTask); 60 | 61 | _lock(); 62 | 63 | _m_lAsynTaskList.add(info); 64 | _m_sSemaphore.release(); 65 | 66 | _unlock(); 67 | } 68 | 69 | /********************* 70 | * 取出第一个需要处理的异步任务对象 71 | * 72 | * @author alzq.z 73 | * @time Feb 19, 2013 4:09:42 PM 74 | */ 75 | public ALAsynTaskInfo popFirstAsynTask() 76 | { 77 | _m_sSemaphore.acquireUninterruptibly(); 78 | ALAsynTaskInfo info = null; 79 | 80 | _lock(); 81 | 82 | info = _m_lAsynTaskList.remove(0); 83 | 84 | _unlock(); 85 | 86 | return info; 87 | } 88 | 89 | protected void _lock() 90 | { 91 | _m_rMutex.lock(); 92 | } 93 | protected void _unlock() 94 | { 95 | _m_rMutex.unlock(); 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /ALBasicServer/src/ALBasicServer/ALServerSynTask/ALSynTaskDealThread.java: -------------------------------------------------------------------------------- 1 | package ALBasicServer.ALServerSynTask; 2 | 3 | import ALBasicCommon._AALBasicThread; 4 | import ALBasicServer.ALBasicServerConf; 5 | import ALBasicServer.ALTask._IALSynTask; 6 | import ALBasicServer.ALThread.ALThreadManager; 7 | import ALBasicServer.ALThread.ALThreadMutexMgr; 8 | import ALServerLog.ALServerLog; 9 | 10 | 11 | 12 | public class ALSynTaskDealThread extends _AALBasicThread 13 | { 14 | /** 本线程对应锁信息的存储结构体 */ 15 | private ALThreadMutexMgr _m_tmrThreadMutexMgr; 16 | /** 线程是否退出 */ 17 | private boolean _m_bThreadExit; 18 | 19 | public ALSynTaskDealThread() 20 | { 21 | _m_tmrThreadMutexMgr = null; 22 | _m_bThreadExit = false; 23 | } 24 | 25 | public void exitThread() 26 | { 27 | _m_bThreadExit = true; 28 | } 29 | 30 | /****************** 31 | * 线程执行函数 32 | * 33 | * @author alzq.z 34 | * @time Feb 20, 2013 11:05:54 PM 35 | */ 36 | @Override 37 | protected void _run() 38 | { 39 | if(ALBasicServerConf.getInstance().getCheckMutex()) 40 | { 41 | //获得当前线程ID 42 | long threadID = Thread.currentThread().getId(); 43 | _m_tmrThreadMutexMgr = ALThreadManager.getInstance().regThread(threadID); 44 | 45 | //注册失败直接返回,不进行线程体操作 46 | if(null == _m_tmrThreadMutexMgr) 47 | return ; 48 | } 49 | 50 | while(!_m_bThreadExit) 51 | { 52 | //执行任务循环 53 | //获取当前需要执行的任务,无任务时将等待信号量 54 | _IALSynTask curTask = ALSynTaskManager.getInstance().popCurrentTask(); 55 | 56 | if(null != curTask) 57 | { 58 | try 59 | { 60 | //执行对应任务 61 | curTask.run(); 62 | } 63 | catch (Exception e) 64 | { 65 | ALServerLog.Error(curTask.getClass().getName() + " Error!!"); 66 | e.printStackTrace(); 67 | 68 | //当有进行锁检测时需要尝试释放所有注册锁,避免异常的操作导致锁未释放 69 | if(ALBasicServerConf.getInstance().getCheckMutex()) 70 | _m_tmrThreadMutexMgr.releaseAllMutex(); 71 | } 72 | 73 | //在任务正常或异常执行完后都需要对锁的释放情况进行判断 74 | if(ALBasicServerConf.getInstance().getCheckMutex()) 75 | { 76 | if(!_m_tmrThreadMutexMgr.judgeAllMutexRelease()) 77 | { 78 | //有部分锁未释放 79 | ALServerLog.Error(curTask.getClass().getName() + " have some mutexs are not released !"); 80 | 81 | _m_tmrThreadMutexMgr.releaseAllMutex(); 82 | } 83 | } 84 | } 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /ALBasicClient/src/ALBasicClient/_AALBasicClientListener.java: -------------------------------------------------------------------------------- 1 | package ALBasicClient; 2 | 3 | import java.nio.ByteBuffer; 4 | 5 | import ALBasicProtocolPack._IALProtocolStructure; 6 | import ALBasicProtocolPack.BasicObj._IALProtocolReceiver; 7 | 8 | public abstract class _AALBasicClientListener implements _IALProtocolReceiver 9 | { 10 | /** 连接的端口对象 */ 11 | private ALBasicClientSocket _m_csClientSocket; 12 | 13 | public _AALBasicClientListener(String _serverIP, int _serverPort) 14 | { 15 | _m_csClientSocket = new ALBasicClientSocket(this, _serverIP, _serverPort); 16 | } 17 | 18 | public ALBasicClientSocket getSocket() {return _m_csClientSocket;} 19 | 20 | /******************* 21 | * 连接服务器并尝试登录 22 | * 23 | * @author alzq.z 24 | * @time Feb 19, 2013 10:04:33 PM 25 | */ 26 | public void login(int _clientType, String _userName, String _userPassword) 27 | { 28 | _m_csClientSocket.login(_clientType, _userName, _userPassword, ""); 29 | } 30 | public void login(int _clientType, String _userName, String _userPassword, String _customMsg) 31 | { 32 | _m_csClientSocket.login(_clientType, _userName, _userPassword, _customMsg); 33 | } 34 | 35 | /******************** 36 | * 发送消息 37 | * 38 | * @author alzq.z 39 | * @time Feb 19, 2013 10:04:41 PM 40 | */ 41 | public void send(ByteBuffer _buffer) 42 | { 43 | if(null == _m_csClientSocket) 44 | return ; 45 | 46 | _m_csClientSocket.send(_buffer); 47 | } 48 | public void send(ByteBuffer _tmpHeader, ByteBuffer _buffer) 49 | { 50 | if(null == _m_csClientSocket) 51 | return ; 52 | 53 | _m_csClientSocket.send(_tmpHeader, _buffer); 54 | } 55 | public void send(_IALProtocolStructure _protocolObj) 56 | { 57 | if(null == _m_csClientSocket || null == _protocolObj) 58 | return ; 59 | 60 | _m_csClientSocket.send(_protocolObj.makeFullPackage()); 61 | } 62 | 63 | /**************** 64 | * 接收消息的处理函数,此函数在接收线程中处理,如需要更好的处理方式则需要另开线程进行处理 65 | * 66 | * @author alzq.z 67 | * @time Feb 19, 2013 10:04:48 PM 68 | */ 69 | public abstract void receiveMes(ByteBuffer _mes); 70 | /**************** 71 | * 连接服务器失败 72 | * 73 | * @author alzq.z 74 | * @time Feb 19, 2013 10:04:53 PM 75 | */ 76 | public abstract void ConnectFail(); 77 | /*************** 78 | * 登录失败 79 | * 80 | * @author alzq.z 81 | * @time Feb 19, 2013 10:05:03 PM 82 | */ 83 | public abstract void LoginFail(); 84 | /*************** 85 | * 登出操作 86 | * 87 | * @author alzq.z 88 | * @time Feb 19, 2013 10:05:07 PM 89 | */ 90 | public abstract void Disconnect(); 91 | /*************** 92 | * 登录成功 93 | * 94 | * @author alzq.z 95 | * @time Feb 19, 2013 10:05:11 PM 96 | */ 97 | public abstract void LoginSuc(String _customRetMsg); 98 | } 99 | -------------------------------------------------------------------------------- /ALBasicServer/src/ALBasicServer/ALSocket/ALServerSocketMgr.java: -------------------------------------------------------------------------------- 1 | package ALBasicServer.ALSocket; 2 | 3 | import java.nio.channels.SocketChannel; 4 | import java.util.Hashtable; 5 | 6 | import ALBasicServer.ALServerSynTask.ALSynTaskManager; 7 | import ALServerLog.ALServerLog; 8 | 9 | /**************** 10 | * 所有连接到本服务器的Socket的管理对象 11 | * 12 | * @author alzq.z 13 | * @email zhuangfan@vip.163.com 14 | * @time Feb 19, 2013 11:56:18 AM 15 | */ 16 | public class ALServerSocketMgr 17 | { 18 | private static ALServerSocketMgr g_instance; 19 | 20 | public static ALServerSocketMgr getInstance() 21 | { 22 | if(null == g_instance) 23 | g_instance = new ALServerSocketMgr(); 24 | 25 | return g_instance; 26 | } 27 | 28 | /** 注册的相关Socket对象,通过连接的SocketChannel对象作为索引Key */ 29 | private Hashtable _m_htSocketRegTable; 30 | /** 还未注册的socket对象链表 */ 31 | 32 | protected ALServerSocketMgr() 33 | { 34 | _m_htSocketRegTable = new Hashtable(); 35 | } 36 | 37 | /******************* 38 | * 注册Socket对象 39 | * 40 | * @author alzq.z 41 | * @time Feb 19, 2013 11:59:38 AM 42 | */ 43 | public void regSocket(ALBasicServerSocket _socket) 44 | { 45 | _m_htSocketRegTable.put(_socket._getSocketChannel(), _socket); 46 | } 47 | 48 | /******************** 49 | * 获取socket对象 50 | * 51 | * @author alzq.z 52 | * @time Feb 19, 2013 11:59:42 AM 53 | */ 54 | public ALBasicServerSocket getSocket(SocketChannel _channel) 55 | { 56 | return _m_htSocketRegTable.get(_channel); 57 | } 58 | 59 | /********************* 60 | * 删除注册的对象 61 | * 62 | * @author alzq.z 63 | * @time Feb 19, 2013 11:59:48 AM 64 | */ 65 | public void unregSocket(SocketChannel _channel) 66 | { 67 | ALBasicServerSocket socket = _m_htSocketRegTable.remove(_channel); 68 | 69 | kickUser(socket); 70 | } 71 | 72 | /******************* 73 | * 剔除已连接的Socket的操作 74 | * 75 | * @author alzq.z 76 | * @time Feb 19, 2013 11:59:54 AM 77 | */ 78 | public void kickUser(ALBasicServerSocket _socket) 79 | { 80 | if(null == _socket) 81 | return ; 82 | 83 | ALServerLog.Info(_socket.getUserName() + " Disconnected!"); 84 | 85 | SocketChannel channel = _socket._getSocketChannel(); 86 | 87 | if(null != channel) 88 | { 89 | _m_htSocketRegTable.remove(channel); 90 | 91 | //移除Socket中的发送Channel对象 92 | _socket._removeChannel(); 93 | try { 94 | channel.close(); 95 | } catch (Exception e) {} 96 | } 97 | 98 | //插入断开连接的处理任务 99 | ALSynTaskManager.getInstance().regTask(new SynDisconnectTask(_socket)); 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /ALBasicClient/src/ALBasicClient/ALBasicClientConf.java: -------------------------------------------------------------------------------- 1 | package ALBasicClient; 2 | 3 | import java.io.FileInputStream; 4 | import java.io.IOException; 5 | import java.io.InputStream; 6 | import java.util.Properties; 7 | 8 | import ALBasicCommon.ALConfReader; 9 | 10 | /****************** 11 | * 基本的Java客户端配置对象 12 | * 13 | * @author alzq.z 14 | * @email zhuangfan@vip.163.com 15 | * @time Feb 19, 2013 9:34:31 PM 16 | */ 17 | public class ALBasicClientConf 18 | { 19 | private static ALBasicClientConf g_instance; 20 | 21 | public static ALBasicClientConf getInstance() 22 | { 23 | if(null == g_instance) 24 | g_instance = new ALBasicClientConf(); 25 | 26 | return g_instance; 27 | } 28 | 29 | /** Socket消息发送的线程数量 */ 30 | private int _m_iSendThreadNum; 31 | /** 端口接收BUF缓冲区长度 */ 32 | private int _m_iRecBufferLen; 33 | 34 | public ALBasicClientConf() 35 | { 36 | _m_iSendThreadNum = 1; 37 | _m_iRecBufferLen = 131072; 38 | } 39 | 40 | public int getSendThreadNum() {return _m_iSendThreadNum;} 41 | public int getRecBufferLen() {return _m_iRecBufferLen;} 42 | 43 | /******************* 44 | * 初始化属性设置对象 45 | * @param _properties 46 | */ 47 | public boolean init() 48 | { 49 | Properties properties = new Properties(); 50 | 51 | InputStream propertiesInputStream = null; 52 | 53 | try 54 | { 55 | propertiesInputStream = new FileInputStream("./conf/ALBasicClientConf.properties"); 56 | } 57 | catch (IOException e) 58 | { 59 | e.printStackTrace(); 60 | } 61 | 62 | if(null == propertiesInputStream) 63 | { 64 | return false; 65 | } 66 | 67 | //输入有效则开始读取对应配置 68 | try 69 | { 70 | properties.load(propertiesInputStream); 71 | } 72 | catch (IOException e) 73 | { 74 | e.printStackTrace(); 75 | } 76 | 77 | try 78 | { 79 | System.out.println("[Conf init] Start load ALBasicClient Properties ... ..."); 80 | 81 | //获取消息发送线程的数量 82 | _m_iSendThreadNum 83 | = ALConfReader.readInt(properties, "ALBasicClient.SendThreadNum", _m_iRecBufferLen); 84 | 85 | //获取缓冲区长度 86 | _m_iRecBufferLen 87 | = ALConfReader.readInt(properties, "ALBasicClient.RecSocketBufLen", _m_iRecBufferLen); 88 | 89 | System.out.println("[Conf init] Finish load ALBasicClient Properties ... ..."); 90 | } 91 | catch (Exception e) 92 | { 93 | System.out.println("[Conf Init Error] Load ALBasicClient Properties Error!!"); 94 | e.printStackTrace(); 95 | } 96 | finally 97 | { 98 | try 99 | { 100 | propertiesInputStream.close(); 101 | } 102 | catch (IOException e) 103 | { 104 | e.printStackTrace(); 105 | } 106 | } 107 | 108 | return true; 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /ALBasicCommon/src/ALBasicCommon/ALConfReader.java: -------------------------------------------------------------------------------- 1 | package ALBasicCommon; 2 | 3 | import java.util.Properties; 4 | 5 | public class ALConfReader 6 | { 7 | /********************** 8 | * 读取整形配置信息 9 | * 10 | * @author alzq.z 11 | * @time Feb 19, 2013 10:54:27 AM 12 | */ 13 | public static int readInt(Properties _properties, String _name, int _defaultValue) 14 | { 15 | int value = _defaultValue; 16 | 17 | String tmpStr = _properties.getProperty(_name); 18 | if(null != tmpStr && !tmpStr.isEmpty()) 19 | { 20 | value = Integer.parseInt(tmpStr.trim()); 21 | } 22 | System.out.println("[Conf Init] " + _name + " = " + tmpStr); 23 | 24 | return value; 25 | } 26 | 27 | /********************** 28 | * 读取长整形配置信息 29 | * 30 | * @author alzq.z 31 | * @time Feb 19, 2013 10:54:27 AM 32 | */ 33 | public static long readLong(Properties _properties, String _name, long _defaultValue) 34 | { 35 | long value = _defaultValue; 36 | 37 | String tmpStr = _properties.getProperty(_name); 38 | if(null != tmpStr && !tmpStr.isEmpty()) 39 | { 40 | value = Long.parseLong(tmpStr.trim()); 41 | } 42 | System.out.println("[Conf Init] " + _name + " = " + tmpStr); 43 | 44 | return value; 45 | } 46 | 47 | /********************** 48 | * 读取字符串配置信息 49 | * 50 | * @author alzq.z 51 | * @time Feb 19, 2013 10:54:23 AM 52 | */ 53 | public static String readStr(Properties _properties, String _name, String _defaultValue) 54 | { 55 | String value = _defaultValue; 56 | 57 | String tmpStr = _properties.getProperty(_name); 58 | if(null != tmpStr && !tmpStr.isEmpty()) 59 | { 60 | value = tmpStr; 61 | } 62 | System.out.println("[Conf Init] " + _name + " = " + tmpStr); 63 | 64 | return value; 65 | } 66 | 67 | /********************** 68 | * 读取密码类配置信息,输出不同 69 | * 70 | * @author alzq.z 71 | * @time Feb 19, 2013 10:54:23 AM 72 | */ 73 | public static String readPassword(Properties _properties, String _name, String _defaultValue) 74 | { 75 | String value = _defaultValue; 76 | 77 | String tmpStr = _properties.getProperty(_name); 78 | if(null != tmpStr && !tmpStr.isEmpty()) 79 | { 80 | value = tmpStr; 81 | } 82 | System.out.println("[Conf Init] " + _name + " = ******"); 83 | 84 | return value; 85 | } 86 | 87 | /********************** 88 | * 读取布尔型配置信息 89 | * 90 | * @author alzq.z 91 | * @time Feb 19, 2013 10:54:19 AM 92 | */ 93 | public static Boolean readBool(Properties _properties, String _name, Boolean _defaultValue) 94 | { 95 | Boolean value = _defaultValue; 96 | 97 | String tmpStr = _properties.getProperty(_name); 98 | if(null != tmpStr && !tmpStr.isEmpty()) 99 | { 100 | value = tmpStr.trim().equalsIgnoreCase("true"); 101 | } 102 | System.out.println("[Conf Init] " + _name + " = " + tmpStr); 103 | 104 | return value; 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /ALBasicServer/src/ALBasicServer/ALBasicServer.java: -------------------------------------------------------------------------------- 1 | package ALBasicServer; 2 | 3 | import ALBasicServer.ALServerAsynTask.ALAsynTaskManager; 4 | import ALBasicServer.ALSocket.ALServerSocketListenFunction; 5 | import ALBasicServer.ALThread.ALThreadManager; 6 | import ALBasicServer.ALVerifyObj._IALVerifyFun; 7 | import ALServerLog.ALServerLog; 8 | 9 | public class ALBasicServer 10 | { 11 | /** 是否成功初始化 */ 12 | private static boolean g_inited = false; 13 | 14 | /** 15 | * 服务器模块启动初始化函数
16 | * 开启基本的服务器逻辑任务处理线程
17 | * 异步任务处理线程
18 | * 以及相关发送消息线程和Socket监听循环
19 | * 20 | * @author alzq.z 21 | * @time Feb 19, 2013 4:33:52 PM 22 | */ 23 | public static void initBasicServer(int _asynTaskDealThreadCount) 24 | { 25 | if(g_inited) 26 | { 27 | ALServerLog.Fatal("Please don't try to repeat init AL Basic Server model!!"); 28 | new Exception().printStackTrace(); 29 | return ; 30 | } 31 | 32 | g_inited = true; 33 | 34 | //读取配置文件并初始化相关环境操作 35 | if(ALBasicServerConf.getInstance().init()) 36 | { 37 | //初始化日志配置 38 | ALServerLog.initALServerLog(); 39 | 40 | //输出服务器基本日志 41 | ALServerLog.Fatal(ALBasicServerConf.getInstance().getServerTag() + " start initialize..."); 42 | ALServerLog.Fatal("Server Log Level - " + ALServerLog.getLogLevel()); 43 | 44 | //开启命令行读取任务 45 | ALThreadManager.getInstance().createCmdReadThread(); 46 | 47 | //开启定时任务的检测线程 48 | ALThreadManager.getInstance().createTimingTaskCheckThread(); 49 | 50 | //开启对应的普通任务执行线程 51 | ALServerLog.Fatal("Server Start Task Thread Count - " + ALBasicServerConf.getInstance().getSynTaskThreadNum()); 52 | for(int i = 0; i < ALBasicServerConf.getInstance().getSynTaskThreadNum(); i++) 53 | { 54 | ALThreadManager.getInstance().createTaskDealThread(); 55 | } 56 | 57 | //开启对应的端口发送执行线程 58 | ALServerLog.Fatal("Server Start Socket Send Thread Count - " + ALBasicServerConf.getInstance().getSendThreadNum()); 59 | for(int i = 0; i < ALBasicServerConf.getInstance().getSendThreadNum(); i++) 60 | { 61 | ALThreadManager.getInstance().createSocketSendThread(); 62 | } 63 | 64 | //开启对应的异步任务执行线程 65 | ALServerLog.Fatal("Server Start AsyncTask Thread Count - " + _asynTaskDealThreadCount); 66 | ALAsynTaskManager.getInstance().init(_asynTaskDealThreadCount); 67 | } 68 | 69 | if(ALBasicServerConf.getInstance().getCheckMutex()) 70 | { 71 | //获得当前线程ID 72 | long threadID = Thread.currentThread().getId(); 73 | ALThreadManager.getInstance().regThread(threadID); 74 | } 75 | } 76 | 77 | /********************** 78 | * 开启服务器监听端口,并对所有返回数据做处理 79 | * 80 | * @author alzq.z 81 | * @time Feb 19, 2013 4:34:07 PM 82 | */ 83 | public static void startListener(int _port, int _recBuffLen, _IALVerifyFun _verifyObj) 84 | { 85 | if(null == _verifyObj) 86 | { 87 | ALServerLog.Fatal("Can not Use The Null VerifyObj!"); 88 | return ; 89 | } 90 | 91 | ALServerSocketListenFunction.startServer(_port, _recBuffLen, _verifyObj); 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /ALBasicServer/src/ALBasicClient/_AALBasicServerClientListener.java: -------------------------------------------------------------------------------- 1 | package ALBasicClient; 2 | 3 | import java.nio.ByteBuffer; 4 | import java.util.LinkedList; 5 | import java.util.concurrent.locks.ReentrantLock; 6 | 7 | import ALBasicServer.ALServerSynTask.ALSynTaskManager; 8 | 9 | /********************* 10 | * 在服务器架构内连接服务器的客户端对象,在接受消息后统一使用同步任务进行处理 11 | * 12 | * @author alzq.z 13 | * @email zhuangfan@vip.163.com 14 | * @time May 28, 2014 11:32:21 PM 15 | */ 16 | public abstract class _AALBasicServerClientListener extends _AALBasicClientListener 17 | { 18 | /** 接收到的消息管理队列信息 */ 19 | private ReentrantLock _m_msgMutex; 20 | private LinkedList _m_lMsgList; 21 | 22 | public _AALBasicServerClientListener(String _serverIP, int _serverPort) 23 | { 24 | super(_serverIP, _serverPort); 25 | 26 | _m_msgMutex = new ReentrantLock(); 27 | _m_lMsgList = new LinkedList(); 28 | } 29 | 30 | @Override 31 | public void receiveMes(ByteBuffer _mes) 32 | { 33 | addMessage(_mes); 34 | } 35 | 36 | /******************** 37 | * 添加一个需要处理的消息 38 | * 39 | * @author alzq.z 40 | * @time Mar 4, 2013 10:19:30 PM 41 | */ 42 | public void addMessage(ByteBuffer _msg) 43 | { 44 | //消息无效或角色无加载完成则直接返回 45 | if(null == _msg) 46 | return ; 47 | 48 | boolean needStartTask = false; 49 | 50 | _lock(); 51 | 52 | if(_m_lMsgList.isEmpty()) 53 | needStartTask = true; 54 | 55 | _m_lMsgList.addLast(_msg); 56 | 57 | _unlock(); 58 | 59 | if(needStartTask) 60 | ALSynTaskManager.getInstance().regTask(new ALSynServerClientDealMessageTask(this)); 61 | } 62 | 63 | /****************** 64 | * 自行从消息队列中取出一个消息进行处理 65 | * 66 | * @author alzq.z 67 | * @time Mar 4, 2013 10:24:27 PM 68 | */ 69 | public void dealMessage() 70 | { 71 | ByteBuffer msg = null; 72 | boolean needContinueTask = false; 73 | 74 | //取出第一个消息 75 | _lock(); 76 | 77 | if(!_m_lMsgList.isEmpty()) 78 | msg = _m_lMsgList.getFirst(); 79 | 80 | _unlock(); 81 | 82 | if(null != msg) 83 | { 84 | //处理消息 85 | try 86 | { 87 | this._dealMes(msg); 88 | } 89 | catch(Exception ex) 90 | { 91 | ex.printStackTrace(); 92 | } 93 | } 94 | 95 | _lock(); 96 | 97 | _m_lMsgList.pop(); 98 | 99 | //判断消息队列是否为空 100 | if(!_m_lMsgList.isEmpty()) 101 | needContinueTask = true; 102 | 103 | _unlock(); 104 | 105 | if(needContinueTask) 106 | ALSynTaskManager.getInstance().regTask(new ALSynServerClientDealMessageTask(this)); 107 | } 108 | 109 | protected void _lock() 110 | { 111 | _m_msgMutex.lock(); 112 | } 113 | protected void _unlock() 114 | { 115 | _m_msgMutex.unlock(); 116 | } 117 | 118 | /******************** 119 | * 玩家角色消息数据的处理函数 120 | * 121 | * @author alzq.z 122 | * @time Mar 4, 2013 10:46:06 AM 123 | */ 124 | protected abstract void _dealMes(ByteBuffer _msg); 125 | } 126 | -------------------------------------------------------------------------------- /ALBasicProtocolPack/src/ALBasicProtocolPack/BasicObj/_AALBasicProtocolMainOrderDealer.java: -------------------------------------------------------------------------------- 1 | package ALBasicProtocolPack.BasicObj; 2 | 3 | import java.nio.ByteBuffer; 4 | 5 | import ALBasicCommon.ALBasicCommonFun; 6 | import ALServerLog.ALServerLog; 7 | 8 | 9 | @SuppressWarnings("rawtypes") 10 | public abstract class _AALBasicProtocolMainOrderDealer 11 | { 12 | private byte mainOrder; 13 | private _AALBasicProtocolSubOrderDealer[] dealArray = null; 14 | 15 | /***************** 16 | * 带入主协议号以及处理的协议最大的子协议号,进行协议处理队列的初始化 17 | * 18 | * @author alzq.z 19 | * @time Feb 19, 2013 10:52:55 AM 20 | */ 21 | public _AALBasicProtocolMainOrderDealer(byte _mainOrder, int _protocolMaxTypeNum) 22 | { 23 | mainOrder = _mainOrder; 24 | dealArray = new _AALBasicProtocolSubOrderDealer[_protocolMaxTypeNum + 1]; 25 | } 26 | 27 | /************ 28 | * 获取主协议号 29 | * 30 | * @author alzq.z 31 | * @time Feb 19, 2013 11:38:46 AM 32 | */ 33 | public byte getMainOrder() {return mainOrder;} 34 | 35 | /**************** 36 | * 设置处理对象,直接设置到数组中保证处理速度 37 | * 38 | * @author alzq.z 39 | * @time Feb 19, 2013 10:52:50 AM 40 | */ 41 | public void regDealer(_AALBasicProtocolSubOrderDealer _dealer) 42 | { 43 | if(null == dealArray) 44 | return ; 45 | 46 | if(_dealer.getMainOrder() != mainOrder) 47 | { 48 | //主协议号不匹配,提示警告 49 | ALServerLog.Fatal(mainOrder + " doesn't match the dealer's(" + _dealer.getClass().toString() + ") main order: " + _dealer.getMainOrder() + "!"); 50 | } 51 | 52 | int subOrder = ALBasicCommonFun.byte2int(_dealer.getSubOrder()); 53 | if(subOrder >= dealArray.length) 54 | { 55 | ALServerLog.Fatal(mainOrder + " Protocol dispather don't have " + subOrder + " size list to save the dealer obj!"); 56 | return ; 57 | } 58 | 59 | dealArray[subOrder] = _dealer; 60 | } 61 | 62 | /**************** 63 | * 强制设置指定对象为处理对象 64 | * 65 | * @author alzq.z 66 | * @time Feb 19, 2013 10:52:50 AM 67 | */ 68 | public void setSubDealer(int _subOrderID, _AALBasicProtocolSubOrderDealer _dealer) 69 | { 70 | if(null == dealArray) 71 | return ; 72 | 73 | if(_subOrderID >= dealArray.length) 74 | { 75 | ALServerLog.Fatal(mainOrder + " Protocol dispather don't have " + _subOrderID + " size list to save the dealer obj!"); 76 | return ; 77 | } 78 | 79 | dealArray[_subOrderID] = _dealer; 80 | } 81 | 82 | /******************** 83 | * 获取子处理对象信息 84 | * @company Isg @author alzq.zhf 85 | * 2014年11月15日 下午12:08:17 86 | */ 87 | public _AALBasicProtocolSubOrderDealer getSubDealer(byte _subOrder) 88 | { 89 | int iIndex = ALBasicCommonFun.byte2int(_subOrder); 90 | //编号超出数组大小,直接返回失败 91 | if(iIndex >= dealArray.length) 92 | return null; 93 | 94 | return dealArray[iIndex]; 95 | } 96 | 97 | /********************** 98 | * 根据协议编号分发协议并进行处理 99 | * 100 | * @author alzq.z 101 | * @time Feb 19, 2013 10:52:46 AM 102 | */ 103 | public boolean dispathProtocol(_IALProtocolReceiver _receiver, ByteBuffer _msg) 104 | { 105 | if(null == _msg) 106 | return false; 107 | 108 | //获取子协议编号 109 | byte subType = _msg.get(); 110 | //获取对应处理对象 111 | _AALBasicProtocolSubOrderDealer dealer = getSubDealer(subType); 112 | 113 | //判断处理对象是否有效 114 | if(null == dealer) 115 | return false; 116 | 117 | //处理对象 118 | dealer.dealProtocol(_receiver, _msg); 119 | //返回处理成功 120 | return true; 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /ALBasicProtocol/src/BasicServer/C2S_BasicClientVerifyInfo.java: -------------------------------------------------------------------------------- 1 | package BasicServer; 2 | 3 | import java.nio.ByteBuffer; 4 | public class C2S_BasicClientVerifyInfo implements ALBasicProtocolPack._IALProtocolStructure { 5 | private Integer clientType; 6 | private String userName; 7 | private String userPassword; 8 | private String customMsg; 9 | 10 | 11 | public C2S_BasicClientVerifyInfo() { 12 | clientType = 0; 13 | userName = ""; 14 | userPassword = ""; 15 | customMsg = ""; 16 | } 17 | 18 | public final byte getMainOrder() { return (byte)0; } 19 | 20 | public final byte getSubOrder() { return (byte)0; } 21 | 22 | public int getClientType() { return clientType; } 23 | public void setClientType(int _clientType) { clientType = _clientType; } 24 | public String getUserName() { return userName; } 25 | public void setUserName(String _userName) { userName = _userName; } 26 | public String getUserPassword() { return userPassword; } 27 | public void setUserPassword(String _userPassword) { userPassword = _userPassword; } 28 | public String getCustomMsg() { return customMsg; } 29 | public void setCustomMsg(String _customMsg) { customMsg = _customMsg; } 30 | 31 | 32 | public final int GetUnzipBufSize() { 33 | int _size = 4; 34 | _size += ALBasicProtocolPack.ALProtocolCommon.GetStringBufSize(userName); 35 | _size += ALBasicProtocolPack.ALProtocolCommon.GetStringBufSize(userPassword); 36 | _size += ALBasicProtocolPack.ALProtocolCommon.GetStringBufSize(customMsg); 37 | 38 | return _size; 39 | } 40 | 41 | public final int GetZipBufSize() { 42 | int _size = 0; 43 | _size += ALBasicProtocolPack.ALProtocolCommon.GetIntZipSize(clientType); 44 | _size += ALBasicProtocolPack.ALProtocolCommon.GetStringBufSize(userName); 45 | _size += ALBasicProtocolPack.ALProtocolCommon.GetStringBufSize(userPassword); 46 | _size += ALBasicProtocolPack.ALProtocolCommon.GetStringBufSize(customMsg); 47 | 48 | return _size; 49 | } 50 | 51 | 52 | 53 | public final void ReadUnzipBuf(ByteBuffer _buf) { 54 | clientType = _buf.getInt(); 55 | userName = ALBasicProtocolPack.ALProtocolCommon.GetStringFromBuf(_buf); 56 | userPassword = ALBasicProtocolPack.ALProtocolCommon.GetStringFromBuf(_buf); 57 | customMsg = ALBasicProtocolPack.ALProtocolCommon.GetStringFromBuf(_buf); 58 | } 59 | 60 | public final void ReadZipBuf(ByteBuffer _buf) { 61 | clientType = ALBasicProtocolPack.ALProtocolCommon.ZipGetIntFromBuf(_buf); 62 | userName = ALBasicProtocolPack.ALProtocolCommon.GetStringFromBuf(_buf); 63 | userPassword = ALBasicProtocolPack.ALProtocolCommon.GetStringFromBuf(_buf); 64 | customMsg = ALBasicProtocolPack.ALProtocolCommon.GetStringFromBuf(_buf); 65 | } 66 | 67 | public final void PutUnzipBuf(ByteBuffer _buf) { 68 | _buf.putInt(clientType); 69 | ALBasicProtocolPack.ALProtocolCommon.PutStringIntoBuf(_buf, userName); 70 | ALBasicProtocolPack.ALProtocolCommon.PutStringIntoBuf(_buf, userPassword); 71 | ALBasicProtocolPack.ALProtocolCommon.PutStringIntoBuf(_buf, customMsg); 72 | } 73 | 74 | public final void PutZipBuf(ByteBuffer _buf) { 75 | ALBasicProtocolPack.ALProtocolCommon.ZipPutIntIntoBuf(_buf, clientType); 76 | ALBasicProtocolPack.ALProtocolCommon.PutStringIntoBuf(_buf, userName); 77 | ALBasicProtocolPack.ALProtocolCommon.PutStringIntoBuf(_buf, userPassword); 78 | ALBasicProtocolPack.ALProtocolCommon.PutStringIntoBuf(_buf, customMsg); 79 | } 80 | 81 | public final ByteBuffer makeFullPackage() { 82 | int _bufSize = GetUnzipBufSize() + 2; 83 | ByteBuffer _buf = ByteBuffer.allocate(_bufSize); 84 | _buf.put((byte)0); 85 | _buf.put((byte)0); 86 | PutUnzipBuf(_buf); 87 | _buf.flip(); 88 | return _buf; 89 | } 90 | public final ByteBuffer makePackage() { 91 | int _bufSize = GetUnzipBufSize(); 92 | ByteBuffer _buf = ByteBuffer.allocate(_bufSize); 93 | PutUnzipBuf(_buf); 94 | _buf.flip(); 95 | return _buf; 96 | } 97 | public final void readPackage(ByteBuffer _buf) { 98 | ReadUnzipBuf(_buf); 99 | } 100 | } 101 | 102 | -------------------------------------------------------------------------------- /ALBasicServer/src/ALBasicServer/ALThread/ALMutex.java: -------------------------------------------------------------------------------- 1 | package ALBasicServer.ALThread; 2 | 3 | import java.util.concurrent.locks.ReentrantLock; 4 | 5 | import ALBasicServer.ALBasicServerConf; 6 | import ALServerLog.ALServerLog; 7 | 8 | /************************* 9 | * city of steam 项目中基本单元对象,单元对象中包含锁定解锁操作,需要自行在线程中控制
10 | * 每个线程对象同一时间只允许获取到一个锁,超过一个锁的获取操作将引发警告或错误
11 | * 线程锁根据可能分为可能的三个等级,已经获取某个等级锁的对象只允许获取下一等级对象的锁,如果发现逆序获取锁的现象将产生错误
12 | * 带入构造函数的等级数字越大表示锁等级越低
13 | * 对于锁等级的探测监控可进行开关,可在发布版本中关闭该对象
14 | * 15 | * @author alzq 16 | * 17 | */ 18 | public class ALMutex 19 | { 20 | /** 存储实际的锁对象 */ 21 | private ReentrantLock _m_lMutex; 22 | /** 锁对应的优先等级,从0开始,数字越小表示越高级 */ 23 | private int _m_iMutexPriority; 24 | 25 | public ALMutex(int _mutexLevel) 26 | { 27 | /** 锁对象初始化,带入true表示使用公平队列的加解锁排序方式 */ 28 | _m_lMutex = new ReentrantLock(true); 29 | _m_iMutexPriority = _mutexLevel; 30 | } 31 | 32 | /**************** 33 | * 获取锁的优先级 34 | * @return 35 | */ 36 | public int getPriority() 37 | { 38 | return _m_iMutexPriority; 39 | } 40 | 41 | /*************** 42 | * 增加锁的优先级 43 | */ 44 | public void addPriority() 45 | { 46 | _m_iMutexPriority--; 47 | 48 | if(_m_iMutexPriority < 0) 49 | _m_iMutexPriority = 0; 50 | } 51 | public void addPriority(int _deltaPriority) 52 | { 53 | _m_iMutexPriority -= _deltaPriority; 54 | 55 | if(_m_iMutexPriority < 0) 56 | _m_iMutexPriority = 0; 57 | } 58 | 59 | /**************** 60 | * 降低锁的优先级 61 | */ 62 | public void reducePriority() 63 | { 64 | _m_iMutexPriority++; 65 | } 66 | public void reducePriority(int _deltaPriority) 67 | { 68 | _m_iMutexPriority += _deltaPriority; 69 | } 70 | 71 | /****************** 72 | * 锁定操作 73 | * @throws CosThreadUnregThreadException 74 | */ 75 | public void lock() 76 | { 77 | //判断是否检查加锁顺序合法性 78 | if(ALBasicServerConf.getInstance().getCheckMutex()) 79 | { 80 | //获取当前线程ID 81 | long curThreadID = Thread.currentThread().getId(); 82 | 83 | //获取线程锁信息 84 | ALThreadMutexMgr threadMutexMgr = ALThreadManager.getInstance().getThreadMutexRegister(curThreadID); 85 | 86 | if(null == threadMutexMgr) 87 | { 88 | ALServerLog.Fatal("Unreg Thread try to lock mutex"); 89 | return ; 90 | } 91 | 92 | if(threadMutexMgr.tryLock(this)) 93 | { 94 | //仅当加锁成功后才进行锁定操作 95 | _m_lMutex.lock(); 96 | } 97 | } 98 | else 99 | { 100 | //不检测则直接加锁 101 | _m_lMutex.lock(); 102 | } 103 | } 104 | 105 | /****************** 106 | * 解锁操作 107 | * @throws CosThreadUnregThreadException 108 | */ 109 | public void unlock() 110 | { 111 | //判断是否检查加锁顺序合法性 112 | if(ALBasicServerConf.getInstance().getCheckMutex()) 113 | { 114 | //获取当前线程ID 115 | long curThreadID = Thread.currentThread().getId(); 116 | 117 | //获取线程锁信息 118 | ALThreadMutexMgr threadMutexMgr = ALThreadManager.getInstance().getThreadMutexRegister(curThreadID); 119 | 120 | if(null == threadMutexMgr) 121 | { 122 | ALServerLog.Fatal("Unreg Thread try to unlock mutex"); 123 | return ; 124 | } 125 | 126 | if(threadMutexMgr.tryUnlock(this)) 127 | { 128 | //仅当加锁成功后才进行解锁操作 129 | _m_lMutex.unlock(); 130 | } 131 | } 132 | else 133 | { 134 | _m_lMutex.unlock(); 135 | } 136 | } 137 | } 138 | -------------------------------------------------------------------------------- /ALServerLog/src/ALServerLog/ALServerLog.java: -------------------------------------------------------------------------------- 1 | package ALServerLog; 2 | 3 | import java.io.FileInputStream; 4 | import java.io.IOException; 5 | import java.io.InputStream; 6 | import java.nio.ByteBuffer; 7 | import java.util.Properties; 8 | 9 | import ALBasicCommon.ALConfReader; 10 | 11 | public class ALServerLog 12 | { 13 | private static LogLevel g_logLevel; 14 | private static boolean g_bInit = false; 15 | 16 | public static void initALServerLog() 17 | { 18 | if(g_bInit) 19 | return ; 20 | 21 | g_bInit = true; 22 | 23 | Properties properties = new Properties(); 24 | 25 | InputStream propertiesInputStream = null; 26 | 27 | try 28 | { 29 | propertiesInputStream = new FileInputStream("./conf/ALServerLog.properties"); 30 | } 31 | catch (IOException e) 32 | { 33 | e.printStackTrace(); 34 | } 35 | 36 | if(null == propertiesInputStream) 37 | { 38 | return; 39 | } 40 | 41 | //输入有效则开始读取对应配置 42 | try 43 | { 44 | properties.load(propertiesInputStream); 45 | } 46 | catch (IOException e) 47 | { 48 | e.printStackTrace(); 49 | } 50 | 51 | try 52 | { 53 | System.out.println("[Conf init] Load ALServerLog Properties start......"); 54 | 55 | String tmpStr 56 | = ALConfReader.readStr(properties, "ALServerLog.LogLevel", "ERROR"); 57 | g_logLevel = LogLevel.valueOf(tmpStr.toUpperCase().trim()); 58 | 59 | System.out.println("[Conf init] Finish load ALServerLog Properties ... ..."); 60 | } 61 | catch (Exception e) 62 | { 63 | System.out.println("[Conf Init Error] Load ALServerLog Properties Error!!"); 64 | g_logLevel = LogLevel.ERROR; 65 | } 66 | finally 67 | { 68 | try 69 | { 70 | propertiesInputStream.close(); 71 | } 72 | catch (IOException e) 73 | { 74 | e.printStackTrace(); 75 | } 76 | } 77 | } 78 | 79 | public static LogLevel getLogLevel() 80 | { 81 | return g_logLevel; 82 | } 83 | 84 | public static void Debug(String text) 85 | { 86 | _Log (LogLevel.DEBUG, text); 87 | } 88 | public static void Info(String text) 89 | { 90 | _Log (LogLevel.INFO, text); 91 | } 92 | public static void Warning(String text) 93 | { 94 | _Log (LogLevel.WARNING, text); 95 | } 96 | public static void Error(String text) 97 | { 98 | _Log (LogLevel.ERROR, text); 99 | } 100 | public static void Fatal(String text) 101 | { 102 | _Log (LogLevel.FATAL, ""); 103 | _Log (LogLevel.FATAL, "=================== FATAL ERR ================="); 104 | _Log (LogLevel.FATAL, text); 105 | _Log (LogLevel.FATAL, "==============================================="); 106 | _Log (LogLevel.FATAL, ""); 107 | } 108 | public static void Sys(String text) 109 | { 110 | _Log (LogLevel.SYS, text); 111 | } 112 | 113 | public static void Info(ByteBuffer _buffer) 114 | { 115 | if (g_logLevel.compareTo(LogLevel.INFO) <= 0) 116 | { 117 | StringBuffer str = new StringBuffer(); 118 | str.append(" ---- \n"); 119 | for(int i = _buffer.position(); i < _buffer.remaining(); i++) 120 | { 121 | byte b = _buffer.get(i); 122 | str.append(b + "\n"); 123 | } 124 | 125 | ALServerLog.Info(str.toString()); 126 | } 127 | } 128 | 129 | protected static void _Log(LogLevel lev, String logstr) 130 | { 131 | if (g_logLevel.compareTo(lev) <= 0) 132 | { 133 | System.out.println("[" + lev.toString() + "] " + logstr); 134 | } 135 | } 136 | 137 | public static enum LogLevel 138 | { 139 | DEBUG, // 调试信息提示 140 | INFO, // 比较重要的信息提示 141 | WARNING, // 可能存在的潜在问题的提示 142 | ERROR, // 系统发生异常的提示 143 | FATAL, // 系统发生了致命的错误的提示 144 | SYS, 145 | } 146 | } 147 | -------------------------------------------------------------------------------- /ALBasicServer/src/ALBasicServer/ALServerAsynTask/ALAsynTaskManager.java: -------------------------------------------------------------------------------- 1 | package ALBasicServer.ALServerAsynTask; 2 | 3 | import java.util.ArrayList; 4 | 5 | import ALBasicServer.ALTask._AALAsynCallAndBackTask; 6 | import ALBasicServer.ALTask._IALAsynCallBackTask; 7 | import ALBasicServer.ALTask._IALAsynCallTask; 8 | import ALBasicServer.ALTask._IALAsynRunnableTask; 9 | import ALBasicServer.ALThread.ALThreadManager; 10 | 11 | /*********************** 12 | * 异步任务处理的管理对象 13 | * 14 | * @author alzq.z 15 | * @email zhuangfan@vip.163.com 16 | * @time Feb 19, 2013 4:09:59 PM 17 | */ 18 | public class ALAsynTaskManager 19 | { 20 | private static ALAsynTaskManager g_instance = new ALAsynTaskManager(); 21 | 22 | public static ALAsynTaskManager getInstance() 23 | { 24 | return g_instance; 25 | } 26 | 27 | /** 已经排入计划的异步任务处理对象 */ 28 | private ArrayList _m_lAsynTaskThreadList; 29 | private int maxIdx; 30 | 31 | /** 系统异步任务处理线程对象 */ 32 | private ALAsynTaskThread _m_tSystemAsynTaskThread; 33 | 34 | public ALAsynTaskManager() 35 | { 36 | _m_lAsynTaskThreadList = null; 37 | maxIdx = -1; 38 | 39 | _m_tSystemAsynTaskThread = null; 40 | } 41 | 42 | /***************** 43 | * 初始化所有的异步任务处理线程,带入处理线程数量 44 | * 45 | * @author alzq.z 46 | * @time Feb 20, 2013 10:51:29 PM 47 | */ 48 | public void init(int _asynTaskThreadCount) 49 | { 50 | //初始化系统异步处理线程 51 | _m_tSystemAsynTaskThread = ALThreadManager.getInstance().createAsynTaskThread(); 52 | 53 | //最少一个异步线程 54 | if(_asynTaskThreadCount <= 0) 55 | _asynTaskThreadCount = 1; 56 | 57 | _m_lAsynTaskThreadList = new ArrayList(_asynTaskThreadCount); 58 | 59 | for(int i = 0; i < _asynTaskThreadCount; i++) 60 | { 61 | //逐个创建线程 62 | _m_lAsynTaskThreadList.add(ALThreadManager.getInstance().createAsynTaskThread()); 63 | } 64 | 65 | maxIdx = _asynTaskThreadCount - 1; 66 | } 67 | 68 | /*************** 69 | * 为指定序号的异步处理线程加入回调类型异步任务处理 70 | * 71 | * @author alzq.z 72 | * @time Feb 19, 2013 4:09:01 PM 73 | */ 74 | public void regTask(int _threadIdx, _IALAsynCallTask _callObj, _IALAsynCallBackTask _callBackObj) 75 | { 76 | if(_threadIdx > maxIdx || _threadIdx < 0) 77 | _threadIdx = 0; 78 | 79 | //注册任务 80 | _m_lAsynTaskThreadList.get(_threadIdx)._getTaskManager().regTask(_callObj, _callBackObj); 81 | } 82 | 83 | /*************** 84 | * 为指定序号的异步处理线程加入回调类型异步任务处理 85 | * 86 | * @author alzq.z 87 | * @time Feb 19, 2013 4:09:01 PM 88 | */ 89 | public void regTask(int _threadIdx, _AALAsynCallAndBackTask _task) 90 | { 91 | if(_threadIdx > maxIdx || _threadIdx < 0) 92 | _threadIdx = 0; 93 | 94 | //注册任务 95 | _m_lAsynTaskThreadList.get(_threadIdx)._getTaskManager().regTask(_task, _task); 96 | } 97 | 98 | /***************** 99 | * 为指定序号的异步处理线程加入执行类异步任务处理 100 | * 101 | * @author alzq.z 102 | * @time Feb 19, 2013 4:09:29 PM 103 | */ 104 | public void regTask(int _threadIdx, _IALAsynRunnableTask _runTask) 105 | { 106 | if(_threadIdx > maxIdx || _threadIdx < 0) 107 | _threadIdx = 0; 108 | 109 | //注册任务 110 | _m_lAsynTaskThreadList.get(_threadIdx)._getTaskManager().regTask(_runTask); 111 | } 112 | 113 | /*************** 114 | * 为系统异步处理线程加入回调类型异步任务处理 115 | * 116 | * @author alzq.z 117 | * @time Feb 19, 2013 4:09:01 PM 118 | */ 119 | public void regSysTask(_IALAsynCallTask _callObj, _IALAsynCallBackTask _callBackObj) 120 | { 121 | //注册任务 122 | _m_tSystemAsynTaskThread._getTaskManager().regTask(_callObj, _callBackObj); 123 | } 124 | 125 | /***************** 126 | * 为系统异步处理线程加入执行类异步任务处理 127 | * 128 | * @author alzq.z 129 | * @time Feb 19, 2013 4:09:29 PM 130 | */ 131 | public void regSysTask(_IALAsynRunnableTask _runTask) 132 | { 133 | //注册任务 134 | _m_tSystemAsynTaskThread._getTaskManager().regTask(_runTask); 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /ALBasicServer/src/ALBasicServer/ALThread/ALThreadManager.java: -------------------------------------------------------------------------------- 1 | package ALBasicServer.ALThread; 2 | 3 | import java.util.Hashtable; 4 | 5 | import ALBasicServer.ALServerAsynTask.ALAsynTaskThread; 6 | import ALBasicServer.ALServerCmd.ALCmdLineReadThread; 7 | import ALBasicServer.ALServerSynTask.ALSynTaskDealThread; 8 | import ALBasicServer.ALServerSynTask.ALSynTimingTaskCheckThread; 9 | import ALBasicServer.ALSocket.ALServerSocketSendThread; 10 | import ALServerLog.ALServerLog; 11 | 12 | /*********************** 13 | * 线程注册控制对象,每个由系统开启的线程将在此对象中注册
14 | * 并由注册的队列进行锁获取的相关检查和控制操作
15 | * 16 | * @author alzq 17 | * 18 | */ 19 | public class ALThreadManager 20 | { 21 | private static ALThreadManager g_instance = new ALThreadManager(); 22 | 23 | public static ALThreadManager getInstance() 24 | { 25 | if(null == g_instance) 26 | g_instance = new ALThreadManager(); 27 | 28 | return g_instance; 29 | } 30 | 31 | /** 存储所有线程ID对应线程中锁信息的表 */ 32 | private Hashtable _m_htThreadMutexInfoTable; 33 | 34 | protected ALThreadManager() 35 | { 36 | _m_htThreadMutexInfoTable = new Hashtable(); 37 | } 38 | 39 | /********************* 40 | * 开启命令行读取处理线程 41 | * 42 | * @author alzq.z 43 | * @time Feb 18, 2013 10:36:17 PM 44 | */ 45 | public ALCmdLineReadThread createCmdReadThread() 46 | { 47 | ALCmdLineReadThread readThread = new ALCmdLineReadThread(); 48 | //开启线程 49 | readThread.start(); 50 | 51 | return readThread; 52 | } 53 | 54 | /********************* 55 | * 开启任务执行线程,并返回该线程的控制对象 56 | * 57 | * @author alzq.z 58 | * @time Feb 18, 2013 10:36:17 PM 59 | */ 60 | public ALSynTaskDealThread createTaskDealThread() 61 | { 62 | ALSynTaskDealThread normalTaskDealThread = new ALSynTaskDealThread(); 63 | //开启线程 64 | normalTaskDealThread.start(); 65 | 66 | return normalTaskDealThread; 67 | } 68 | 69 | /*************** 70 | * 开启定时任务监控线程,此线程全局只开一个,并返回该线程的控制对象 71 | * 72 | * @author alzq.z 73 | * @time Feb 18, 2013 11:43:24 PM 74 | */ 75 | public ALSynTimingTaskCheckThread createTimingTaskCheckThread() 76 | { 77 | ALSynTimingTaskCheckThread timingTaskDealThread = new ALSynTimingTaskCheckThread(); 78 | //开启线程 79 | timingTaskDealThread.start(); 80 | 81 | return timingTaskDealThread; 82 | } 83 | 84 | /*************** 85 | * 开启Socket发送线程,并返回该线程的控制对象 86 | * 87 | * @author alzq.z 88 | * @time Feb 19, 2013 4:33:19 PM 89 | */ 90 | public ALServerSocketSendThread createSocketSendThread() 91 | { 92 | ALServerSocketSendThread socketSendThread = new ALServerSocketSendThread(); 93 | //开启线程 94 | socketSendThread.start(); 95 | 96 | return socketSendThread; 97 | } 98 | 99 | /*************** 100 | * 开启异步处理线程,并返回该线程的控制对象 101 | * 102 | * @author alzq.z 103 | * @time Feb 19, 2013 4:29:31 PM 104 | */ 105 | public ALAsynTaskThread createAsynTaskThread() 106 | { 107 | ALAsynTaskThread asynTaskThread = new ALAsynTaskThread(); 108 | //开启线程 109 | asynTaskThread.start(); 110 | 111 | return asynTaskThread; 112 | } 113 | 114 | /*************** 115 | * 在工程中注册一个线程对象 116 | * 117 | * @author alzq.z 118 | * @time Feb 19, 2013 4:29:23 PM 119 | */ 120 | public ALThreadMutexMgr regThread(long _threadID) 121 | { 122 | if(_m_htThreadMutexInfoTable.containsKey(_threadID)) 123 | return null; 124 | 125 | ALServerLog.Info("Reg thread: " + _threadID); 126 | 127 | ALThreadMutexMgr threadMutexMgr = new ALThreadMutexMgr(_threadID); 128 | _m_htThreadMutexInfoTable.put(_threadID, threadMutexMgr); 129 | 130 | return threadMutexMgr; 131 | } 132 | 133 | /**************** 134 | * 获取对应线程的锁信息控制对象 135 | * 136 | * @author alzq.z 137 | * @time Feb 18, 2013 11:47:30 PM 138 | */ 139 | public ALThreadMutexMgr getThreadMutexRegister(long _threadID) 140 | { 141 | return _m_htThreadMutexInfoTable.get(_threadID); 142 | } 143 | } 144 | -------------------------------------------------------------------------------- /ALBasicServer/src/ALBasicServer/ALBasicServerConf.java: -------------------------------------------------------------------------------- 1 | package ALBasicServer; 2 | 3 | import java.io.FileInputStream; 4 | import java.io.IOException; 5 | import java.io.InputStream; 6 | import java.util.Properties; 7 | 8 | import ALBasicCommon.ALConfReader; 9 | 10 | 11 | public class ALBasicServerConf 12 | { 13 | private static ALBasicServerConf g_instance; 14 | 15 | public static ALBasicServerConf getInstance() 16 | { 17 | if(null == g_instance) 18 | g_instance = new ALBasicServerConf(); 19 | 20 | return g_instance; 21 | } 22 | 23 | /** 服务器标识 */ 24 | private String _m_sServerTag; 25 | /** 是否检测锁对象的获取 */ 26 | private boolean _m_bCheckMutex; 27 | /** 开启执行任务的线程数量 */ 28 | private int _m_iSynTaskThreadNum; 29 | /** Socket消息发送的线程数量 */ 30 | private int _m_iSendThreadNum; 31 | /** 定时任务检测时间的精度 */ 32 | private int _m_iTimerCheckTime; 33 | /** 定时任务的大区间长度,根据精度和长度可以决定一个区间的时间跨度 */ 34 | private int _m_iTimerCheckAreaSize; 35 | 36 | public ALBasicServerConf() 37 | { 38 | _m_sServerTag = "AL Server"; 39 | _m_bCheckMutex = true; 40 | _m_iSynTaskThreadNum = 4; 41 | _m_iSendThreadNum = 1; 42 | _m_iTimerCheckTime = 20; 43 | _m_iTimerCheckAreaSize = 5000; 44 | } 45 | 46 | public String getServerTag() {return _m_sServerTag;} 47 | public boolean getCheckMutex() {return _m_bCheckMutex;} 48 | public int getSynTaskThreadNum() {return _m_iSynTaskThreadNum;} 49 | public int getSendThreadNum() {return _m_iSendThreadNum;} 50 | public int getTimerCheckTime() {return _m_iTimerCheckTime;} 51 | public int getTimerCheckAreaSize() {return _m_iTimerCheckAreaSize;} 52 | 53 | /******************* 54 | * 初始化属性设置对象,返回是否成功 55 | * @param _properties 56 | */ 57 | public boolean init() 58 | { 59 | Properties properties = new Properties(); 60 | 61 | InputStream propertiesInputStream = null; 62 | 63 | try 64 | { 65 | propertiesInputStream = new FileInputStream("./conf/ALBasicServerConf.properties"); 66 | } 67 | catch (Exception e) 68 | { 69 | e.printStackTrace(); 70 | } 71 | 72 | if(null == propertiesInputStream) 73 | { 74 | return false; 75 | } 76 | 77 | //输入有效则开始读取对应配置 78 | try 79 | { 80 | properties.load(propertiesInputStream); 81 | } 82 | catch (IOException e) 83 | { 84 | e.printStackTrace(); 85 | } 86 | 87 | try 88 | { 89 | System.out.println("[Conf init] Start load ALBasicServer Properties ... ..."); 90 | 91 | //服务器标记 92 | _m_sServerTag 93 | = ALConfReader.readStr(properties, "ALBasicServer.ServerTag", _m_sServerTag); 94 | 95 | //服务器开启同步逻辑处理的线程数量 96 | _m_iSynTaskThreadNum 97 | = ALConfReader.readInt(properties, "ALBasicServer.SynTaskDealThreadNum", _m_iSynTaskThreadNum); 98 | 99 | //服务器Socket返回消息的发送线程数量 100 | _m_iSendThreadNum 101 | = ALConfReader.readInt(properties, "ALBasicServer.ServerSendBackDealThreadNum", _m_iSendThreadNum); 102 | 103 | //服务器内部任务处理的时间间隔最小片段长度 104 | _m_iTimerCheckTime 105 | = ALConfReader.readInt(properties, "ALBasicServer.TimerCheckTime", _m_iTimerCheckTime); 106 | 107 | //定时任务的大区间长度,根据精度和长度可以决定一个区间的时间跨度 108 | _m_iTimerCheckAreaSize 109 | = ALConfReader.readInt(properties, "ALBasicServer.TimerCheckAreaSize", _m_iTimerCheckAreaSize); 110 | 111 | //是否在线程内进行死锁的检测 112 | _m_bCheckMutex 113 | = ALConfReader.readBool(properties, "ALBasicServer.CheckMutex", _m_bCheckMutex); 114 | 115 | System.out.println("[Conf init] Finish load ALBasicServer Properties ... ..."); 116 | } 117 | catch (Exception e) 118 | { 119 | System.out.println("[Conf Init Error] Load ALBasicServer Properties Error!!"); 120 | e.printStackTrace(); 121 | } 122 | finally 123 | { 124 | try 125 | { 126 | propertiesInputStream.close(); 127 | } 128 | catch (IOException e) 129 | { 130 | e.printStackTrace(); 131 | } 132 | } 133 | 134 | return true; 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /ALBasicServer/src/ALBasicServer/ALVerifyObj/ALVerifyObjMgr.java: -------------------------------------------------------------------------------- 1 | package ALBasicServer.ALVerifyObj; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Hashtable; 5 | import java.util.concurrent.locks.ReentrantLock; 6 | 7 | import ALBasicServer.ALServerAsynTask.ALAsynTaskManager; 8 | import ALBasicServer.ALServerSynTask.ALSynTaskManager; 9 | import ALBasicServer.ALSocket.ALBasicServerSocket; 10 | import ALBasicServer.ALSocket._AALBasicServerSocketListener; 11 | import ALBasicServer.ALSocket.ALServerSocketMgr; 12 | import BasicServer.S2C_BasicClientVerifyResult; 13 | 14 | /****************** 15 | * 连接Socket验证的管理对象 16 | * 17 | * @author alzq.z 18 | * @email zhuangfan@vip.163.com 19 | * @time Feb 19, 2013 2:36:33 PM 20 | */ 21 | public class ALVerifyObjMgr 22 | { 23 | private static int g_verifySerialize = 1; 24 | private static ALVerifyObjMgr g_instance = new ALVerifyObjMgr(); 25 | 26 | public static ALVerifyObjMgr getInstance() 27 | { 28 | if(null == g_instance) 29 | g_instance = new ALVerifyObjMgr(); 30 | 31 | return g_instance; 32 | } 33 | 34 | private Hashtable _m_htVerifySocket; 35 | /** 验证处理对象的队列 */ 36 | private ReentrantLock _m_mutex; 37 | private ArrayList<_IALVerifyFun> _m_arrVerifyFunList; 38 | 39 | public ALVerifyObjMgr() 40 | { 41 | _m_htVerifySocket = new Hashtable(); 42 | 43 | _m_mutex = new ReentrantLock(); 44 | _m_arrVerifyFunList = new ArrayList<_IALVerifyFun>(); 45 | } 46 | 47 | /************ 48 | * 注册一个验证处理对象,并返回验证处理对象的下标 49 | * 50 | * @author alzq.z 51 | * @time Jan 22, 2014 11:50:33 PM 52 | */ 53 | public int regVerifyObj(_IALVerifyFun _verifyFun) 54 | { 55 | _m_mutex.lock(); 56 | 57 | int newIdx = _m_arrVerifyFunList.size(); 58 | _m_arrVerifyFunList.add(_verifyFun); 59 | 60 | _m_mutex.unlock(); 61 | 62 | return newIdx; 63 | } 64 | 65 | /************ 66 | * 获取验证处理的对象 67 | * 68 | * @author alzq.z 69 | * @time Jan 22, 2014 11:50:33 PM 70 | */ 71 | public _IALVerifyFun getVerifyObj(int _verifyFunIdx) 72 | { 73 | _m_mutex.lock(); 74 | 75 | try 76 | { 77 | return _m_arrVerifyFunList.get(_verifyFunIdx); 78 | } 79 | finally 80 | { 81 | _m_mutex.unlock(); 82 | } 83 | } 84 | 85 | /**************** 86 | * 添加一个需要验证的Socket对象 87 | * 88 | * @author alzq.z 89 | * @time Feb 19, 2013 2:37:43 PM 90 | */ 91 | public void addVerifySocket(ALBasicServerSocket _socket) 92 | { 93 | int serialize = _getSerizlize(); 94 | 95 | _m_htVerifySocket.put(serialize, _socket); 96 | 97 | //开启一个异步任务用于验证Socket的合法性 98 | ALAsynTaskManager.getInstance().regSysTask(new AsynRun_UserLoginTask(serialize, _socket)); 99 | 100 | //开启定时任务检测是否登录超时,超时则直接按照失败处理 101 | ALSynTaskManager.getInstance().regTask(new SynCheckVerifyLoginTimeOutTask(serialize), 30000); 102 | } 103 | 104 | /************* 105 | * 带入处理序列号,设置处理结果。 106 | * 107 | * @author alzq.z 108 | * @time Feb 19, 2013 2:41:52 PM 109 | */ 110 | protected void _comfirmVerifyResult(int _serialize, _AALBasicServerSocketListener _listener) 111 | { 112 | _comfirmVerifyResult(_serialize, _listener, ""); 113 | } 114 | protected void _comfirmVerifyResult(int _serialize, _AALBasicServerSocketListener _listener, String _customRetMsg) 115 | { 116 | ALBasicServerSocket socket = _m_htVerifySocket.remove(_serialize); 117 | 118 | if(null == socket) 119 | return ; 120 | 121 | if(null == _listener) 122 | { 123 | ALServerSocketMgr.getInstance().kickUser(socket); 124 | } 125 | else 126 | { 127 | //设置Socket和Listener相互的关联 128 | socket.setListener(_listener); 129 | _listener.setSocket(socket); 130 | 131 | socket.setLoginEnd(); 132 | 133 | //创建返回协议 134 | S2C_BasicClientVerifyResult retMsg = new S2C_BasicClientVerifyResult(); 135 | retMsg.setSocketID(socket.getSocketID()); 136 | retMsg.setCustomRetMsg(_customRetMsg); 137 | 138 | //发送登录完成的协议返回 139 | _listener.send(retMsg.makePackage()); 140 | 141 | _listener.login(); 142 | } 143 | } 144 | 145 | /*************** 146 | * 获取新的验证序列号 147 | * 148 | * @author alzq.z 149 | * @time Feb 19, 2013 3:14:37 PM 150 | */ 151 | private synchronized int _getSerizlize() 152 | { 153 | return g_verifySerialize++; 154 | } 155 | } 156 | -------------------------------------------------------------------------------- /ALBasicClient/src/ALBasicClient/ALBasicClientRecThread.java: -------------------------------------------------------------------------------- 1 | package ALBasicClient; 2 | 3 | import java.io.IOException; 4 | import java.net.InetSocketAddress; 5 | import java.nio.ByteBuffer; 6 | import java.nio.channels.SelectionKey; 7 | import java.nio.channels.Selector; 8 | import java.nio.channels.SocketChannel; 9 | import java.util.Iterator; 10 | import java.util.Set; 11 | 12 | import ALBasicCommon._AALBasicThread; 13 | import ALServerLog.ALServerLog; 14 | import BasicServer.C2S_BasicClientVerifyInfo; 15 | 16 | public class ALBasicClientRecThread extends _AALBasicThread 17 | { 18 | /** 客户端对象类型 */ 19 | private int _m_iClientType; 20 | /** 登录验证信息 */ 21 | private String _m_sUserName; 22 | private String _m_sUserPassword; 23 | /** 登录时发送的自定义信息 */ 24 | private String _m_sCustomMsg; 25 | /** 线程是否退出 */ 26 | private boolean _m_bThreadExit; 27 | private ALBasicClientSocket _m_scSocket; 28 | private SocketChannel _m_SocketChannel; 29 | private String _m_sServerIP; 30 | private int _m_iServerPort; 31 | 32 | public ALBasicClientRecThread(int _clientType, String _userName, String _userPassword, String _customMsg, ALBasicClientSocket _socket, String _serverIP, int _serverPort) 33 | { 34 | _m_iClientType = _clientType; 35 | _m_sUserName = _userName; 36 | _m_sUserPassword = _userPassword; 37 | _m_sCustomMsg = _customMsg; 38 | _m_bThreadExit = false; 39 | _m_scSocket = _socket; 40 | _m_sServerIP = _serverIP; 41 | _m_iServerPort = _serverPort; 42 | _m_SocketChannel = null; 43 | } 44 | 45 | public void ExitThread() 46 | { 47 | _m_bThreadExit = true; 48 | } 49 | 50 | /****************** 51 | * 线程执行函数 52 | * 53 | * @author alzq.z 54 | * @time Feb 20, 2013 11:03:08 PM 55 | */ 56 | @Override 57 | protected void _run() 58 | { 59 | Selector clientSelector = null; 60 | try 61 | { 62 | clientSelector = Selector.open(); 63 | _m_SocketChannel = _m_scSocket._getSocketChannel(); 64 | 65 | InetSocketAddress address = new InetSocketAddress(_m_sServerIP, _m_iServerPort); 66 | if(!_m_SocketChannel.connect(address)) 67 | { 68 | _m_scSocket._logout(); 69 | return ; 70 | } 71 | 72 | _m_SocketChannel.configureBlocking(false); 73 | _m_SocketChannel.register(clientSelector, SelectionKey.OP_READ); 74 | 75 | //发送登录请求 76 | C2S_BasicClientVerifyInfo msg = new C2S_BasicClientVerifyInfo(); 77 | msg.setClientType(_m_iClientType); 78 | msg.setUserName(_m_sUserName); 79 | msg.setUserPassword(_m_sUserPassword); 80 | if(null == _m_sCustomMsg) 81 | msg.setCustomMsg(""); 82 | else 83 | msg.setCustomMsg(_m_sCustomMsg); 84 | 85 | _m_scSocket.send(msg.makePackage()); 86 | } 87 | catch (Exception ex) 88 | { 89 | _m_scSocket._logout(); 90 | return ; 91 | } 92 | 93 | //创建接收BUF 94 | ByteBuffer recBuffer = ByteBuffer.allocate(ALBasicClientConf.getInstance().getRecBufferLen() * 2); 95 | 96 | //开启循环处理Socket事件 97 | while(!_m_bThreadExit) 98 | { 99 | try 100 | { 101 | clientSelector.select(); 102 | } catch (Exception e) { 103 | ALServerLog.Fatal("Client port select event error!!"); 104 | e.printStackTrace(); 105 | } 106 | 107 | //循环获取到的事件 108 | Set readyKeySet = clientSelector.selectedKeys(); 109 | Iterator iter = readyKeySet.iterator(); 110 | while(iter.hasNext()) 111 | { 112 | SelectionKey key = (SelectionKey)iter.next(); 113 | //移除已经取出的事件 114 | iter.remove(); 115 | 116 | if(key.isReadable()) 117 | { 118 | //收到数据 119 | SocketChannel socketChannel = (SocketChannel)key.channel(); 120 | 121 | //读取数据 122 | try 123 | { 124 | recBuffer.clear(); 125 | //此时进行读取,当读取的包大小超过存储区域则可能导致数据读取不全 126 | int recLen = socketChannel.read(recBuffer); 127 | //设置限制,并将读取位置归0 128 | recBuffer.flip(); 129 | 130 | if(recLen < 0) 131 | { 132 | _m_scSocket._logout(); 133 | return ; 134 | } 135 | 136 | if(recLen > 0) 137 | { 138 | //处理消息读取 139 | _m_scSocket._socketReceivingMessage(recBuffer); 140 | } 141 | } 142 | catch (IOException e) 143 | { 144 | _m_scSocket._logout(); 145 | return ; 146 | } 147 | catch (Exception e) 148 | { 149 | ALServerLog.Fatal("Client port read buffer error!!"); 150 | e.printStackTrace(); 151 | } 152 | } 153 | } 154 | } 155 | } 156 | } 157 | -------------------------------------------------------------------------------- /ALBasicServer/src/ALBasicServer/ALServerCmd/ALCmdDealerManager.java: -------------------------------------------------------------------------------- 1 | package ALBasicServer.ALServerCmd; 2 | 3 | import java.util.ArrayList; 4 | import java.util.LinkedList; 5 | import java.util.concurrent.locks.ReentrantLock; 6 | 7 | import ALBasicServer.ALServerSynTask.ALSynTaskManager; 8 | 9 | /********************** 10 | * 命令行处理对象的注册处理函数 11 | * 12 | * @author alzq.z 13 | * @email zhuangfan@vip.163.com 14 | * @time Oct 5, 2013 11:06:51 AM 15 | */ 16 | public class ALCmdDealerManager 17 | { 18 | private static ALCmdDealerManager _g_instance = new ALCmdDealerManager(); 19 | public static ALCmdDealerManager getInstance() 20 | { 21 | if(null == _g_instance) 22 | _g_instance = new ALCmdDealerManager(); 23 | 24 | return _g_instance; 25 | } 26 | 27 | /** 注册的命令行处理对象队列 */ 28 | private ArrayList<_IALBasicServerCmdDealer> _m_lCmdDealerList; 29 | /** 处理对象的队列锁 */ 30 | private ReentrantLock _m_dealerMutex; 31 | 32 | /** 已经输入的命令行数据存储 */ 33 | private LinkedList _m_lCmdList; 34 | /** 处理内容队列锁 */ 35 | private ReentrantLock _m_cmdMutex; 36 | 37 | protected ALCmdDealerManager() 38 | { 39 | _m_lCmdDealerList = new ArrayList<_IALBasicServerCmdDealer>(); 40 | _m_dealerMutex = new ReentrantLock(); 41 | 42 | _m_lCmdList = new LinkedList<>(); 43 | _m_cmdMutex = new ReentrantLock(); 44 | } 45 | 46 | /**************** 47 | * 增加命令行对象 48 | * 49 | * @author alzq.z 50 | * @time Oct 5, 2013 11:36:33 AM 51 | */ 52 | public void addCmd(String _cmd) 53 | { 54 | //添加到命令行队列中,并判断是否需要开启任务 55 | _lockCmd(); 56 | 57 | boolean needStartTask = false; 58 | 59 | if(_m_lCmdList.isEmpty()) 60 | needStartTask = true; 61 | 62 | _m_lCmdList.add(_cmd); 63 | 64 | _unlockCmd(); 65 | 66 | //原队列为空则注册任务开启对应操作的执行 67 | if(needStartTask) 68 | ALSynTaskManager.getInstance().regTask(new ALSynCmdDealTask()); 69 | } 70 | 71 | /****************** 72 | * 获取当前处理对象的队列 73 | * 74 | * @author alzq.z 75 | * @time Oct 5, 2013 11:49:21 AM 76 | */ 77 | public ArrayList<_IALBasicServerCmdDealer> getDealerList() 78 | { 79 | _lockDealer(); 80 | 81 | ArrayList<_IALBasicServerCmdDealer> resList = _m_lCmdDealerList; 82 | 83 | _unlockDealer(); 84 | 85 | return resList; 86 | } 87 | 88 | /*************** 89 | * 注册命令处理对象队列 90 | * 91 | * @author alzq.z 92 | * @time Oct 5, 2013 11:36:50 AM 93 | */ 94 | public void regDealer(_IALBasicServerCmdDealer _dealer) 95 | { 96 | _lockDealer(); 97 | 98 | ArrayList<_IALBasicServerCmdDealer> newCmdDealerList = 99 | new ArrayList<_IALBasicServerCmdDealer>(_m_lCmdDealerList.size() + 1); 100 | 101 | newCmdDealerList.addAll(_m_lCmdDealerList); 102 | newCmdDealerList.add(_dealer); 103 | 104 | //替换队列 105 | _m_lCmdDealerList = newCmdDealerList; 106 | 107 | _unlockDealer(); 108 | } 109 | 110 | /*************** 111 | * 注销命令处理对象队列 112 | * 113 | * @author alzq.z 114 | * @time Oct 5, 2013 11:36:50 AM 115 | */ 116 | public void unregDealer(_IALBasicServerCmdDealer _dealer) 117 | { 118 | _lockDealer(); 119 | 120 | ArrayList<_IALBasicServerCmdDealer> newCmdDealerList = 121 | new ArrayList<_IALBasicServerCmdDealer>(_m_lCmdDealerList.size()); 122 | 123 | newCmdDealerList.addAll(_m_lCmdDealerList); 124 | 125 | //移除处理对象 126 | newCmdDealerList.remove(_dealer); 127 | 128 | //替换队列 129 | _m_lCmdDealerList = newCmdDealerList; 130 | 131 | _unlockDealer(); 132 | } 133 | 134 | /**************** 135 | * 处理命令行操作对象 136 | * 137 | * @author alzq.z 138 | * @time Oct 5, 2013 11:36:33 AM 139 | */ 140 | protected void _dealCmd() 141 | { 142 | String cmd = null; 143 | boolean needStartTask = false; 144 | 145 | //添加到命令行队列中,并判断是否需要开启任务 146 | _lockCmd(); 147 | 148 | if(!_m_lCmdList.isEmpty()) 149 | { 150 | //取第一个命令行 151 | cmd = _m_lCmdList.getFirst(); 152 | } 153 | 154 | _unlockCmd(); 155 | 156 | //获取处理队列 157 | ArrayList<_IALBasicServerCmdDealer> dealerList = getDealerList(); 158 | 159 | if(null != cmd) 160 | { 161 | //非空才进行处理 162 | for(int i = 0; i < dealerList.size(); i++) 163 | { 164 | _IALBasicServerCmdDealer dealer = dealerList.get(i); 165 | 166 | if(null == dealer) 167 | continue; 168 | 169 | try 170 | { 171 | dealer.dealCmd(cmd); 172 | } 173 | catch (Exception e) 174 | { 175 | e.printStackTrace(); 176 | } 177 | } 178 | } 179 | 180 | _lockCmd(); 181 | 182 | //取出第一个命令行 183 | _m_lCmdList.pop(); 184 | 185 | //判断命令行是否为空 186 | if(!_m_lCmdList.isEmpty()) 187 | needStartTask = true; 188 | 189 | _unlockCmd(); 190 | 191 | //原队列为空则注册任务开启对应操作的执行 192 | if(needStartTask) 193 | ALSynTaskManager.getInstance().regTask(new ALSynCmdDealTask()); 194 | } 195 | 196 | protected void _lockCmd() 197 | { 198 | _m_cmdMutex.lock(); 199 | } 200 | protected void _unlockCmd() 201 | { 202 | _m_cmdMutex.unlock(); 203 | } 204 | 205 | protected void _lockDealer() 206 | { 207 | _m_dealerMutex.lock(); 208 | } 209 | protected void _unlockDealer() 210 | { 211 | _m_dealerMutex.unlock(); 212 | } 213 | } 214 | -------------------------------------------------------------------------------- /ALBasicServer/src/ALBasicServer/ALThread/ALThreadMutexMgr.java: -------------------------------------------------------------------------------- 1 | package ALBasicServer.ALThread; 2 | 3 | import java.util.ArrayList; 4 | 5 | import ALServerLog.ALServerLog; 6 | 7 | /************************ 8 | * 线程中锁对象信息保存控制
9 | * 存储一个线程获取的锁对象的信息
10 | * 11 | * @author alzq 12 | * 13 | */ 14 | public class ALThreadMutexMgr 15 | { 16 | /** 所属线程ID */ 17 | private long _m_lThreadID; 18 | /** 线程已经获取的锁对象信息存储表 */ 19 | private ArrayList _m_lThreadMutexList; 20 | 21 | public ALThreadMutexMgr(long _threadID) 22 | { 23 | _m_lThreadID = _threadID; 24 | _m_lThreadMutexList = new ArrayList(); 25 | } 26 | 27 | /************ 28 | * 获取线程ID 29 | * @return 30 | */ 31 | public long getThreadID() 32 | { 33 | return _m_lThreadID; 34 | } 35 | 36 | /******************** 37 | * 尝试对对象进行加锁 38 | * 39 | * @author alzq.z 40 | * @time Feb 18, 2013 10:27:51 PM 41 | */ 42 | public boolean tryLock(ALMutex _cosObj) 43 | { 44 | if(null == _cosObj) 45 | return false; 46 | 47 | //默认当前加锁对象为空,表示无已经加锁的相同对象 48 | ALMutexInfo mutexInfo = null; 49 | if(!_isMutexListEmpty()) 50 | { 51 | //根据最低等级锁对象判断是否可对该对象进行加锁 52 | ALMutexInfo topLvMutexInfo = _getLowestPriorityMutex(); 53 | 54 | //判断最低等级锁是否比加锁对象还高级,当比加锁对象高级时,表示可以直接加锁 55 | if(topLvMutexInfo.getMutexPriority() >= _cosObj.getPriority()) 56 | { 57 | //当需要枷锁的对象锁等级比最低等级还要高时(数字小) 58 | //判断加锁对象是否在队列中已经加过锁了,如果已经加过锁此时是安全的 59 | mutexInfo = _getMutexByPriority(_cosObj.getPriority()); 60 | if(null == mutexInfo || mutexInfo.getObj() != _cosObj) 61 | { 62 | //尝试获取等级高的锁,返回错误 63 | ALServerLog.Fatal("无法获取高等级锁"); 64 | //输出堆栈 65 | new Exception().printStackTrace(); 66 | //直接返回,不进行加锁处理 67 | return false; 68 | } 69 | } 70 | } 71 | 72 | if(null == mutexInfo) 73 | { 74 | mutexInfo = new ALMutexInfo(_cosObj); 75 | //将锁信息添加到队列中,由于可以加锁的对象一定是最低级的锁,所以直接使用添加最低优先级锁函数 76 | _addLowestPriorityMutex(mutexInfo); 77 | } 78 | 79 | //加锁 80 | mutexInfo.addLockTime(); 81 | 82 | return true; 83 | } 84 | 85 | /*************** 86 | * 尝试对对象进行解锁 87 | * 88 | * @author alzq.z 89 | * @time Feb 18, 2013 10:27:42 PM 90 | */ 91 | public boolean tryUnlock(ALMutex _cosObj) 92 | { 93 | if(null == _cosObj) 94 | return false; 95 | 96 | //获取同优先级的锁对象 97 | ALMutexInfo mutexInfo = _getMutexByPriority(_cosObj.getPriority()); 98 | 99 | //本线程并未获取该优先级的锁,或同优先级锁并不是同一个时,表示解锁失败 100 | if(null == mutexInfo || mutexInfo.getObj() != _cosObj) 101 | { 102 | ALServerLog.Fatal("尝试释放未获取的锁"); 103 | //输出堆栈 104 | new Exception().printStackTrace(); 105 | //直接返回,不进行加锁处理 106 | return false; 107 | } 108 | 109 | //释放锁 110 | mutexInfo.reduceLockTime(); 111 | 112 | if(mutexInfo.getLockTime() <= 0) 113 | { 114 | //次数低于0时从队列删除 115 | _removeMutexLevelInfo(mutexInfo); 116 | } 117 | 118 | return true; 119 | } 120 | 121 | /***************** 122 | * 判断当前线程是否释放所有锁 123 | * 124 | * @author alzq.z 125 | * @time Feb 18, 2013 11:22:22 PM 126 | */ 127 | public boolean judgeAllMutexRelease() 128 | { 129 | return _m_lThreadMutexList.isEmpty(); 130 | } 131 | 132 | /******************** 133 | * 释放所有本线程获取的对象锁 134 | * 135 | * @author alzq.z 136 | * @time Feb 18, 2013 11:22:29 PM 137 | */ 138 | public void releaseAllMutex() 139 | { 140 | //清空队列中每个锁对象的加锁信息 141 | while(!_m_lThreadMutexList.isEmpty()) 142 | { 143 | ALMutexInfo info = _m_lThreadMutexList.get(0); 144 | 145 | if(null == info) 146 | continue; 147 | 148 | //释放所有锁 149 | info.releaseAllLock(); 150 | } 151 | 152 | //清空队列 153 | _m_lThreadMutexList.clear(); 154 | } 155 | 156 | /********** 157 | * 加锁队列是否为空 158 | * 159 | * @author alzq.z 160 | * @time Feb 18, 2013 10:24:59 PM 161 | */ 162 | protected boolean _isMutexListEmpty() 163 | { 164 | return _m_lThreadMutexList.isEmpty(); 165 | } 166 | 167 | /******************* 168 | * 查询本线程中指定优先级的锁对象 169 | * 170 | * @author alzq.z 171 | * @time Feb 18, 2013 10:17:26 PM 172 | */ 173 | protected ALMutexInfo _getMutexByPriority(int _priority) 174 | { 175 | for(int i = 0; i < _m_lThreadMutexList.size(); i ++) 176 | { 177 | ALMutexInfo info = _m_lThreadMutexList.get(i); 178 | 179 | if(info.getMutexPriority() == _priority) 180 | return info; 181 | } 182 | 183 | return null; 184 | } 185 | 186 | /*************** 187 | * 获取已经加锁的最低等级锁 188 | * 189 | * @author alzq.z 190 | * @time Feb 18, 2013 10:23:02 PM 191 | */ 192 | protected ALMutexInfo _getLowestPriorityMutex() 193 | { 194 | return _m_lThreadMutexList.get(_m_lThreadMutexList.size() - 1); 195 | } 196 | 197 | /*************** 198 | * 增加一个最低等级锁到加锁队列中 199 | * 200 | * @author alzq.z 201 | * @time Feb 18, 2013 10:23:02 PM 202 | */ 203 | protected void _addLowestPriorityMutex(ALMutexInfo _mutexInfo) 204 | { 205 | _m_lThreadMutexList.add(_mutexInfo); 206 | } 207 | 208 | /***************** 209 | * 从加锁队列中删除对象 210 | * 211 | * @author alzq.z 212 | * @time Feb 18, 2013 10:02:29 PM 213 | */ 214 | protected void _removeMutexLevelInfo(ALMutexInfo _info) 215 | { 216 | _m_lThreadMutexList.remove(_info); 217 | } 218 | } 219 | -------------------------------------------------------------------------------- /ALBasicServer/src/ALBasicServer/ALSocket/ALServerSocketListenFunction.java: -------------------------------------------------------------------------------- 1 | package ALBasicServer.ALSocket; 2 | 3 | import java.io.IOException; 4 | import java.net.InetSocketAddress; 5 | import java.net.ServerSocket; 6 | import java.nio.ByteBuffer; 7 | import java.nio.channels.SelectionKey; 8 | import java.nio.channels.Selector; 9 | import java.nio.channels.ServerSocketChannel; 10 | import java.nio.channels.SocketChannel; 11 | import java.util.Iterator; 12 | import java.util.Set; 13 | 14 | import ALBasicServer.ALVerifyObj.ALVerifyObjMgr; 15 | import ALBasicServer.ALVerifyObj._IALVerifyFun; 16 | import ALServerLog.ALServerLog; 17 | 18 | /*********************** 19 | * 服务器监听端口的处理函数类,部分操作由于需要访问内部函数,因此独立 20 | * 21 | * @author alzq.z 22 | * @email zhuangfan@vip.163.com 23 | * @time Feb 19, 2013 4:39:40 PM 24 | */ 25 | public class ALServerSocketListenFunction 26 | { 27 | /** 分配Socket连接的ID标志 */ 28 | private static long g_socketSerialize = 1; 29 | 30 | /********************** 31 | * 开启服务器监听端口,并对所有返回数据做处理 32 | * 33 | * @author alzq.z 34 | * @time Feb 19, 2013 4:34:07 PM 35 | */ 36 | public static void startServer(int _port, int _recBuffLen, _IALVerifyFun _verifyObj) 37 | { 38 | InetSocketAddress socketAddress = new InetSocketAddress(_port); 39 | Selector selector = null; 40 | 41 | //注册验证处理对象 42 | int verifyObjIdx = ALVerifyObjMgr.getInstance().regVerifyObj(_verifyObj); 43 | 44 | //创建接收BUF 45 | ByteBuffer recBuffer = ByteBuffer.allocate(_recBuffLen * 2); 46 | 47 | try { 48 | //创建事件响应对象 49 | selector = Selector.open(); 50 | //创建服务器channel 51 | ServerSocketChannel serverSocketChannel = ServerSocketChannel.open(); 52 | serverSocketChannel.configureBlocking(false); 53 | //绑定socket 54 | ServerSocket serverSocket = serverSocketChannel.socket(); 55 | serverSocket.bind(socketAddress); 56 | 57 | //注册处理事件 58 | serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT); 59 | } 60 | catch (IOException e) 61 | { 62 | //开启端口失败 63 | ALServerLog.Fatal("Open server port error!!"); 64 | e.printStackTrace(); 65 | return ; 66 | } 67 | 68 | ALServerLog.Info("Server Start socket..."); 69 | 70 | //开启循环处理Socket事件 71 | while(true) 72 | { 73 | try 74 | { 75 | selector.select(); 76 | } catch (Exception e) { 77 | ALServerLog.Fatal("Server port select event error!!"); 78 | e.printStackTrace(); 79 | } 80 | 81 | //循环获取到的事件 82 | Set readyKeySet = selector.selectedKeys(); 83 | Iterator iter = readyKeySet.iterator(); 84 | while(iter.hasNext()) 85 | { 86 | SelectionKey key = (SelectionKey)iter.next(); 87 | //移除已经取出的事件 88 | iter.remove(); 89 | 90 | try 91 | { 92 | if(key.isAcceptable()) 93 | { 94 | //收到一个接受连接的操作 95 | ServerSocketChannel serverSocketChannel = (ServerSocketChannel)key.channel(); 96 | try 97 | { 98 | SocketChannel client = serverSocketChannel.accept(); 99 | ALServerLog.Info("Accept a client connection "); 100 | 101 | client.configureBlocking(false); 102 | 103 | ALBasicServerSocket newSocket = new ALBasicServerSocket(_getSocketID(), verifyObjIdx, client, _recBuffLen); 104 | //将对象及其ID注册 105 | ALServerSocketMgr.getInstance().regSocket(newSocket); 106 | 107 | //注册读取事件,读取操作由server socket channel处理,写入操作可直接对socket channel进行操作 108 | client.register(selector, SelectionKey.OP_READ); 109 | } 110 | catch (Exception e) 111 | { 112 | ALServerLog.Fatal("Server port accept error!!"); 113 | e.printStackTrace(); 114 | } 115 | } 116 | else if(key.isReadable()) 117 | { 118 | //收到数据 119 | SocketChannel socketChannel = (SocketChannel)key.channel(); 120 | 121 | //读取数据 122 | try 123 | { 124 | recBuffer.clear(); 125 | //此时进行读取,当读取的包大小超过存储区域则可能导致数据读取不全 126 | int recLen = socketChannel.read(recBuffer); 127 | //设置限制,并将读取位置归0 128 | recBuffer.flip(); 129 | 130 | if(recLen <= 0) 131 | { 132 | if(recLen < 0) 133 | { 134 | //尝试在对应Socket存储结构体中删除对应Socket 135 | ALServerSocketMgr.getInstance().unregSocket(socketChannel); 136 | } 137 | continue; 138 | } 139 | 140 | //尝试在已注册对象中查询对应Socket 141 | ALBasicServerSocket socket = ALServerSocketMgr.getInstance().getSocket(socketChannel); 142 | 143 | if(null == socket) 144 | continue; 145 | 146 | //处理消息读取 147 | socket._socketReceivingMessage(recBuffer); 148 | } 149 | catch (IOException e) 150 | { 151 | //尝试在对应Socket存储结构体中删除对应Socket 152 | ALServerSocketMgr.getInstance().unregSocket(socketChannel); 153 | } 154 | } 155 | } 156 | catch (Exception e) { 157 | 158 | } 159 | } 160 | } 161 | } 162 | 163 | /************** 164 | * 获取新的SocketID 165 | * @return 166 | */ 167 | protected static synchronized long _getSocketID() 168 | { 169 | return g_socketSerialize++; 170 | } 171 | } 172 | -------------------------------------------------------------------------------- /ALBasicProtocolPack/src/ALBasicProtocolPack/ALProtocolCommon.java: -------------------------------------------------------------------------------- 1 | package ALBasicProtocolPack; 2 | 3 | import java.nio.ByteBuffer; 4 | import java.nio.charset.Charset; 5 | import java.nio.charset.CharsetDecoder; 6 | 7 | /********************** 8 | * Protocol制作对象的基本公用函数 9 | * 10 | * @author alzq.z 11 | * @email zhuangfan@vip.163.com 12 | * @time Jan 23, 2013 11:25:54 PM 13 | */ 14 | public class ALProtocolCommon 15 | { 16 | private static Charset _g_CharSet = Charset.forName("UTF-8"); 17 | 18 | /**************** 19 | * 获取Int型数据在压缩数据后的数据大小 20 | * 需要多一字节存放长度 21 | * 22 | * @author alzq.z 23 | * @time Jan 23, 2013 11:25:38 PM 24 | */ 25 | public static int GetIntZipSize(int _num) 26 | { 27 | if(_num > Byte.MIN_VALUE && _num < Byte.MAX_VALUE) 28 | return 2; 29 | else if(_num > Short.MIN_VALUE && _num < Short.MAX_VALUE) 30 | return 3; 31 | 32 | return 5; 33 | } 34 | 35 | /**************** 36 | * 获取Long型数据在压缩数据后的数据大小 37 | * 需要多一字节存放长度 38 | * 39 | * @author alzq.z 40 | * @time Jan 23, 2013 11:25:38 PM 41 | */ 42 | public static int GetLongZipSize(long _num) 43 | { 44 | if(_num > Byte.MIN_VALUE && _num < Byte.MAX_VALUE) 45 | return 2; 46 | else if(_num > Short.MIN_VALUE && _num < Short.MAX_VALUE) 47 | return 3; 48 | else if(_num > Integer.MIN_VALUE && _num < Integer.MAX_VALUE) 49 | return 5; 50 | 51 | return 9; 52 | } 53 | 54 | /**************** 55 | * 将Int数据通过压缩方式放入内存块中 56 | * 57 | * @author alzq.z 58 | * @time Jan 23, 2013 11:25:38 PM 59 | */ 60 | public static void ZipPutIntIntoBuf(ByteBuffer _buff, int _num) 61 | { 62 | if(_num > Byte.MIN_VALUE && _num < Byte.MAX_VALUE) 63 | { 64 | //put the length 65 | _buff.put((byte)1); 66 | //put the value 67 | _buff.put((byte)_num); 68 | return ; 69 | } 70 | else if(_num > Short.MIN_VALUE && _num < Short.MAX_VALUE) 71 | { 72 | //put the length 73 | _buff.put((byte)2); 74 | //put the value 75 | _buff.putShort((short)_num); 76 | return ; 77 | } 78 | 79 | //put the length 80 | _buff.put((byte)4); 81 | //put the value 82 | _buff.putInt(_num); 83 | } 84 | 85 | /**************** 86 | * 获取Long型数据在压缩数据后的数据大小 87 | * 需要多一字节存放长度 88 | * 89 | * @author alzq.z 90 | * @time Jan 23, 2013 11:25:38 PM 91 | */ 92 | public static void ZipPutLongIntoBuf(ByteBuffer _buff, long _num) 93 | { 94 | if(_num > Byte.MIN_VALUE && _num < Byte.MAX_VALUE) 95 | { 96 | //put the length 97 | _buff.put((byte)1); 98 | //put the value 99 | _buff.put((byte)_num); 100 | return ; 101 | } 102 | else if(_num > Short.MIN_VALUE && _num < Short.MAX_VALUE) 103 | { 104 | //put the length 105 | _buff.put((byte)2); 106 | //put the value 107 | _buff.putShort((short)_num); 108 | return ; 109 | } 110 | else if(_num > Integer.MIN_VALUE && _num < Integer.MAX_VALUE) 111 | { 112 | //put the length 113 | _buff.put((byte)4); 114 | //put the value 115 | _buff.putInt((int)_num); 116 | return ; 117 | } 118 | 119 | 120 | //put the length 121 | _buff.put((byte)8); 122 | //put the value 123 | _buff.putLong(_num); 124 | } 125 | 126 | /**************** 127 | * 将Int数据通过压缩方式从内存方式 128 | * 129 | * @author alzq.z 130 | * @time Jan 23, 2013 11:25:38 PM 131 | */ 132 | public static int ZipGetIntFromBuf(ByteBuffer _buff) 133 | { 134 | byte size = _buff.get(); 135 | 136 | if(size == 1) 137 | return _buff.get(); 138 | else if(size == 2) 139 | return _buff.getShort(); 140 | 141 | return _buff.getInt(); 142 | } 143 | 144 | /**************** 145 | * 将Long数据通过压缩方式从内存方式 146 | * 147 | * @author alzq.z 148 | * @time Jan 23, 2013 11:25:38 PM 149 | */ 150 | public static long ZipGetLongFromBuf(ByteBuffer _buff) 151 | { 152 | byte size = _buff.get(); 153 | 154 | if(size == 1) 155 | return _buff.get(); 156 | else if(size == 2) 157 | return _buff.getShort(); 158 | else if(size == 4) 159 | return _buff.getInt(); 160 | 161 | return _buff.getLong(); 162 | } 163 | 164 | /*********** 165 | * 获取发送字符串所需要的包长度 166 | * @param str 167 | * @return 168 | */ 169 | public static int GetStringBufSize(String str) 170 | { 171 | if(null == str || str.isEmpty()) 172 | { 173 | return 2; 174 | } 175 | 176 | return str.getBytes(_g_CharSet).length + 2; 177 | } 178 | 179 | /************ 180 | * 将字符串放入字节包中 181 | * @param _str 182 | * @param _buf 183 | */ 184 | public static void PutStringIntoBuf(ByteBuffer _buff, String _str) 185 | { 186 | if (_str != null && _str.length() > 0) 187 | { 188 | byte[] sb = _str.getBytes(); 189 | _buff.putShort((short) sb.length); 190 | _buff.put(sb); 191 | } 192 | else 193 | { 194 | _buff.putShort((short) 0); 195 | } 196 | } 197 | 198 | /**************** 199 | * 从字节数据中获取字符串 200 | * @param bb 201 | * @return 202 | */ 203 | public static String GetStringFromBuf(ByteBuffer _buff) 204 | { 205 | short len = _buff.getShort(); 206 | if(0 == len) 207 | return ""; 208 | 209 | byte[] strbytes = new byte[len]; 210 | _buff.get(strbytes, 0, len); 211 | String str; 212 | try 213 | { 214 | CharsetDecoder decoder = _g_CharSet.newDecoder(); 215 | str = decoder.decode(ByteBuffer.wrap(strbytes)).toString(); 216 | } 217 | catch (Exception e) 218 | { 219 | return ""; 220 | } 221 | 222 | return str; 223 | } 224 | 225 | /**************** 226 | * 从字节数据中获取字符串 227 | * @param bb 228 | * @return 229 | */ 230 | public static String GetStringFromBuf(byte[] _strBytes) 231 | { 232 | String str; 233 | try 234 | { 235 | CharsetDecoder decoder = _g_CharSet.newDecoder(); 236 | str = decoder.decode(ByteBuffer.wrap(_strBytes)).toString(); 237 | } 238 | catch (Exception e) 239 | { 240 | return ""; 241 | } 242 | 243 | return str; 244 | } 245 | } 246 | -------------------------------------------------------------------------------- /ALBasicServer/src/ALBasicServer/ALServerSynTask/ALSynTimingTaskNode.java: -------------------------------------------------------------------------------- 1 | package ALBasicServer.ALServerSynTask; 2 | 3 | import java.util.LinkedList; 4 | import java.util.ListIterator; 5 | import java.util.concurrent.locks.ReentrantLock; 6 | 7 | import ALBasicServer.ALTask._IALSynTask; 8 | import ALServerLog.ALServerLog; 9 | 10 | /******************* 11 | * 定时任务的划片集合节点信息 12 | * 13 | * @author alzq.z 14 | * @email zhuangfan@vip.163.com 15 | * @time Jul 16, 2015 10:57:02 PM 16 | */ 17 | public class ALSynTimingTaskNode 18 | { 19 | /** 当前回合标记 */ 20 | private int _m_iCurRound; 21 | /** 当前回合的本节点定时任务队列 */ 22 | private LinkedList<_IALSynTask> _m_lCurRoundTimingTaskList; 23 | 24 | /** 下一回合标记 */ 25 | private int _m_iNextRound; 26 | /** 固定记录下一回合的延迟任务队列集合 */ 27 | private LinkedList<_IALSynTask> _m_lNextRoundTimingTaskList; 28 | 29 | /** 非本回合与下一回合的较长时间延迟任务信息集合队列 */ 30 | private LinkedList _m_lFarDelayTaskList; 31 | 32 | /** 本节点下的数据锁 */ 33 | private ReentrantLock _m_mutex; 34 | 35 | public ALSynTimingTaskNode(int _round) 36 | { 37 | _m_iCurRound = _round; 38 | _m_lCurRoundTimingTaskList = new LinkedList<_IALSynTask>(); 39 | 40 | _m_iNextRound = _round + 1; 41 | _m_lNextRoundTimingTaskList = new LinkedList<_IALSynTask>(); 42 | 43 | _m_lFarDelayTaskList = new LinkedList(); 44 | 45 | _m_mutex = new ReentrantLock(); 46 | } 47 | 48 | /*************** 49 | * 添加指定回合的本时间节点的任务,返回是否添加成功,不成功则表示需要马上执行 50 | * 51 | * @author alzq.z 52 | * @time Jul 16, 2015 11:26:06 PM 53 | */ 54 | public boolean addTimingTask(int _round, _IALSynTask _task) 55 | { 56 | _lock(); 57 | 58 | try 59 | { 60 | if(null == _task) 61 | return false; 62 | 63 | //当本回合的时候,直接进行添加 64 | if(_round == _m_iCurRound) 65 | { 66 | _m_lCurRoundTimingTaskList.add(_task); 67 | return true; 68 | } 69 | else if(_round == _m_iNextRound) 70 | { 71 | _m_lNextRoundTimingTaskList.add(_task); 72 | return true; 73 | } 74 | else if(_round > _m_iNextRound) 75 | { 76 | //长时间延迟的任务,按照回合顺序放入对应队列 77 | ListIterator iterator = _m_lFarDelayTaskList.listIterator(); 78 | while(iterator.hasNext()) 79 | { 80 | ALSynTimingTaskNodeFarDelayTaskInfo taskInfo = iterator.next(); 81 | if(taskInfo.getRound() == _round) 82 | { 83 | //匹配回合则加入本节点 84 | taskInfo.addSynTask(_task); 85 | break; 86 | } 87 | else if(taskInfo.getRound() < _round) 88 | { 89 | //当插入的回合比对应回合早,则需要在对应回合之前插入数据 90 | //这里采用的做法是将本节点数据重复插入到下一个节点,之后将本节点设置为新数据 91 | iterator.add(taskInfo); 92 | 93 | //创建新节点 94 | ALSynTimingTaskNodeFarDelayTaskInfo newInfo = new ALSynTimingTaskNodeFarDelayTaskInfo(_round); 95 | iterator.set(newInfo); 96 | //插入任务 97 | newInfo.addSynTask(_task); 98 | break; 99 | } 100 | } 101 | 102 | //判断是否已经到了最后节点 103 | if(!iterator.hasNext()) 104 | { 105 | //在最后节点则往最后追加数据 106 | //创建新节点 107 | ALSynTimingTaskNodeFarDelayTaskInfo newInfo = new ALSynTimingTaskNodeFarDelayTaskInfo(_round); 108 | iterator.add(newInfo); 109 | //插入任务 110 | newInfo.addSynTask(_task); 111 | } 112 | 113 | return true; 114 | } 115 | else 116 | { 117 | //当回合小于当前回合则表示失败,外部需要直接处理 118 | return false; 119 | } 120 | } 121 | finally 122 | { 123 | _unlock(); 124 | } 125 | } 126 | 127 | /*************** 128 | * 取出所有对应回合的本节点任务 129 | * 130 | * @author alzq.z 131 | * @time Jul 16, 2015 11:49:51 PM 132 | */ 133 | public void popAllRoundTaskAndMoveNextRound(int _round, LinkedList<_IALSynTask> _recList) 134 | { 135 | if(null == _recList) 136 | return ; 137 | 138 | _lock(); 139 | 140 | try 141 | { 142 | //判断回合是否在本回合之前,则不做处理 143 | if(_round < _m_iCurRound) 144 | return ; 145 | 146 | //将所有当前回合任务放入队列 147 | while(!_m_lCurRoundTimingTaskList.isEmpty()) 148 | { 149 | _recList.addLast(_m_lCurRoundTimingTaskList.pop()); 150 | } 151 | 152 | //当回合在本回合之后则弹出错误警告,并将所有对应回合之后的任务放入队列 153 | if(_round > _m_iCurRound) 154 | { 155 | //可能跳过某个回合,因此输出错误 156 | ALServerLog.Fatal("Timing Syn Task Round Error! pop round: " + _round + " - current round: " + _m_iCurRound); 157 | 158 | //移动到对应的回合 159 | _moveToRound(_round); 160 | //将所有当前回合任务放入队列 161 | while(!_m_lCurRoundTimingTaskList.isEmpty()) 162 | { 163 | _recList.addLast(_m_lCurRoundTimingTaskList.pop()); 164 | } 165 | } 166 | 167 | //移动到下一回合 168 | _moveNextRound(); 169 | } 170 | finally 171 | { 172 | _unlock(); 173 | } 174 | } 175 | 176 | /**************** 177 | * 移动当前回合至指定回合 178 | * 179 | * @author alzq.z 180 | * @time Jul 16, 2015 11:57:27 PM 181 | */ 182 | protected void _moveToRound(int _targetRound) 183 | { 184 | //在不匹配对应回合的时候不断往后推移 185 | while(_m_iCurRound < _targetRound) 186 | { 187 | _moveNextRound(); 188 | } 189 | } 190 | 191 | /*************** 192 | * 向下移动一个回合 193 | * 194 | * @author alzq.z 195 | * @time Jul 16, 2015 11:58:23 PM 196 | */ 197 | protected void _moveNextRound() 198 | { 199 | //累加一个回合 200 | _m_iCurRound++; 201 | _m_iNextRound++; 202 | 203 | //将下一回合任务累加到当前队列 204 | while(!_m_lNextRoundTimingTaskList.isEmpty()) 205 | { 206 | _m_lCurRoundTimingTaskList.addLast(_m_lNextRoundTimingTaskList.pop()); 207 | } 208 | 209 | //获取第一个长时间间隔任务队列节点,是否匹配下一回合,是则将任务放入 210 | if(!_m_lFarDelayTaskList.isEmpty()) 211 | { 212 | ALSynTimingTaskNodeFarDelayTaskInfo farDelayInfo = _m_lFarDelayTaskList.getFirst(); 213 | if(farDelayInfo.getRound() == _m_iNextRound) 214 | { 215 | //从长时间间隔队列删除 216 | _m_lFarDelayTaskList.pop(); 217 | //将任务放入 218 | farDelayInfo.popAllSynTask(_m_lNextRoundTimingTaskList); 219 | } 220 | } 221 | } 222 | 223 | protected void _lock(){_m_mutex.lock();} 224 | protected void _unlock() {_m_mutex.unlock();} 225 | } 226 | -------------------------------------------------------------------------------- /ALBasicCommon/src/ALBasicCommon/ALBasicCommonFun.java: -------------------------------------------------------------------------------- 1 | package ALBasicCommon; 2 | 3 | import java.nio.ByteBuffer; 4 | import java.nio.charset.CharacterCodingException; 5 | import java.nio.charset.Charset; 6 | import java.nio.charset.CharsetDecoder; 7 | import java.util.Calendar; 8 | import java.util.Random; 9 | 10 | public class ALBasicCommonFun 11 | { 12 | private static Random g_randomObj = new Random(); 13 | private static String g_sHexStrIdxString = "0123456789ABCDEF"; 14 | 15 | /***************** 16 | * 将字节转化为int对象 17 | * 18 | * @author alzq.z 19 | * @time Feb 19, 2013 11:30:30 AM 20 | */ 21 | public static int byte2int(byte value) { return (int)value & 0xFF; } 22 | 23 | /***************** 24 | * 将2个short转化为int对象 25 | * 26 | * @author alzq.z 27 | * @time Feb 19, 2013 11:30:30 AM 28 | */ 29 | public static int mergeShort(short _s1, short _s2) 30 | { 31 | return (((int)_s1) << 16) | _s2; 32 | } 33 | public static int mergeShortNum(int _s1, int _s2) 34 | { 35 | return (_s1 << 16) | _s2; 36 | } 37 | 38 | /***************** 39 | * 将2个int转化为long对象 40 | * 41 | * @author alzq.z 42 | * @time Feb 19, 2013 11:30:30 AM 43 | */ 44 | public static long mergeInt(int _i1, int _i2) 45 | { 46 | return (((long)_i1) << 32) | _i2; 47 | } 48 | 49 | public static boolean getBoolean(ByteBuffer buf) 50 | { 51 | if ( buf.get() == 1 ) 52 | { 53 | return true; 54 | } 55 | 56 | return false; 57 | } 58 | 59 | public static void putBoolean(ByteBuffer buf, boolean bData) 60 | { 61 | if ( null == buf ) 62 | { 63 | return; 64 | } 65 | 66 | if ( bData ) 67 | { 68 | buf.put((byte)1); 69 | } 70 | else { 71 | buf.put((byte)0); 72 | } 73 | } 74 | 75 | /**************** 76 | * 从字节数据中获取字符串 77 | * @param bb 78 | * @return 79 | */ 80 | public static String getString(ByteBuffer bb) 81 | { 82 | short nStringLen = bb.getShort(); 83 | byte[] byarrString = new byte[nStringLen]; 84 | 85 | try 86 | { 87 | bb.get(byarrString, 0, nStringLen); 88 | } 89 | catch (Exception e) 90 | { 91 | return ""; 92 | } 93 | 94 | String str; 95 | try 96 | { 97 | CharsetDecoder decoder = Charset.forName("UTF-8").newDecoder(); 98 | str = decoder.decode(ByteBuffer.wrap(byarrString)).toString(); 99 | } 100 | catch (CharacterCodingException e) 101 | { 102 | return ""; 103 | } 104 | 105 | return str; 106 | } 107 | 108 | /*********** 109 | * 获取发送字符串所需要的包长度 110 | * @param str 111 | * @return 112 | */ 113 | public static int getStringSize(String str) 114 | { 115 | if(null == str || str.isEmpty()) 116 | { 117 | return 2; 118 | } 119 | 120 | return str.getBytes().length + 2; 121 | } 122 | 123 | /************ 124 | * 将字符串放入字节包中 125 | * @param _str 126 | * @param _buf 127 | */ 128 | public static void putString(String _str, ByteBuffer _buf) 129 | { 130 | if (_str != null && _str.length() > 0) 131 | { 132 | byte[] sb = _str.getBytes(); 133 | _buf.putShort((short) sb.length); 134 | _buf.put(sb); 135 | } 136 | else 137 | { 138 | _buf.putShort((short) 0); 139 | } 140 | } 141 | 142 | /************** 143 | * 将字符串转化为字节包 144 | * @param _str 145 | * @return 146 | */ 147 | public static ByteBuffer getStringBuf(String _str) 148 | { 149 | if (_str != null && _str.length() > 0) 150 | { 151 | byte[] stringByte = _str.getBytes(); 152 | 153 | ByteBuffer buf = ByteBuffer.allocate(stringByte.length + 2); 154 | buf.putShort((short) stringByte.length); 155 | buf.put(stringByte); 156 | buf.flip(); 157 | 158 | return buf; 159 | } 160 | else 161 | { 162 | ByteBuffer buf = ByteBuffer.allocate(2); 163 | buf.putShort((short) 0); 164 | buf.flip(); 165 | 166 | return buf; 167 | } 168 | } 169 | 170 | /** 171 | * 获取当前时间的小时部分(24小时制) 172 | * @return 173 | */ 174 | public static int getNowTimeHour() 175 | { 176 | Calendar calendar = Calendar.getInstance(); 177 | return calendar.get(Calendar.HOUR_OF_DAY); 178 | } 179 | 180 | /** 181 | * 获取当前时间距纪元所经历的秒数 182 | * @return 183 | */ 184 | public static int getNowTime() 185 | { 186 | Calendar calendar = Calendar.getInstance(); 187 | int iNowTime = (int) (calendar.getTimeInMillis() / 1000); 188 | 189 | return iNowTime; 190 | } 191 | 192 | /** 193 | * 获取当前时间距纪元所经历的毫秒数 194 | * @return 195 | */ 196 | public static long getNowTimeMS() 197 | { 198 | Calendar calendar = Calendar.getInstance(); 199 | return calendar.getTimeInMillis(); 200 | } 201 | 202 | /** 203 | * 获取当前时间信息连接起来的数字 204 | * @return 205 | */ 206 | public static long getNowTimeNum() 207 | { 208 | Calendar calendar = Calendar.getInstance(); 209 | 210 | long timeNum = calendar.get(Calendar.YEAR); 211 | timeNum = (timeNum * 100) + calendar.get(Calendar.MONTH) + 1; 212 | timeNum = (timeNum * 100) + calendar.get(Calendar.DAY_OF_MONTH); 213 | timeNum = (timeNum * 100) + calendar.get(Calendar.HOUR_OF_DAY); 214 | timeNum = (timeNum * 100) + calendar.get(Calendar.MINUTE); 215 | timeNum = (timeNum * 100) + calendar.get(Calendar.SECOND); 216 | 217 | return timeNum; 218 | } 219 | 220 | /** 221 | * 产生一个处于区间 0<= x < _iRangeLimit 的随机整数 222 | * @return 223 | */ 224 | public static int getRandomIntByRange(int _iRangeLimit) 225 | { 226 | return Math.abs(g_randomObj.nextInt(_iRangeLimit)); 227 | } 228 | 229 | /** 230 | * 产生一个处于区间 0<= x <= _iRangeLimit 的随机整数 231 | * @param iDelta 232 | * @return 233 | */ 234 | public static int getRandomInt(int _iRangeLimit) 235 | { 236 | return Math.abs(g_randomObj.nextInt(_iRangeLimit + 1)); 237 | } 238 | public static long getRandomLong() 239 | { 240 | return Math.abs(g_randomObj.nextLong()); 241 | } 242 | 243 | /** 244 | * 产生一个处于区间 0<= x <= 1 的随机浮点数 245 | * @param iDelta 246 | * @return 247 | */ 248 | public static float getRandomFloat() 249 | { 250 | return g_randomObj.nextFloat(); 251 | } 252 | 253 | /** 254 | * 将字节数组转换成十六进制字符串 255 | * @param iDelta 256 | * @return 257 | */ 258 | public static String getHexString(byte[] _buf) 259 | { 260 | if(null == _buf || _buf.length <= 0) 261 | return "0"; 262 | 263 | //逐个字节处理 264 | StringBuilder builder = new StringBuilder(); 265 | for(int i = 0; i < _buf.length; i++) 266 | { 267 | byte b = _buf[i]; 268 | 269 | //取前4位 270 | builder.append(g_sHexStrIdxString.charAt((b >> 4) & 0x0F)); 271 | //取后4位 272 | builder.append(g_sHexStrIdxString.charAt(b & 0x0F)); 273 | } 274 | 275 | return builder.toString(); 276 | } 277 | public static String getHexString(ByteBuffer _buf) 278 | { 279 | if(null == _buf) 280 | return ""; 281 | 282 | //记录当前下标位置 283 | int prePos = _buf.position(); 284 | int len = _buf.limit(); 285 | //逐个字节处理 286 | StringBuilder builder = new StringBuilder(); 287 | for(int i = 0; i < len; i++) 288 | { 289 | byte b = _buf.get(); 290 | 291 | //取前4位 292 | builder.append(g_sHexStrIdxString.charAt((b >> 4) & 0x0F)); 293 | //取后4位 294 | builder.append(g_sHexStrIdxString.charAt(b & 0x0F)); 295 | } 296 | 297 | //重置buff下标 298 | _buf.position(prePos); 299 | 300 | return builder.toString(); 301 | } 302 | } 303 | -------------------------------------------------------------------------------- /ALBasicServer/src/ALBasicServer/ALServerSynTask/ALSynTaskManager.java: -------------------------------------------------------------------------------- 1 | package ALBasicServer.ALServerSynTask; 2 | 3 | import java.util.LinkedList; 4 | import java.util.concurrent.Semaphore; 5 | import java.util.concurrent.locks.ReentrantLock; 6 | 7 | import ALBasicCommon.ALBasicCommonFun; 8 | import ALBasicServer.ALBasicServerConf; 9 | import ALBasicServer.ALTask._IALSynTask; 10 | 11 | /********************** 12 | * 架构中的同步任务管理对象,对象中根据不同的任务安排方式进行处理
13 | * 14 | * @author alzq 15 | * 16 | */ 17 | public class ALSynTaskManager 18 | { 19 | private static ALSynTaskManager g_instance = new ALSynTaskManager(); 20 | 21 | public static ALSynTaskManager getInstance() 22 | { 23 | if(null == g_instance) 24 | g_instance = new ALSynTaskManager(); 25 | 26 | return g_instance; 27 | } 28 | 29 | /** 当前任务队列由于此队列只从队列头抽取对象,并且仅在队列尾插入对象 */ 30 | private LinkedList<_IALSynTask> _m_lCurrentTaskList; 31 | /** 当前任务队列操作锁 */ 32 | private ReentrantLock _m_lCurrentTaskMutex; 33 | 34 | /** 定时任务的时间精度 */ 35 | private int _m_iTimingTaskCheckTime; 36 | /** 定时任务的大区间长度,根据精度和长度可以决定一个区间的时间跨度 */ 37 | private int _m_iTimingTaskCheckAreaSize; 38 | /** 定时任务开启处理的时间标记 */ 39 | private long _m_lTimingTaskMgrStartTime; 40 | 41 | /** 最后一次检测的回合数和对应下标 */ 42 | private int _m_iLastCheckRound; 43 | private int _m_iLastCheckTick; 44 | 45 | /** 记录固定队列长度的定时任务存储队列,用数组便于根据下标查询 */ 46 | private ALSynTimingTaskNode[] _m_arrTimingTaskNodeList; 47 | 48 | /** 定时任务队列锁 */ 49 | private ReentrantLock _m_lTimingTaskMutex; 50 | 51 | /** 任务对应的同步信号量 */ 52 | private Semaphore _m_sTaskEvent; 53 | 54 | protected ALSynTaskManager() 55 | { 56 | _m_lCurrentTaskList = new LinkedList<_IALSynTask>(); 57 | _m_lCurrentTaskMutex = new ReentrantLock(); 58 | 59 | //读取配置 60 | _m_iTimingTaskCheckTime = ALBasicServerConf.getInstance().getTimerCheckTime(); 61 | if(_m_iTimingTaskCheckTime < 10) 62 | _m_iTimingTaskCheckTime = 10; 63 | if(_m_iTimingTaskCheckTime > 1000) 64 | _m_iTimingTaskCheckTime = 1000; 65 | 66 | _m_iTimingTaskCheckAreaSize = ALBasicServerConf.getInstance().getTimerCheckAreaSize(); 67 | if(_m_iTimingTaskCheckAreaSize < 1000) 68 | _m_iTimingTaskCheckAreaSize = 1000; 69 | if(_m_iTimingTaskCheckAreaSize > 100000) 70 | _m_iTimingTaskCheckAreaSize = 100000; 71 | 72 | //获取开启管理对象的时间 73 | _m_lTimingTaskMgrStartTime = ALBasicCommonFun.getNowTimeMS(); 74 | //初始化最后一次检测的位置信息 75 | _m_iLastCheckRound = 0; 76 | _m_iLastCheckTick = 0; 77 | 78 | //创建固定区间长度的精度队列 79 | _m_arrTimingTaskNodeList = new ALSynTimingTaskNode[_m_iTimingTaskCheckAreaSize]; 80 | for(int i = 0; i < _m_iTimingTaskCheckAreaSize; i++) 81 | { 82 | _m_arrTimingTaskNodeList[i] = new ALSynTimingTaskNode(0); 83 | } 84 | 85 | //创建锁对象 86 | _m_lTimingTaskMutex = new ReentrantLock(); 87 | 88 | _m_sTaskEvent = new Semaphore(0); 89 | } 90 | 91 | public int getTaskCheckTime() {return _m_iTimingTaskCheckTime;} 92 | 93 | /***************** 94 | * 注册一个直接执行的任务 95 | * 96 | * @author alzq.z 97 | * @time Feb 18, 2013 11:01:18 PM 98 | */ 99 | public void regTask(_IALSynTask _task) 100 | { 101 | _lockCurrentTaskList(); 102 | 103 | //向链表中添加执行任务 104 | _m_lCurrentTaskList.add(_task); 105 | 106 | //释放任务数量信号量,在实际线程中将可获取任务进行处理 107 | _releaseTaskEvent(); 108 | 109 | _unlockCurrentTaskList(); 110 | } 111 | 112 | /********************* 113 | * 注册定时执行的任务 114 | * 115 | * @author alzq.z 116 | * @time Feb 18, 2013 11:04:48 PM 117 | */ 118 | public void regTask(_IALSynTask _task, int _time) 119 | { 120 | _lockTimingTaskList(); 121 | 122 | //判断定时时间,当非法,则直接当作当前执行任务插入 123 | if(_time <= 0) 124 | { 125 | regTask(_task); 126 | } 127 | else 128 | { 129 | //获取当前时间 130 | long nowTime = ALBasicCommonFun.getNowTimeMS(); 131 | //注册定时任务,将任务添加到表中等待插入到执行队列 132 | if(!_regTimingTask(nowTime + _time - _m_lTimingTaskMgrStartTime, _task)) 133 | regTask(_task); 134 | } 135 | 136 | _unlockTimingTaskList(); 137 | } 138 | public void regTask(_IALSynTask _task, long _time) 139 | { 140 | _lockTimingTaskList(); 141 | 142 | //判断定时时间,当非法,则直接当作当前执行任务插入 143 | if(_time <= 0) 144 | { 145 | regTask(_task); 146 | } 147 | else 148 | { 149 | //获取当前时间 150 | long nowTime = ALBasicCommonFun.getNowTimeMS(); 151 | //注册定时任务,将任务添加到表中等待插入到执行队列 152 | if(!_regTimingTask(nowTime + _time - _m_lTimingTaskMgrStartTime, _task)) 153 | regTask(_task); 154 | } 155 | 156 | _unlockTimingTaskList(); 157 | } 158 | 159 | /********************* 160 | * 提取出第一个需要执行的任务 161 | * 162 | * @author alzq.z 163 | * @time Feb 18, 2013 11:17:58 PM 164 | */ 165 | public _IALSynTask popCurrentTask() 166 | { 167 | _acquireTaskEvent(); 168 | _lockCurrentTaskList(); 169 | 170 | //判断任务队列是否为空 171 | if(_m_lCurrentTaskList.isEmpty()) 172 | { 173 | _unlockCurrentTaskList(); 174 | return null; 175 | } 176 | 177 | //取出并移除任务队列第一个任务 178 | _IALSynTask task = _m_lCurrentTaskList.removeFirst(); 179 | 180 | _unlockCurrentTaskList(); 181 | return task; 182 | } 183 | 184 | /**************** 185 | * 注册整个队列的定时任务 186 | * 系统内接口不对外开放 187 | * 188 | * @author alzq.z 189 | * @time Feb 18, 2013 11:32:18 PM 190 | */ 191 | protected void _registerTaskList(LinkedList<_IALSynTask> _taskList) 192 | { 193 | //在循环内加锁有利于大量任务插入时长时间阻塞处理线程的情况 194 | while(!_taskList.isEmpty()) 195 | { 196 | _lockCurrentTaskList(); 197 | 198 | _m_lCurrentTaskList.add(_taskList.removeFirst()); 199 | 200 | _releaseTaskEvent(); 201 | 202 | _unlockCurrentTaskList(); 203 | } 204 | } 205 | 206 | /*************** 207 | * 当前任务队列操作锁定操作 208 | * 209 | * @author alzq.z 210 | * @time Feb 18, 2013 11:34:52 PM 211 | */ 212 | protected void _lockCurrentTaskList() 213 | { 214 | _m_lCurrentTaskMutex.lock(); 215 | } 216 | protected void _unlockCurrentTaskList() 217 | { 218 | _m_lCurrentTaskMutex.unlock(); 219 | } 220 | 221 | /********************* 222 | * 定时任务队列操作锁定操作 223 | * 224 | * @author alzq.z 225 | * @time Feb 18, 2013 11:35:02 PM 226 | */ 227 | protected void _lockTimingTaskList() 228 | { 229 | _m_lTimingTaskMutex.lock(); 230 | } 231 | protected void _unlockTimingTaskList() 232 | { 233 | _m_lTimingTaskMutex.unlock(); 234 | } 235 | 236 | /********************* 237 | * 释放一个任务信号量,以使得等待执行任务的线程通过信号量获得通知 238 | * 239 | * @author alzq.z 240 | * @time Feb 18, 2013 11:35:08 PM 241 | */ 242 | protected void _releaseTaskEvent() 243 | { 244 | _m_sTaskEvent.release(); 245 | } 246 | 247 | /********************* 248 | * 获取一个任务信号量,表示开始处理一个任务 249 | * 250 | * @author alzq.z 251 | * @time Feb 18, 2013 11:35:37 PM 252 | */ 253 | protected void _acquireTaskEvent() 254 | { 255 | _m_sTaskEvent.acquireUninterruptibly(); 256 | } 257 | 258 | /**************** 259 | * 在定时任务处理表中添加定时执行的任务,带入的_dealTime是距离本任务管理对象开启的时间间隔 260 | * 261 | * @author alzq.z 262 | * @time Feb 18, 2013 11:06:12 PM 263 | */ 264 | protected boolean _regTimingTask(long _dealTime, _IALSynTask _task) 265 | { 266 | _lockTimingTaskList(); 267 | 268 | try 269 | { 270 | //根据时间精度以及回合总时间区域计算对应的回合数以及时间节点 271 | int tick = (int)((_dealTime + _m_iTimingTaskCheckTime - 1) / _m_iTimingTaskCheckTime); 272 | int round = tick / _m_iTimingTaskCheckAreaSize; 273 | //计算实际的下标数 274 | tick = tick - (round * _m_iTimingTaskCheckAreaSize); 275 | 276 | //当下标和回合等于最后一次检测的数据时将任务移到下一个下标中进行处理 277 | if(tick <= _m_iLastCheckTick && round <= _m_iLastCheckRound) 278 | { 279 | tick++; 280 | if(tick >= _m_iTimingTaskCheckAreaSize) 281 | { 282 | tick -= _m_iTimingTaskCheckAreaSize; 283 | round++; 284 | } 285 | } 286 | 287 | //将任务添加到对应下标 288 | return _m_arrTimingTaskNodeList[tick].addTimingTask(round, _task); 289 | } 290 | finally 291 | { 292 | _unlockTimingTaskList(); 293 | } 294 | } 295 | 296 | /******************** 297 | * 将到目前为止的所有定时任务取出 298 | * 299 | * @author alzq.z 300 | * @time Feb 18, 2013 11:23:11 PM 301 | */ 302 | protected void _popTimerTask(LinkedList<_IALSynTask> _recList) 303 | { 304 | if(null == _recList) 305 | return ; 306 | 307 | _lockTimingTaskList(); 308 | 309 | try 310 | { 311 | //获取运行的时间 312 | long dealTime = ALBasicCommonFun.getNowTimeMS() - _m_lTimingTaskMgrStartTime; 313 | //根据运行时间计算出当前时间对应的下标 314 | int tick = (int)(dealTime / _m_iTimingTaskCheckTime); 315 | int round = tick / _m_iTimingTaskCheckAreaSize; 316 | //计算实际的下标数 317 | tick = tick - (round * _m_iTimingTaskCheckAreaSize); 318 | 319 | //将下标和round不断累加获取需要执行的任务 320 | while(_m_iLastCheckTick < tick || _m_iLastCheckRound < round) 321 | { 322 | //累加下标 323 | _m_iLastCheckTick++; 324 | //判断下标是否越界 325 | if(_m_iLastCheckTick >= _m_iTimingTaskCheckAreaSize) 326 | { 327 | _m_iLastCheckTick -= _m_iTimingTaskCheckAreaSize; 328 | _m_iLastCheckRound++; 329 | } 330 | 331 | //获取对应数据 332 | _m_arrTimingTaskNodeList[_m_iLastCheckTick].popAllRoundTaskAndMoveNextRound(_m_iLastCheckRound, _recList); 333 | } 334 | } 335 | finally 336 | { 337 | _unlockTimingTaskList(); 338 | } 339 | } 340 | } 341 | -------------------------------------------------------------------------------- /ALBasicClient/src/ALBasicClient/ALBasicClientSocket.java: -------------------------------------------------------------------------------- 1 | package ALBasicClient; 2 | 3 | import java.io.IOException; 4 | import java.nio.BufferOverflowException; 5 | import java.nio.ByteBuffer; 6 | import java.nio.channels.SocketChannel; 7 | import java.util.LinkedList; 8 | import java.util.concurrent.locks.ReentrantLock; 9 | 10 | import ALServerLog.ALServerLog; 11 | import BasicServer.S2C_BasicClientVerifyResult; 12 | 13 | public class ALBasicClientSocket 14 | { 15 | /** 对应于服务端的ID */ 16 | private long _m_iClientID; 17 | /** 对应的处理对象 */ 18 | private _AALBasicClientListener _m_clClient; 19 | /** 是否正在登录 */ 20 | private boolean _m_bLoginIng; 21 | /** 是否登录成功 */ 22 | private boolean _m_bLoged; 23 | /** 连接服务器的IP,端口 */ 24 | private String _m_sServerIP; 25 | private int _m_iServerPort; 26 | /** 连接的端口对象 */ 27 | private SocketChannel _m_scSocket; 28 | 29 | /** 发送队列锁 */ 30 | private ReentrantLock _m_rSendListMutex; 31 | /** 需要发送的消息队列 */ 32 | private LinkedList _m_lSendBufferList; 33 | 34 | /** 缓存读取字节的位置,长度根据配置设置 */ 35 | private int _m_sBufferLen; 36 | private ByteBuffer _m_bByteBuffer; 37 | 38 | public ALBasicClientSocket(_AALBasicClientListener _client, String _serverIP, int _serverPort) 39 | { 40 | _m_iClientID = 0; 41 | _m_sServerIP = _serverIP; 42 | _m_iServerPort = _serverPort; 43 | _m_scSocket = null; 44 | 45 | _m_clClient = _client; 46 | 47 | _m_rSendListMutex = new ReentrantLock(); 48 | _m_lSendBufferList = new LinkedList(); 49 | 50 | _m_bLoginIng = false; 51 | _m_bLoged = false; 52 | _m_sBufferLen = 0; 53 | _m_bByteBuffer = ByteBuffer.allocate(ALBasicClientConf.getInstance().getRecBufferLen()); 54 | _m_bByteBuffer.clear(); 55 | } 56 | 57 | public long getID() {return _m_iClientID;} 58 | public boolean getIsLoginIng() {return _m_bLoginIng;} 59 | public _AALBasicClientListener getClient() {return _m_clClient;} 60 | 61 | /************** 62 | * 判断是否正在连接状态 63 | * 64 | * @author alzq.z 65 | * @time Mar 17, 2013 10:52:53 PM 66 | */ 67 | public boolean getIsConnecting() 68 | { 69 | if(_m_bLoginIng || _m_bLoged) 70 | return true; 71 | 72 | return false; 73 | } 74 | 75 | /****************** 76 | * 登录操作 77 | * 78 | * @author alzq.z 79 | * @time Feb 19, 2013 9:57:25 PM 80 | */ 81 | public void login(int _clientType, String _userName, String _userPassword, String _customMsg) 82 | { 83 | if(_m_bLoginIng || _m_bLoged) 84 | return ; 85 | 86 | _m_bLoginIng = true; 87 | 88 | ALBasicClientRecThread recThread = 89 | new ALBasicClientRecThread(_clientType, _userName, _userPassword, _customMsg, this, _m_sServerIP, _m_iServerPort); 90 | recThread.start(); 91 | } 92 | 93 | /******************** 94 | * 将消息添加到发送队列,等待发送 95 | * 96 | * @author alzq.z 97 | * @time Feb 19, 2013 9:57:33 PM 98 | */ 99 | public void send(ByteBuffer _buf) 100 | { 101 | if(null == _m_scSocket || null == _buf || _buf.remaining() == 0) 102 | return ; 103 | 104 | boolean needAddToSendList = false; 105 | _lockBuf(); 106 | 107 | //判断当前队列是否有剩余协议,表明是否需要将socket添加到对应发送队列中 108 | if(_m_lSendBufferList.isEmpty()) 109 | needAddToSendList = true; 110 | 111 | //先插入长度数据,后插入实际数据 112 | ByteBuffer lenthBuffer = ByteBuffer.allocate(4); 113 | lenthBuffer.putInt(_buf.remaining()); 114 | lenthBuffer.flip(); 115 | 116 | _m_lSendBufferList.add(lenthBuffer); 117 | _m_lSendBufferList.add(_buf); 118 | 119 | _unlockBuf(); 120 | 121 | if(needAddToSendList) 122 | ALBasicSendingClientManager.getInstance().addSendSocket(this); 123 | } 124 | 125 | /**************** 126 | * 对数据添加临时头的发送方式 127 | * 128 | * @author alzq.z 129 | * @time Feb 19, 2013 9:59:13 PM 130 | */ 131 | public void send(ByteBuffer _tmpHeader, ByteBuffer _buf) 132 | { 133 | if(null == _m_scSocket || null == _buf || _buf.remaining() == 0) 134 | return ; 135 | 136 | boolean needAddToSendList = false; 137 | _lockBuf(); 138 | 139 | //判断当前队列是否有剩余协议,表明是否需要将socket添加到对应发送队列中 140 | if(_m_lSendBufferList.isEmpty()) 141 | needAddToSendList = true; 142 | 143 | //先插入长度数据,后插入实际数据 144 | ByteBuffer lenthBuffer = ByteBuffer.allocate(4); 145 | lenthBuffer.putInt(_buf.remaining() + _tmpHeader.remaining()); 146 | lenthBuffer.flip(); 147 | 148 | _m_lSendBufferList.add(lenthBuffer); 149 | _m_lSendBufferList.add(_tmpHeader); 150 | _m_lSendBufferList.add(_buf); 151 | 152 | _unlockBuf(); 153 | 154 | if(needAddToSendList) 155 | ALBasicSendingClientManager.getInstance().addSendSocket(this); 156 | } 157 | 158 | /********************** 159 | * 实际的发送函数,尝试发送尽量多的消息,并判断是否有剩余消息需要发送
160 | * 发送完成后判断是否有剩余消息,并在计划队列中添加节点
161 | * 162 | * @author alzq.z 163 | * @time Feb 19, 2013 9:59:24 PM 164 | */ 165 | protected void _realSendMessage() 166 | { 167 | if(null == _m_scSocket) 168 | return ; 169 | 170 | if(!_m_scSocket.isConnected()) 171 | { 172 | ALBasicSendingClientManager.getInstance().addSendSocket(this); 173 | return ; 174 | } 175 | 176 | boolean needAddToSendList = false; 177 | _lockBuf(); 178 | 179 | while(!_m_lSendBufferList.isEmpty()) 180 | { 181 | //Socket 允许写入操作时 182 | ByteBuffer buf = _m_lSendBufferList.getFirst(); 183 | 184 | if(buf.remaining() <= 0) 185 | { 186 | ALServerLog.Error("try to send a null buffer"); 187 | ALServerLog.Error("Wrong buffer:"); 188 | for(int i = 0; i < buf.limit(); i++) 189 | { 190 | ALServerLog.Error(buf.get(i) + " "); 191 | } 192 | } 193 | 194 | try { 195 | _m_scSocket.write(buf); 196 | 197 | //判断写入后对应数据的读取指针位置 198 | if(buf.remaining() <= 0) 199 | _m_lSendBufferList.pop(); 200 | else 201 | break; 202 | } 203 | catch (IOException e) 204 | { 205 | ALServerLog.Error("Client Socket send message error! socket id[" + getID() + "]"); 206 | e.printStackTrace(); 207 | break; 208 | } 209 | } 210 | 211 | //当需要发送队列不为空时,继续添加发送节点 212 | if(!_m_lSendBufferList.isEmpty()) 213 | needAddToSendList = true; 214 | 215 | _unlockBuf(); 216 | 217 | if(needAddToSendList) 218 | ALBasicSendingClientManager.getInstance().addSendSocket(this); 219 | } 220 | 221 | /********************* 222 | * 接收函数中将接收到的字节放入消息中,根据Socket之前收的残留信息进行一并处理。 223 | * 224 | * @author alzq.z 225 | * @time Feb 19, 2013 10:00:23 PM 226 | */ 227 | protected void _socketReceivingMessage(ByteBuffer _buf) 228 | { 229 | //将数据放入缓冲中 230 | try 231 | { 232 | _m_bByteBuffer.put(_buf); 233 | } 234 | catch (BufferOverflowException e) 235 | { 236 | ALServerLog.Error("_socketReceivingMessage length is too long, Socket Buffer need more!"); 237 | _m_bByteBuffer.put(_buf.array(), 0, _m_bByteBuffer.remaining()); 238 | //放置缓冲区读取指针 239 | _buf.position(_m_bByteBuffer.remaining()); 240 | } 241 | 242 | if(0 == _m_sBufferLen) 243 | { 244 | //尚未读取长度前 245 | if(_m_bByteBuffer.position() >= 4) 246 | { 247 | //当缓冲中字节大于2时可获取对应的消息长度 248 | _m_sBufferLen = _m_bByteBuffer.getInt(0); 249 | } 250 | } 251 | 252 | //当长度有效则判断是否到达消息末尾 253 | int bufLen = _m_bByteBuffer.position(); 254 | int startPos = 0; 255 | while(0 != _m_sBufferLen && bufLen >= startPos + _m_sBufferLen + 4) 256 | { 257 | //到达消息末尾,将消息取出,并清除缓存消息 258 | ByteBuffer message = ByteBuffer.allocate(_m_sBufferLen); 259 | message.put(_m_bByteBuffer.array(), startPos + 4, _m_sBufferLen); 260 | message.flip(); 261 | 262 | startPos = startPos + _m_sBufferLen + 4; 263 | 264 | //添加消息 265 | if(_m_bLoged) 266 | { 267 | _m_clClient.receiveMes(message); 268 | } 269 | else 270 | { 271 | //处理登录操作 272 | _checkLoginMes(message); 273 | } 274 | 275 | //根据长度设置对应消息长度 276 | if(bufLen - startPos > 4) 277 | { 278 | //当缓冲中字节大于2时可获取对应的消息长度 279 | _m_sBufferLen = _m_bByteBuffer.getInt(startPos); 280 | } 281 | else 282 | { 283 | _m_sBufferLen = 0; 284 | break; 285 | } 286 | } 287 | 288 | //当数据经过了拷贝则将剩余数据拷贝放入缓存 289 | if(startPos != 0) 290 | { 291 | ByteBuffer tmpBuf = ByteBuffer.allocate(bufLen - startPos); 292 | tmpBuf.put(_m_bByteBuffer.array(), startPos, bufLen - startPos); 293 | tmpBuf.flip(); 294 | 295 | _m_bByteBuffer.clear(); 296 | _m_bByteBuffer.put(tmpBuf); 297 | } 298 | 299 | //如原先缓存数据未完全放入,此时将剩余数据放入 300 | if(_buf.remaining() > 0) 301 | { 302 | _m_bByteBuffer.put(_buf); 303 | } 304 | } 305 | 306 | protected SocketChannel _getSocketChannel() throws Exception 307 | { 308 | if(null == _m_scSocket) 309 | _m_scSocket = SocketChannel.open(); 310 | 311 | return _m_scSocket; 312 | } 313 | 314 | /************* 315 | * 未登录情况下对返回信息进行处理 316 | * 317 | * @author alzq.z 318 | * @time Feb 19, 2013 10:02:04 PM 319 | */ 320 | protected void _checkLoginMes(ByteBuffer _mes) 321 | { 322 | _m_bLoginIng = false; 323 | 324 | try 325 | { 326 | S2C_BasicClientVerifyResult msg = new S2C_BasicClientVerifyResult(); 327 | msg.readPackage(_mes); 328 | 329 | //获取ID 330 | _m_iClientID = msg.getSocketID(); 331 | 332 | //直接当作登录成功处理,未成功将直接断开 333 | _m_bLoged = true; 334 | _m_clClient.LoginSuc(msg.getCustomRetMsg()); 335 | } 336 | catch (Exception e) 337 | { 338 | _logout(); 339 | } 340 | } 341 | 342 | /************* 343 | * 断开连接 344 | * 345 | * @author alzq.z 346 | * @time Feb 19, 2013 10:07:34 PM 347 | */ 348 | protected void _logout() 349 | { 350 | if(null != _m_scSocket) 351 | { 352 | try 353 | { 354 | _m_scSocket.close(); 355 | } 356 | catch (IOException e){} 357 | } 358 | 359 | _clearLoginValidate(); 360 | } 361 | 362 | /*********** 363 | * 清空连接相关变量 364 | * 365 | * @author alzq.z 366 | * @time Feb 19, 2013 10:07:39 PM 367 | */ 368 | protected void _clearLoginValidate() 369 | { 370 | if(_m_bLoged) 371 | { 372 | //已经登录了为退出操作 373 | _m_clClient.Disconnect(); 374 | } 375 | else if(_m_bLoginIng) 376 | { 377 | //正在登录为连接失败操作 378 | _m_clClient.ConnectFail(); 379 | } 380 | else 381 | { 382 | //其他情况为登录失败操作 383 | _m_clClient.LoginFail(); 384 | } 385 | 386 | _m_bLoged = false; 387 | _m_bLoginIng = false; 388 | _m_scSocket = null; 389 | } 390 | 391 | protected void _lockBuf() 392 | { 393 | _m_rSendListMutex.lock(); 394 | } 395 | protected void _unlockBuf() 396 | { 397 | _m_rSendListMutex.unlock(); 398 | } 399 | } 400 | -------------------------------------------------------------------------------- /ALBasicServer/src/ALBasicServer/ALSocket/ALBasicServerSocket.java: -------------------------------------------------------------------------------- 1 | package ALBasicServer.ALSocket; 2 | 3 | import java.nio.BufferOverflowException; 4 | import java.nio.ByteBuffer; 5 | import java.nio.channels.SocketChannel; 6 | import java.util.LinkedList; 7 | import java.util.concurrent.locks.ReentrantLock; 8 | 9 | import ALBasicServer.ALServerSynTask.ALSynTaskManager; 10 | import ALBasicServer.ALVerifyObj.ALVerifyObjMgr; 11 | import ALServerLog.ALServerLog; 12 | import BasicServer.C2S_BasicClientVerifyInfo; 13 | 14 | 15 | public class ALBasicServerSocket 16 | { 17 | /** 对应的连接ID */ 18 | private long _m_ID; 19 | /** 验证对象的序列号 */ 20 | private int _m_iVerifyObjIdx; 21 | /** 对应的连接对象 */ 22 | private SocketChannel _m_scSocketChannel; 23 | /** 对应的处理对象 */ 24 | private _AALBasicServerSocketListener _m_clListener; 25 | /** 验证时传入的客户端类型 */ 26 | private int _m_iLoginClientType; 27 | /** 验证时传入的用户名 */ 28 | private String _m_sUserName; 29 | /** 验证时传入的用户密码 */ 30 | private String _m_sUserPassword; 31 | /** 验证时传入的自定义信息 */ 32 | private String _m_sLoginCustomMsg; 33 | /** 是否正在登录 */ 34 | private boolean _m_bLoginIng; 35 | 36 | /** 对方连接的信息 */ 37 | private String _m_ConnectIP; 38 | private int _m_iConnectPort; 39 | 40 | /** 接收到的消息相关处理 */ 41 | private ReentrantLock _m_rRecMessageMutex; 42 | private LinkedList _m_lRecMessageList; 43 | 44 | /** 发送队列锁 */ 45 | private ReentrantLock _m_rSendListMutex; 46 | /** 需要发送的消息队列 */ 47 | private LinkedList _m_lSendBufferList; 48 | 49 | /** 缓存读取字节的位置,长度根据配置设置 */ 50 | private int _m_sBufferLen; 51 | private ByteBuffer _m_bByteBuffer; 52 | 53 | public ALBasicServerSocket(long _id, int _verifyObjIdx, SocketChannel _channel, int _bufLen) 54 | { 55 | _m_ID = _id; 56 | _m_iVerifyObjIdx = _verifyObjIdx; 57 | _m_scSocketChannel = _channel; 58 | 59 | _m_clListener = null; 60 | _m_sUserName = null; 61 | _m_sUserPassword = null; 62 | 63 | _m_rRecMessageMutex = new ReentrantLock(); 64 | _m_lRecMessageList = new LinkedList(); 65 | 66 | _m_rSendListMutex = new ReentrantLock(); 67 | _m_lSendBufferList = new LinkedList(); 68 | 69 | _m_sBufferLen = 0; 70 | _m_bByteBuffer = ByteBuffer.allocate(_bufLen); 71 | _m_bByteBuffer.clear(); 72 | } 73 | 74 | public long getSocketID() {return _m_ID;} 75 | public int getVerifyObjIdx() {return _m_iVerifyObjIdx;} 76 | public int getLoginClientType() {return _m_iLoginClientType;} 77 | public String getUserName() {return _m_sUserName;} 78 | public String getUserPassword() {return _m_sUserPassword;} 79 | public String getLoginCustomMsg() {return _m_sLoginCustomMsg;} 80 | public _AALBasicServerSocketListener getListener() {return _m_clListener;} 81 | public String getIP() {return _m_ConnectIP;} 82 | public int getPort() {return _m_iConnectPort;} 83 | 84 | /************** 85 | * 设置处理对象 86 | * @param _listener 87 | */ 88 | public void setListener(_AALBasicServerSocketListener _listener) 89 | { 90 | _m_clListener = _listener; 91 | } 92 | 93 | /************** 94 | * 设置登录过程完成 95 | * 96 | * @author alzq.z 97 | * @time Feb 19, 2013 2:44:56 PM 98 | */ 99 | public void setLoginEnd() 100 | { 101 | _m_bLoginIng = false; 102 | } 103 | 104 | /******************** 105 | * 将消息添加到发送队列,等待发送 106 | * 107 | * @author alzq.z 108 | * @time Feb 19, 2013 1:42:24 PM 109 | */ 110 | public void send(ByteBuffer _buf) 111 | { 112 | if(null == _m_scSocketChannel || null == _buf || _buf.remaining() == 0) 113 | return ; 114 | 115 | boolean needAddToSendList = false; 116 | _lockBuf(); 117 | 118 | //判断当前队列是否有剩余协议 119 | //当当前无发送消息存在于队列中时,需要将socket添加到对应发送队列中 120 | if(_m_lSendBufferList.isEmpty()) 121 | needAddToSendList = true; 122 | 123 | //先插入长度数据,后插入实际数据 124 | ByteBuffer lenthBuffer = ByteBuffer.allocate(4); 125 | lenthBuffer.putInt(_buf.remaining()); 126 | lenthBuffer.flip(); 127 | 128 | _m_lSendBufferList.add(lenthBuffer); 129 | _m_lSendBufferList.add(_buf); 130 | 131 | _unlockBuf(); 132 | 133 | if(needAddToSendList) 134 | ALServerSendSocketMgr.getInstance().addSendSocket(this); 135 | } 136 | /***************** 137 | * 增加函数用于将两段数据作为一个数据包发送。
138 | * 用于一些拼凑数据发送。(如协议对象发送)
139 | * 140 | * @author alzq.z 141 | * @time Feb 19, 2013 1:46:29 PM 142 | */ 143 | public void send(ByteBuffer _tmpHeader, ByteBuffer _buf) 144 | { 145 | if(null == _m_scSocketChannel || null == _buf || _buf.remaining() == 0) 146 | return ; 147 | 148 | boolean needAddToSendList = false; 149 | _lockBuf(); 150 | 151 | //判断当前队列是否有剩余协议 152 | //当当前无发送消息存在于队列中时,需要将socket添加到对应发送队列中 153 | if(_m_lSendBufferList.isEmpty()) 154 | needAddToSendList = true; 155 | 156 | //先插入长度数据,后插入实际数据 157 | ByteBuffer lenthBuffer = ByteBuffer.allocate(4); 158 | lenthBuffer.putInt(_buf.remaining() + _tmpHeader.remaining()); 159 | lenthBuffer.flip(); 160 | 161 | _m_lSendBufferList.add(lenthBuffer); 162 | _m_lSendBufferList.add(_tmpHeader); 163 | _m_lSendBufferList.add(_buf); 164 | 165 | _unlockBuf(); 166 | 167 | if(needAddToSendList) 168 | ALServerSendSocketMgr.getInstance().addSendSocket(this); 169 | } 170 | 171 | /***************** 172 | * 直接将字节数据作为一个完整包发送,不增加长度等消息
173 | * 用于一些可扩展的发送方式,如Group
174 | * 175 | * @author alzq.z 176 | * @time Feb 19, 2013 1:48:07 PM 177 | */ 178 | public void sendRealDataBuffer(ByteBuffer _buf) 179 | { 180 | if(null == _m_scSocketChannel || null == _buf || _buf.remaining() == 0) 181 | return ; 182 | 183 | boolean needAddToSendList = false; 184 | _lockBuf(); 185 | 186 | //判断当前队列是否有剩余协议 187 | //当当前无发送消息存在于队列中时,需要将socket添加到对应发送队列中 188 | if(_m_lSendBufferList.isEmpty()) 189 | needAddToSendList = true; 190 | 191 | _m_lSendBufferList.add(_buf); 192 | 193 | _unlockBuf(); 194 | 195 | if(needAddToSendList) 196 | ALServerSendSocketMgr.getInstance().addSendSocket(this); 197 | } 198 | 199 | /********************** 200 | * 实际的发送函数,尝试发送尽量多的消息,并判断是否有剩余消息需要发送
201 | * 发送完成后判断是否有消息未发送完毕
202 | * 如有消息未发送完毕,需要添加下一轮的发送任务
203 | * 204 | * @author alzq.z 205 | * @time Feb 19, 2013 2:00:56 PM 206 | */ 207 | protected void _realSendMessage() 208 | { 209 | if(null == _m_scSocketChannel) 210 | return ; 211 | 212 | boolean needAddToSendList = false; 213 | //是否需要延迟发送,当写入操作无法将数据写入时,需要延迟发送 214 | //避免因为网速问题导致不断循环发送一个Socket而使Socket占用达到100% 215 | boolean needDelaySend = false; 216 | //总体写入数据的长度 217 | int totalWriteBufLen = 0; 218 | _lockBuf(); 219 | 220 | while(!_m_lSendBufferList.isEmpty()) 221 | { 222 | //Socket 允许写入操作时 223 | ByteBuffer buf = _m_lSendBufferList.getFirst(); 224 | 225 | if(buf.remaining() <= 0) 226 | { 227 | ALServerLog.Error("try to send a null buffer"); 228 | ALServerLog.Error("Wrong buffer Src Data:"); 229 | for(int i = 0; i < buf.limit(); i++) 230 | { 231 | ALServerLog.Error(buf.get(i) + " "); 232 | } 233 | } 234 | 235 | try { 236 | //统计写入数据的长度 237 | totalWriteBufLen += _m_scSocketChannel.write(buf); 238 | 239 | //判断写入后对应数据的读取指针位置 240 | if(buf.remaining() <= 0) 241 | _m_lSendBufferList.pop(); 242 | else 243 | break; 244 | } 245 | catch (Exception e) 246 | { 247 | ALServerLog.Error("Socket send message error! user[" + _m_sUserName + "]"); 248 | e.printStackTrace(); 249 | ALServerSocketMgr.getInstance().kickUser(this); 250 | _unlockBuf(); 251 | return ; 252 | } 253 | } 254 | 255 | //判断总体写入数据的长度 256 | if(totalWriteBufLen <= 0) 257 | needDelaySend = true; 258 | 259 | //当需要发送队列不为空时,继续添加发送节点 260 | if(!_m_lSendBufferList.isEmpty()) 261 | needAddToSendList = true; 262 | 263 | _unlockBuf(); 264 | 265 | if(needAddToSendList) 266 | { 267 | if(needDelaySend) 268 | { 269 | //使用定时任务的定时处理方式进行延迟发送 270 | ALSynTaskManager.getInstance().regTask(new SynDelaySendTask(this), 50); 271 | } 272 | else 273 | { 274 | ALServerSendSocketMgr.getInstance().addSendSocket(this); 275 | } 276 | } 277 | } 278 | 279 | /******************** 280 | * 将消息添加到待处理消息队列中 281 | * 282 | * @author alzq.z 283 | * @time Feb 19, 2013 2:13:48 PM 284 | */ 285 | protected void _addRecMessage(ByteBuffer _mes) 286 | { 287 | if(null == _m_scSocketChannel) 288 | return ; 289 | 290 | boolean needAddDealTask = false; 291 | _lockRecMes(); 292 | 293 | //判断处理消息队列中是否已经有数据 294 | //如无数据,表明需要将socket添加到对应处理队列中 295 | if(_m_lRecMessageList.isEmpty()) 296 | needAddDealTask = true; 297 | 298 | _m_lRecMessageList.add(_mes); 299 | 300 | _unlockRecMes(); 301 | 302 | if(needAddDealTask) 303 | ALSynTaskManager.getInstance().regTask(new SynReceiveMessageTask(this)); 304 | } 305 | 306 | /********************** 307 | * 消息处理函数,将队列中第一个消息取出并处理。根据取出时消息队列剩余数量决定是否在任务队列末尾添加对应的处理任务
308 | * 此函数在同步任务中处理 309 | * 310 | * @author alzq.z 311 | * @time Feb 19, 2013 2:17:02 PM 312 | */ 313 | protected void _dealRecMessage() 314 | { 315 | if(null == _m_scSocketChannel) 316 | return ; 317 | 318 | ByteBuffer buf = null; 319 | boolean needAddDealTask = false; 320 | 321 | _lockRecMes(); 322 | 323 | if(!_m_lRecMessageList.isEmpty()) 324 | { 325 | //非空才能取出第一个消息对象 326 | buf = _m_lRecMessageList.getFirst(); 327 | } 328 | 329 | _unlockRecMes(); 330 | 331 | if(null != buf) 332 | { 333 | //处理消息 334 | try 335 | { 336 | _m_clListener.receiveMsg(buf); 337 | } 338 | catch(Exception ex) 339 | { 340 | ex.printStackTrace(); 341 | } 342 | } 343 | 344 | _lockRecMes(); 345 | 346 | //必须在处理完成后才删除BUF,否在在处理过程中可能因为插入接收数据导致同时开启第2个任务进行消息处理 347 | _m_lRecMessageList.pop(); 348 | 349 | //当需要发送队列不为空时,继续添加发送节点 350 | if(!_m_lRecMessageList.isEmpty()) 351 | needAddDealTask = true; 352 | 353 | _unlockRecMes(); 354 | 355 | if(needAddDealTask) 356 | ALSynTaskManager.getInstance().regTask(new SynReceiveMessageTask(this)); 357 | } 358 | 359 | /********************* 360 | * 接收函数中将接收到的字节放入消息缓冲区中,根据消息组装原理进行消息拆分
361 | * 并将拆分后的成型消息放入待处理消息队列中 362 | * 363 | * @author alzq.z 364 | * @time Feb 19, 2013 2:23:16 PM 365 | */ 366 | protected void _socketReceivingMessage(ByteBuffer _buf) 367 | { 368 | //将数据放入缓冲中 369 | try 370 | { 371 | _m_bByteBuffer.put(_buf); 372 | } 373 | catch (BufferOverflowException e) 374 | { 375 | //长度不足,此时提示 376 | ALServerLog.Error("_socketReceivingMessage length is too long, Socket Buffer need more!"); 377 | _m_bByteBuffer.put(_buf.array(), 0, _m_bByteBuffer.remaining()); 378 | //放置待插入数据中指针位置为缓冲区读取指针,可在数据处理后再将数据放入缓存一次 379 | _buf.position(_m_bByteBuffer.remaining()); 380 | } 381 | 382 | if(0 == _m_sBufferLen) 383 | { 384 | //尚未读取长度前 385 | if(_m_bByteBuffer.position() >= 4) 386 | { 387 | //当缓冲中字节大于2时可获取对应的消息长度 388 | _m_sBufferLen = _m_bByteBuffer.getInt(0); 389 | } 390 | } 391 | 392 | //当长度有效则判断是否到达消息末尾 393 | int bufLen = _m_bByteBuffer.position(); 394 | int startPos = 0; 395 | while(0 != _m_sBufferLen && bufLen >= startPos + _m_sBufferLen + 4) 396 | { 397 | //到达消息末尾,将消息取出,并清除缓存消息 398 | ByteBuffer message = ByteBuffer.allocate(_m_sBufferLen); 399 | message.put(_m_bByteBuffer.array(), startPos + 4, _m_sBufferLen); 400 | message.flip(); 401 | 402 | //设置新的开始位置 403 | startPos = startPos + _m_sBufferLen + 4; 404 | 405 | //添加消息 406 | if(null != _m_clListener) 407 | { 408 | _addRecMessage(message); 409 | } 410 | else 411 | { 412 | //处理登录操作 413 | _login(message); 414 | } 415 | 416 | //根据长度设置对应消息长度 417 | if(bufLen - startPos > 4) 418 | { 419 | //当缓冲中字节大于2时可获取对应的消息长度 420 | _m_sBufferLen = _m_bByteBuffer.getInt(startPos); 421 | } 422 | else 423 | { 424 | _m_sBufferLen = 0; 425 | break; 426 | } 427 | } 428 | 429 | //判断数据经过了操作 430 | //如数据经过了操作需要将剩余数据重新拷贝放入缓存 431 | if(startPos != 0) 432 | { 433 | ByteBuffer tmpBuf = ByteBuffer.allocate(bufLen - startPos); 434 | tmpBuf.put(_m_bByteBuffer.array(), startPos, bufLen - startPos); 435 | tmpBuf.flip(); 436 | 437 | _m_bByteBuffer.clear(); 438 | _m_bByteBuffer.put(tmpBuf); 439 | } 440 | 441 | //如原先缓存数据未完全放入,此时将剩余数据放入 442 | if(_buf.remaining() > 0) 443 | { 444 | _m_bByteBuffer.put(_buf); 445 | } 446 | } 447 | 448 | /******************** 449 | * 处理Socket的连接创建操作 450 | * 451 | * @author alzq.z 452 | * @time Feb 19, 2013 2:30:22 PM 453 | */ 454 | protected void _login(ByteBuffer _loginBuf) 455 | { 456 | if(null == _m_scSocketChannel || _m_bLoginIng || null != _m_clListener) 457 | return ; 458 | 459 | C2S_BasicClientVerifyInfo info = new C2S_BasicClientVerifyInfo(); 460 | try 461 | { 462 | info.readPackage(_loginBuf); 463 | } 464 | catch (Exception e) 465 | { 466 | //读取信息直接异常,则踢出用户 467 | ALServerSocketMgr.getInstance().kickUser(this); 468 | return ; 469 | } 470 | 471 | //设置正在登录 472 | _m_bLoginIng = true; 473 | 474 | //还未登录进入登录流程 475 | _m_iLoginClientType = info.getClientType(); 476 | _m_sUserName = info.getUserName(); 477 | _m_sUserPassword = info.getUserPassword(); 478 | _m_sLoginCustomMsg = info.getCustomMsg(); 479 | 480 | if(null != _m_scSocketChannel) 481 | { 482 | _m_ConnectIP = _m_scSocketChannel.socket().getInetAddress().getHostAddress(); 483 | _m_iConnectPort = _m_scSocketChannel.socket().getPort(); 484 | } 485 | 486 | //开启异步处理登录 487 | ALVerifyObjMgr.getInstance().addVerifySocket(this); 488 | } 489 | 490 | protected void _removeChannel() 491 | { 492 | _m_scSocketChannel = null; 493 | } 494 | 495 | protected SocketChannel _getSocketChannel() 496 | { 497 | return _m_scSocketChannel; 498 | } 499 | 500 | protected void _lockBuf() 501 | { 502 | _m_rSendListMutex.lock(); 503 | } 504 | protected void _unlockBuf() 505 | { 506 | _m_rSendListMutex.unlock(); 507 | } 508 | 509 | protected void _lockRecMes() 510 | { 511 | _m_rRecMessageMutex.lock(); 512 | } 513 | protected void _unlockRecMes() 514 | { 515 | _m_rRecMessageMutex.unlock(); 516 | } 517 | } 518 | --------------------------------------------------------------------------------