├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── build.xml ├── config ├── .gitignore ├── README.md ├── build-config.xml ├── pom.xml └── src │ ├── main │ └── java │ │ └── org │ │ └── grain │ │ └── config │ │ ├── ConfigManager.java │ │ ├── ConfigUtil.java │ │ ├── DefaultConfig.java │ │ └── ITemplate.java │ └── test │ ├── java │ └── org │ │ └── grain │ │ └── config │ │ ├── ConfigManagerTest.java │ │ └── TestTemplate.java │ └── resources │ └── TestConfigData │ ├── config.json │ ├── config_map_test.xml │ └── test.txt ├── distributedlock-clienttest ├── .gitignore ├── pom.xml └── src │ └── main │ ├── java │ ├── log │ │ └── MyAppender.java │ └── test │ │ ├── DistributedlockClientTest.java │ │ ├── GrainLog.java │ │ └── TestMsgService.java │ └── resources │ └── log4j.properties ├── distributedlock-servertest ├── .gitignore ├── pom.xml └── src │ └── main │ ├── java │ ├── log │ │ └── MyAppender.java │ └── test │ │ ├── DistributedlockServerTest.java │ │ └── GrainLog.java │ └── resources │ └── log4j.properties ├── distributedlock ├── .gitignore ├── README.md ├── build-distributedlock.xml ├── distributedlock-client.png ├── distributedlock-client.vsd ├── distributedlock-server.png ├── distributedlock-server.vsd ├── pom.xml ├── protobuf │ ├── DistributedLock.proto │ ├── protobuf编译.bat │ └── protoc.exe └── src │ └── main │ └── java │ └── org │ └── grain │ └── distributedlock │ ├── DistributedLockClient.java │ ├── DistributedLockServer.java │ ├── DistributedLockService.java │ ├── DistributedlockConfig.java │ ├── DistributedlockMsg.java │ ├── DistributedlockServerHandler.java │ ├── DistributedlockTCode.java │ ├── DistributedlockTcpManager.java │ ├── MergeTCPService.java │ ├── MinaClientService.java │ └── tcp │ └── DistributedLock.java ├── grain-framework.png ├── grain-framework.vsd ├── httpclient ├── .gitignore ├── README.md ├── build-httpclient.xml ├── pom.xml └── src │ ├── main │ └── java │ │ └── org │ │ └── grain │ │ └── httpclient │ │ ├── HttpUtil.java │ │ └── TrustStrategyAll.java │ └── test │ ├── java │ └── org │ │ └── grain │ │ └── httpclient │ │ └── HttpUtilTest.java │ └── resources │ └── k_nearest_neighbors.png ├── httpserver-test ├── .gitignore ├── pom.xml ├── protobuf │ ├── UserGroupProto.proto │ ├── protobuf编译.bat │ └── protoc.exe └── src │ └── main │ ├── java │ ├── log │ │ └── MyAppender.java │ ├── protobuf │ │ └── http │ │ │ └── UserGroupProto.java │ ├── server │ │ └── ExpandServer.java │ └── test │ │ ├── GrainLog.java │ │ ├── TestHttpService.java │ │ └── UploadProgressListener.java │ ├── resources │ └── log4j.properties │ └── webapp │ ├── META-INF │ └── MANIFEST.MF │ ├── WEB-INF │ └── web.xml │ ├── index.html │ └── js │ └── juggle-all.js ├── httpserver ├── .gitignore ├── README.md ├── build-httpserver.xml ├── pom.xml └── src │ └── main │ └── java │ └── org │ └── grain │ └── httpserver │ ├── AllowParam.java │ ├── CodeUtils.java │ ├── CrossDomainHttpFilter.java │ ├── FileData.java │ ├── FileHttpFilter.java │ ├── HSession.java │ ├── HeadDataHttpFilter.java │ ├── HeadParam.java │ ├── HttpConfig.java │ ├── HttpException.java │ ├── HttpManager.java │ ├── HttpPacket.java │ ├── IExpandServer.java │ ├── IHttpFilter.java │ ├── IHttpListener.java │ ├── IUploadProgress.java │ ├── InitHttpServer.java │ ├── PacketHttpFilter.java │ ├── PacketUtils.java │ ├── ReadUtils.java │ ├── ReplyFile.java │ ├── ReplyImage.java │ ├── ReplyString.java │ ├── ReplyUtil.java │ └── URLUtil.java ├── log ├── .gitignore ├── README.md ├── build-log.xml ├── pom.xml └── src │ ├── main │ └── java │ │ └── org │ │ └── grain │ │ └── log │ │ ├── ILog.java │ │ └── RunMonitor.java │ └── test │ └── java │ └── org │ └── grain │ └── log │ ├── LogObjTest.java │ ├── LogTest.java │ └── RunMonitorTest.java ├── mariadb ├── .gitignore ├── README.md ├── build-mariadb.xml ├── pom.xml └── src │ ├── main │ └── java │ │ └── org │ │ └── grain │ │ └── mariadb │ │ └── MybatisManager.java │ └── test │ ├── java │ └── org │ │ └── grain │ │ └── mariadb │ │ ├── MybatisManagerTest.java │ │ ├── PaginationPlugin.java │ │ ├── dao │ │ └── base │ │ │ └── TesttableMapper.java │ │ └── model │ │ └── base │ │ ├── Testtable.java │ │ └── TesttableCriteria.java │ └── resources │ ├── TestConfigData │ ├── generatorConfig.xml │ ├── mariadbtest.sql │ └── mybatis-config.xml │ └── org │ └── grain │ └── mariadb │ └── mappers │ └── base │ └── TesttableMapper.xml ├── mongodb ├── .gitignore ├── README.md ├── build-mongodb.xml ├── createdb.txt ├── pom.xml └── src │ ├── main │ └── java │ │ └── org │ │ └── grain │ │ └── mongo │ │ ├── MongoConfig.java │ │ ├── MongoObj.java │ │ └── MongodbManager.java │ └── test │ └── java │ └── org │ └── grain │ └── mongo │ ├── MongodbManagerTest.java │ └── TestMongo.java ├── msg ├── .gitignore ├── README.md ├── build-msg.xml ├── pom.xml └── src │ ├── main │ └── java │ │ └── org │ │ └── grain │ │ └── msg │ │ ├── IMsgListener.java │ │ ├── MsgManager.java │ │ └── MsgPacket.java │ └── test │ └── java │ └── org │ └── grain │ └── msg │ ├── MsgManagerTest.java │ └── TestMsgListener.java ├── pom.xml ├── redis ├── .gitignore ├── README.md ├── build-redis.xml ├── pom.xml └── src │ ├── main │ └── java │ │ └── org │ │ └── grain │ │ └── redis │ │ ├── DeserializingConverter.java │ │ ├── IConverter.java │ │ ├── RedisManager.java │ │ └── SerializingConverter.java │ └── test │ └── java │ └── org │ └── grain │ └── redis │ ├── RedisManagerTest.java │ └── RedisTest.java ├── rpc-clienttest ├── .gitignore ├── pom.xml └── src │ └── main │ ├── java │ ├── log │ │ └── MyAppender.java │ ├── protobuf │ │ └── tcp │ │ │ └── Test.java │ └── test │ │ ├── GrainLog.java │ │ ├── RPCClientTest.java │ │ ├── TestMsgService.java │ │ ├── TestRPCServiceC.java │ │ └── TestTCode.java │ └── resources │ └── log4j.properties ├── rpc-servertest ├── .gitignore ├── pom.xml ├── protobuf │ ├── Test.proto │ ├── protobuf编译.bat │ └── protoc.exe └── src │ └── main │ ├── java │ ├── log │ │ └── MyAppender.java │ ├── protobuf │ │ └── tcp │ │ │ └── Test.java │ └── test │ │ ├── GrainLog.java │ │ ├── RPCServerTest.java │ │ ├── TestMsgService.java │ │ ├── TestRPCServiceS.java │ │ └── TestTCode.java │ └── resources │ └── log4j.properties ├── rpc ├── .gitignore ├── README.md ├── build-rpc.xml ├── pom.xml ├── rpc-client.png ├── rpc-client.vsd ├── rpc-server.png ├── rpc-server.vsd └── src │ └── main │ └── java │ └── org │ └── grain │ └── rpc │ ├── ThreadMinaClientHandler.java │ ├── ThreadMinaServerHandler.java │ ├── ThreadTcpManager.java │ ├── WaitLock.java │ └── WaitLockManager.java ├── tcp-clienttest ├── .gitignore ├── pom.xml └── src │ └── main │ ├── java │ ├── log │ │ └── MyAppender.java │ ├── protobuf │ │ └── tcp │ │ │ └── Test.java │ └── test │ │ ├── GrainLog.java │ │ ├── TCPClientTest.java │ │ ├── TestMsgService.java │ │ ├── TestTCode.java │ │ └── TestTcpServiceC.java │ └── resources │ └── log4j.properties ├── tcp-servertest ├── .gitignore ├── pom.xml ├── protobuf │ ├── Test.proto │ ├── protobuf编译.bat │ └── protoc.exe └── src │ └── main │ ├── java │ ├── log │ │ └── MyAppender.java │ ├── protobuf │ │ └── tcp │ │ │ └── Test.java │ └── test │ │ ├── GrainLog.java │ │ ├── TCPServerTest.java │ │ ├── TestTCode.java │ │ └── TestTcpServiceS.java │ └── resources │ └── log4j.properties ├── tcp ├── .gitignore ├── README.md ├── build-tcp.xml ├── pom.xml └── src │ └── main │ └── java │ └── org │ └── grain │ └── tcp │ ├── ITcpListener.java │ ├── MinaClient.java │ ├── MinaClientHandler.java │ ├── MinaConfig.java │ ├── MinaDecoder.java │ ├── MinaEncoder.java │ ├── MinaHandler.java │ ├── MinaServer.java │ ├── MinaServerHandler.java │ ├── TcpManager.java │ ├── TcpMsg.java │ └── TcpPacket.java ├── thread.png ├── thread.pptx ├── thread ├── .gitignore ├── README.md ├── build-thread.xml ├── pom.xml └── src │ ├── main │ └── java │ │ └── org │ │ └── grain │ │ └── thread │ │ ├── AsyncHandleData.java │ │ ├── AsyncThread.java │ │ ├── AsyncThreadManager.java │ │ ├── ICycle.java │ │ ├── IHandle.java │ │ └── ThreadHandle.java │ └── test │ └── java │ └── org │ └── grain │ └── thread │ ├── AsyncThreadManagerTest.java │ ├── CycleTest.java │ ├── HandlerManagerTest.java │ └── PacketTest.java ├── threadkeylock ├── .gitignore ├── README.md ├── build-threadkeylock.xml ├── pom.xml └── src │ ├── main │ └── java │ │ └── org │ │ └── grain │ │ └── threadkeylock │ │ ├── KeyLock.java │ │ ├── KeyLockException.java │ │ ├── KeyLockManager.java │ │ └── KeylockFunction.java │ └── test │ └── java │ └── org │ └── grain │ └── threadkeylock │ └── KeyLockManagerTest.java ├── threadmsg ├── .gitignore ├── README.md ├── build-threadmsg.xml ├── pom.xml └── src │ ├── main │ └── java │ │ ├── META-INF │ │ └── MANIFEST.MF │ │ └── org │ │ └── grain │ │ └── threadmsg │ │ └── ThreadMsgManager.java │ └── test │ └── java │ └── org │ └── grain │ └── threadmsg │ ├── TestThreadMsgListener.java │ └── ThreadMsgManagerTest.java ├── threadwebsocket-test ├── .gitignore ├── pom.xml ├── protobuf │ ├── Test.proto │ ├── protobuf编译.bat │ └── protoc.exe └── src │ └── main │ ├── java │ ├── init │ │ └── InitServlet.java │ ├── log │ │ └── MyAppender.java │ ├── protobuf │ │ └── ws │ │ │ └── Test.java │ └── test │ │ ├── GrainLog.java │ │ └── TestWSService.java │ ├── resources │ └── log4j.properties │ └── webapp │ ├── META-INF │ └── MANIFEST.MF │ ├── WEB-INF │ └── web.xml │ ├── index.html │ └── js │ └── juggle-all.js ├── threadwebsocket ├── .gitignore ├── README.md ├── build-threadwebsocket.xml ├── pom.xml └── src │ └── main │ └── java │ └── org │ └── grain │ └── threadwebsocket │ ├── ThreadWSManager.java │ └── WebSocketServer.java ├── websocket-lib ├── .gitignore ├── README.md ├── build-websocket-lib.xml ├── pom.xml └── src │ └── main │ └── java │ └── org │ └── grain │ └── websokcetlib │ ├── IWSListener.java │ ├── PacketUtils.java │ ├── WSCodeUtil.java │ ├── WSManager.java │ ├── WSMsg.java │ ├── WebSocketDeCoder.java │ ├── WebSocketEnCoder.java │ └── WsPacket.java ├── websocket-test ├── .gitignore ├── pom.xml ├── protobuf │ ├── Test.proto │ ├── protobuf编译.bat │ └── protoc.exe └── src │ └── main │ ├── java │ ├── init │ │ └── InitServlet.java │ ├── log │ │ └── MyAppender.java │ ├── protobuf │ │ └── ws │ │ │ └── Test.java │ └── test │ │ ├── GrainLog.java │ │ └── TestWSService.java │ ├── resources │ └── log4j.properties │ └── webapp │ ├── META-INF │ └── MANIFEST.MF │ ├── WEB-INF │ └── web.xml │ ├── index.html │ └── js │ └── juggle-all.js └── websocket ├── .gitignore ├── README.md ├── build-websocket.xml ├── pom.xml └── src └── main └── java └── org └── grain └── websocket └── WebSocketServer.java /.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | .classpath 3 | .project 4 | .settings 5 | logs 6 | .idea 7 | *.iml -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: java 2 | install: 3 | - mvn install -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 电霸儿 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /config/.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | .classpath 3 | .project 4 | .settings 5 | logs 6 | .idea 7 | *.iml 8 | dist -------------------------------------------------------------------------------- /config/README.md: -------------------------------------------------------------------------------- 1 | # grain-config 2 | 3 | grain-config 配置文件加载管理工具,可以加载并管理模板类文件与json类文件。 4 | 5 | 6 | 此项目依赖 7 | 8 | grain-log 9 | commons-beanutils-1.9.3.jar 10 | commons-collections-3.2.2.jar 11 | commons-configuration-1.10.jar 12 | commons-lang-2.6.jar 13 | commons-logging-1.2.jar 14 | ezmorph-1.0.6.jar 15 | json-lib-2.4-jdk15.jar 16 | 17 | 使用 18 | 19 | 1、初始化配置文件,读取路径为./TestConfigData/,名字为config_map_test.xml的配置文件 20 | 21 | ConfigManager.init("./TestConfigData/", "config_map_test.xml", null); 22 | 23 | config_map_test.xml----配置文件格式 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | test.txt 32 | 33 | org.grain.config.TestTemplate 34 | 35 | 36 | 37 | 38 | 39 | 40 | config.json 41 | 42 | config 43 | 44 | 45 | 46 | 47 | test.txt----模板类型的格式,使用tab键隔开,前两行略过 48 | 49 | id name 50 | string string 51 | 1 dianbaer 52 | 2 电霸儿 53 | 54 | TestTemplate.java----与test.txt相对应的映射类 55 | 56 | package org.grain.config; 57 | public class TestTemplate implements ITemplate { 58 | private String id; 59 | public String name; 60 | @Override 61 | public String getId() { 62 | return id; 63 | } 64 | @Override 65 | public ITemplate initTemplate(String[] data) throws Exception { 66 | TestTemplate testTemplate = new TestTemplate(); 67 | testTemplate.id = data[0]; 68 | testTemplate.name = data[1]; 69 | return testTemplate; 70 | } 71 | } 72 | config.json-----json格式的配置文件 73 | 74 | { 75 | "test":[true,"test"] 76 | } 77 | 78 | 2、获取json格式配置文件 79 | 80 | JSONObject js = ConfigManager.getJsonData("config"); 81 | 82 | 3、获取模板类型映射表 83 | 84 | Hashtable hashTable = ConfigManager.getTemplateData(TestTemplate.class); 85 | 86 | 4、获取模板类型映射表中某个id的值 87 | 88 | TestTemplate hashTable = (TestTemplate)ConfigManager.getTemplateData(TestTemplate.class,"1"); 89 | -------------------------------------------------------------------------------- /config/build-config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /config/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | com.github.dianbaer 6 | grain 7 | 1.0.0 8 | 9 | config 10 | config 11 | config 12 | 13 | 1.8 14 | 1.8 15 | UTF-8 16 | 17 | 18 | 19 | com.github.dianbaer 20 | log 21 | 1.0.0 22 | 23 | 24 | 25 | commons-configuration 26 | commons-configuration 27 | 1.10 28 | 29 | 30 | commons-lang 31 | commons-lang 32 | 2.6 33 | 34 | 35 | commons-logging 36 | commons-logging 37 | 1.2 38 | 39 | 40 | commons-collections 41 | commons-collections 42 | 3.2.2 43 | 44 | 45 | 46 | 47 | net.sf.json-lib 48 | json-lib 49 | 2.4 50 | jdk15 51 | 52 | 53 | commons-beanutils 54 | commons-beanutils 55 | 1.9.3 56 | 57 | 58 | net.sf.ezmorph 59 | ezmorph 60 | 1.0.6 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /config/src/main/java/org/grain/config/DefaultConfig.java: -------------------------------------------------------------------------------- 1 | package org.grain.config; 2 | 3 | public class DefaultConfig { 4 | public static String UTF8 = "UTF-8"; 5 | } 6 | -------------------------------------------------------------------------------- /config/src/main/java/org/grain/config/ITemplate.java: -------------------------------------------------------------------------------- 1 | package org.grain.config; 2 | 3 | public interface ITemplate { 4 | /** 5 | * 模板类型数据id 6 | * 7 | * @return 8 | */ 9 | public String getId(); 10 | 11 | /** 12 | * 初始化模板数据函数 13 | * 14 | * @param data 15 | * 字符串数组 16 | * @return ITemplate初始化完成的模板 17 | * @throws Exception 18 | */ 19 | public ITemplate initTemplate(String[] data) throws Exception; 20 | } 21 | -------------------------------------------------------------------------------- /config/src/test/java/org/grain/config/ConfigManagerTest.java: -------------------------------------------------------------------------------- 1 | //package org.grain.config; 2 | // 3 | //import static org.junit.Assert.assertEquals; 4 | // 5 | //import java.util.Hashtable; 6 | // 7 | //import org.junit.BeforeClass; 8 | //import org.junit.Test; 9 | // 10 | //import net.sf.json.JSONObject; 11 | // 12 | //public class ConfigManagerTest { 13 | // 14 | // @BeforeClass 15 | // public static void setUpBeforeClass() throws Exception { 16 | // ConfigManager.init("./TestConfigData/", "config_map_test.xml", null); 17 | // } 18 | // 19 | // @Test 20 | // public void testGetJsonData() { 21 | // JSONObject js = ConfigManager.getJsonData("config"); 22 | // assertEquals(true, js != null); 23 | // } 24 | // 25 | // @Test 26 | // public void testGetTemplateData() { 27 | // Hashtable hashTable = ConfigManager.getTemplateData(TestTemplate.class); 28 | // assertEquals(true, hashTable != null); 29 | // } 30 | // 31 | // @Test 32 | // public void testGetTemplateDataById() { 33 | // TestTemplate hashTable = (TestTemplate)ConfigManager.getTemplateData(TestTemplate.class,"1"); 34 | // assertEquals("1", hashTable.getId()); 35 | // } 36 | // 37 | //} 38 | -------------------------------------------------------------------------------- /config/src/test/java/org/grain/config/TestTemplate.java: -------------------------------------------------------------------------------- 1 | package org.grain.config; 2 | 3 | public class TestTemplate implements ITemplate { 4 | 5 | private String id; 6 | public String name; 7 | 8 | @Override 9 | public String getId() { 10 | return id; 11 | } 12 | 13 | @Override 14 | public ITemplate initTemplate(String[] data) throws Exception { 15 | TestTemplate testTemplate = new TestTemplate(); 16 | testTemplate.id = data[0]; 17 | testTemplate.name = data[1]; 18 | return testTemplate; 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /config/src/test/resources/TestConfigData/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "test":[true,"test"] 3 | } -------------------------------------------------------------------------------- /config/src/test/resources/TestConfigData/config_map_test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | test.txt 8 | 9 | org.grain.config.TestTemplate 10 | 11 | 12 | 13 | 14 | 15 | 16 | config.json 17 | 18 | config 19 | 20 | 21 | -------------------------------------------------------------------------------- /config/src/test/resources/TestConfigData/test.txt: -------------------------------------------------------------------------------- 1 | id name 2 | string string 3 | 1 dianbaer 4 | 2 电霸儿 5 | -------------------------------------------------------------------------------- /distributedlock-clienttest/.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | .classpath 3 | .project 4 | .settings 5 | logs 6 | .idea 7 | *.iml 8 | dist -------------------------------------------------------------------------------- /distributedlock-clienttest/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | com.github.dianbaer 6 | grain 7 | 1.0.0 8 | 9 | distributedlock-clienttest 10 | distributedlock-clienttest 11 | distributedlock-clienttest 12 | 13 | 1.8 14 | 1.8 15 | UTF-8 16 | 17 | 18 | 19 | com.github.dianbaer 20 | distributedlock 21 | 1.0.0 22 | 23 | 24 | org.slf4j 25 | slf4j-log4j12 26 | 1.7.22 27 | 28 | 29 | -------------------------------------------------------------------------------- /distributedlock-clienttest/src/main/java/log/MyAppender.java: -------------------------------------------------------------------------------- 1 | package log; 2 | 3 | import org.apache.log4j.DailyRollingFileAppender; 4 | import org.apache.log4j.Priority; 5 | 6 | public class MyAppender extends DailyRollingFileAppender { 7 | @Override 8 | public boolean isAsSevereAsThreshold(Priority priority) { 9 | return this.getThreshold().equals(priority); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /distributedlock-clienttest/src/main/java/test/DistributedlockClientTest.java: -------------------------------------------------------------------------------- 1 | package test; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | import org.grain.distributedlock.DistributedLockClient; 7 | import org.grain.distributedlock.DistributedlockMsg; 8 | import org.grain.distributedlock.MinaClientService; 9 | import org.grain.msg.MsgManager; 10 | import org.grain.rpc.ThreadMinaClientHandler; 11 | import org.grain.rpc.ThreadTcpManager; 12 | import org.grain.rpc.WaitLockManager; 13 | import org.grain.tcp.MinaClient; 14 | import org.grain.tcp.TcpMsg; 15 | import org.grain.thread.AsyncThreadManager; 16 | import org.grain.threadmsg.ThreadMsgManager; 17 | import org.slf4j.LoggerFactory; 18 | 19 | public class DistributedlockClientTest { 20 | 21 | public static void main(String[] args) throws Exception { 22 | GrainLog grainLog = new GrainLog(LoggerFactory.getLogger("minaLog")); 23 | GrainLog grainLog1 = new GrainLog(LoggerFactory.getLogger("msgLog")); 24 | 25 | // 初始化线程消息 26 | AsyncThreadManager.init(100, 10, 3, 1, grainLog1); 27 | AsyncThreadManager.start(); 28 | MsgManager.init(true, grainLog1); 29 | // 设置消息归属线程,不设置则随机分配 30 | ThreadMsgManager.addMapping(TcpMsg.MINA_SERVER_CONNECTED, new int[] { 1, 1 }); 31 | ThreadMsgManager.addMapping(TcpMsg.MINA_SERVER_DISCONNECT, new int[] { 1, 1 }); 32 | ThreadMsgManager.addMapping(DistributedlockMsg.DISTRIBUTEDLOCK_SERVER_CAN_USE, new int[] { 1, 1 }); 33 | // 注册关注的消息 34 | MinaClientService minaClientService = new MinaClientService(); 35 | MsgManager.addMsgListener(minaClientService); 36 | TestMsgService testMsgService = new TestMsgService(); 37 | MsgManager.addMsgListener(testMsgService); 38 | 39 | WaitLockManager.init(120000); 40 | ThreadTcpManager.init(); 41 | // 初始化分布式锁客户端 42 | Map lockToServer = new HashMap(); 43 | lockToServer.put("user", "testserver"); 44 | lockToServer.put("group", "testserver"); 45 | DistributedLockClient.init(lockToServer, grainLog1); 46 | // 创建TCP客户端 47 | MinaClient.init(new String[] { "0.0.0.0" }, new int[] { 7005 }, new String[] { "testserver" }, ThreadMinaClientHandler.class, 10, true, grainLog); 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /distributedlock-clienttest/src/main/java/test/GrainLog.java: -------------------------------------------------------------------------------- 1 | package test; 2 | 3 | import org.grain.log.ILog; 4 | import org.slf4j.Logger; 5 | 6 | public class GrainLog implements ILog { 7 | private Logger log; 8 | 9 | public GrainLog(Logger log) { 10 | this.log = log; 11 | } 12 | 13 | @Override 14 | public void warn(String warn) { 15 | this.log.warn(warn); 16 | 17 | } 18 | 19 | @Override 20 | public void error(String error, Throwable e) { 21 | this.log.error(error, e); 22 | 23 | } 24 | 25 | @Override 26 | public void info(String info) { 27 | this.log.info(info); 28 | 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /distributedlock-clienttest/src/main/java/test/TestMsgService.java: -------------------------------------------------------------------------------- 1 | package test; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | import org.grain.distributedlock.DistributedLockClient; 7 | import org.grain.distributedlock.DistributedlockMsg; 8 | import org.grain.msg.IMsgListener; 9 | import org.grain.msg.MsgPacket; 10 | import org.grain.threadmsg.ThreadMsgManager; 11 | 12 | public class TestMsgService implements IMsgListener { 13 | 14 | @Override 15 | public Map getMsgs() throws Exception { 16 | HashMap map = new HashMap<>(); 17 | map.put(DistributedlockMsg.DISTRIBUTEDLOCK_SERVER_CAN_USE, "onDistributedlockCanUse"); 18 | map.put("DISTRIBUTEDLOCK_TEST", "onDistributedlockTest"); 19 | map.put("DISTRIBUTEDLOCK_TEST1", "onDistributedlockTest1"); 20 | return map; 21 | } 22 | 23 | public void onDistributedlockCanUse(MsgPacket msgPacket) { 24 | // 发布四条消息,分配至随机线程,不同类型互补影响,相同类型不同键值互不影响 25 | ThreadMsgManager.dispatchThreadMsg("DISTRIBUTEDLOCK_TEST", null, null); 26 | ThreadMsgManager.dispatchThreadMsg("DISTRIBUTEDLOCK_TEST", null, null); 27 | ThreadMsgManager.dispatchThreadMsg("DISTRIBUTEDLOCK_TEST1", null, null); 28 | ThreadMsgManager.dispatchThreadMsg("DISTRIBUTEDLOCK_TEST1", null, null); 29 | } 30 | 31 | public void onDistributedlockTest(MsgPacket msgPacket) { 32 | // 获取锁 33 | int lockId = DistributedLockClient.getLock("111", "user"); 34 | if (lockId == 0) { 35 | return; 36 | } 37 | /*********** 执行分布式锁业务逻辑 *********/ 38 | System.out.println("分布式锁id为:" + lockId); 39 | /*********** 执行分布式锁业务逻辑 *********/ 40 | // 释放锁 41 | DistributedLockClient.unLock("111", "user", lockId); 42 | } 43 | 44 | public void onDistributedlockTest1(MsgPacket msgPacket) { 45 | // 获取锁 46 | int lockId = DistributedLockClient.getLock("222", "user"); 47 | if (lockId == 0) { 48 | return; 49 | } 50 | /*********** 执行分布式锁业务逻辑 *********/ 51 | System.out.println("分布式锁id为:" + lockId); 52 | /*********** 执行分布式锁业务逻辑 *********/ 53 | // 释放锁 54 | DistributedLockClient.unLock("222", "user", lockId); 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /distributedlock-servertest/.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | .classpath 3 | .project 4 | .settings 5 | logs 6 | .idea 7 | *.iml 8 | dist -------------------------------------------------------------------------------- /distributedlock-servertest/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | 4 | com.github.dianbaer 5 | grain 6 | 1.0.0 7 | 8 | distributedlock-servertest 9 | distributedlock-servertest 10 | distributedlock-servertest 11 | 12 | 1.8 13 | 1.8 14 | UTF-8 15 | 16 | 17 | 18 | com.github.dianbaer 19 | distributedlock 20 | 1.0.0 21 | 22 | 23 | org.slf4j 24 | slf4j-log4j12 25 | 1.7.22 26 | 27 | 28 | -------------------------------------------------------------------------------- /distributedlock-servertest/src/main/java/log/MyAppender.java: -------------------------------------------------------------------------------- 1 | package log; 2 | 3 | import org.apache.log4j.DailyRollingFileAppender; 4 | import org.apache.log4j.Priority; 5 | 6 | public class MyAppender extends DailyRollingFileAppender { 7 | @Override 8 | public boolean isAsSevereAsThreshold(Priority priority) { 9 | return this.getThreshold().equals(priority); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /distributedlock-servertest/src/main/java/test/GrainLog.java: -------------------------------------------------------------------------------- 1 | package test; 2 | 3 | import org.grain.log.ILog; 4 | import org.slf4j.Logger; 5 | 6 | public class GrainLog implements ILog { 7 | private Logger log; 8 | 9 | public GrainLog(Logger log) { 10 | this.log = log; 11 | } 12 | 13 | @Override 14 | public void warn(String warn) { 15 | this.log.warn(warn); 16 | 17 | } 18 | 19 | @Override 20 | public void error(String error, Throwable e) { 21 | this.log.error(error, e); 22 | 23 | } 24 | 25 | @Override 26 | public void info(String info) { 27 | this.log.info(info); 28 | 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /distributedlock/.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | .classpath 3 | .project 4 | .settings 5 | logs 6 | .idea 7 | *.iml 8 | dist -------------------------------------------------------------------------------- /distributedlock/distributedlock-client.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dianbaer/grain/6dabee1f6ac4a9c845416057babdc0d059363f7f/distributedlock/distributedlock-client.png -------------------------------------------------------------------------------- /distributedlock/distributedlock-client.vsd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dianbaer/grain/6dabee1f6ac4a9c845416057babdc0d059363f7f/distributedlock/distributedlock-client.vsd -------------------------------------------------------------------------------- /distributedlock/distributedlock-server.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dianbaer/grain/6dabee1f6ac4a9c845416057babdc0d059363f7f/distributedlock/distributedlock-server.png -------------------------------------------------------------------------------- /distributedlock/distributedlock-server.vsd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dianbaer/grain/6dabee1f6ac4a9c845416057babdc0d059363f7f/distributedlock/distributedlock-server.vsd -------------------------------------------------------------------------------- /distributedlock/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4.0.0 3 | 4 | com.github.dianbaer 5 | grain 6 | 1.0.0 7 | 8 | distributedlock 9 | 10 | 1.8 11 | 1.8 12 | UTF-8 13 | 14 | 15 | 16 | com.github.dianbaer 17 | rpc 18 | 1.0.0 19 | 20 | 21 | -------------------------------------------------------------------------------- /distributedlock/protobuf/DistributedLock.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package org.grain.distributedlock.tcp; 3 | message DistributedLockC1{ 4 | string key=1;//锁唯一key 5 | string type=2;//锁类型 6 | } 7 | message DistributedLockS1{ 8 | bool result=1;//获取锁成功还是失败 9 | } 10 | message DistributedLockC2{ 11 | string name=1; 12 | } 13 | -------------------------------------------------------------------------------- /distributedlock/protobuf/protobuf编译.bat: -------------------------------------------------------------------------------- 1 | C: 2 | cd C:\Users\admin\Desktop\github\grain\trunk\grain-distributedlock\protobuf 3 | protoc --java_out=./ DistributedLock.proto 4 | -------------------------------------------------------------------------------- /distributedlock/protobuf/protoc.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dianbaer/grain/6dabee1f6ac4a9c845416057babdc0d059363f7f/distributedlock/protobuf/protoc.exe -------------------------------------------------------------------------------- /distributedlock/src/main/java/org/grain/distributedlock/DistributedLockService.java: -------------------------------------------------------------------------------- 1 | package org.grain.distributedlock; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | import org.apache.mina.core.session.IoSession; 7 | import org.grain.distributedlock.tcp.DistributedLock.DistributedLockS1; 8 | import org.grain.tcp.ITcpListener; 9 | import org.grain.tcp.TcpPacket; 10 | import org.grain.rpc.WaitLockManager; 11 | 12 | public class DistributedLockService implements ITcpListener { 13 | 14 | @Override 15 | public Map getTcps() throws Exception { 16 | HashMap map = new HashMap(); 17 | map.put(DistributedlockTCode.DISTRIBUTED_LOCK_C1, "distributedLockC1"); 18 | return map; 19 | } 20 | 21 | /** 22 | * 接受获取锁,然后阻塞等待锁客户端唤醒 23 | * 24 | * @param tcpPacket 25 | */ 26 | public void distributedLockC1(TcpPacket tcpPacket) { 27 | IoSession ioSession = (IoSession) tcpPacket.session; 28 | DistributedLockS1.Builder builder = DistributedLockS1.newBuilder(); 29 | builder.setResult(true); 30 | TcpPacket sendPacket = new TcpPacket(DistributedlockTCode.DISTRIBUTED_LOCK_S1, builder.build()); 31 | sendPacket.unlockedId = tcpPacket.lockedId; 32 | WaitLockManager.lock(ioSession, sendPacket); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /distributedlock/src/main/java/org/grain/distributedlock/DistributedlockConfig.java: -------------------------------------------------------------------------------- 1 | package org.grain.distributedlock; 2 | 3 | import org.grain.log.ILog; 4 | 5 | public class DistributedlockConfig { 6 | public static ILog log; 7 | } 8 | -------------------------------------------------------------------------------- /distributedlock/src/main/java/org/grain/distributedlock/DistributedlockMsg.java: -------------------------------------------------------------------------------- 1 | package org.grain.distributedlock; 2 | 3 | public class DistributedlockMsg { 4 | /** 5 | * 分布式锁服务器可以使用(锁客户端) 6 | */ 7 | public static String DISTRIBUTEDLOCK_SERVER_CAN_USE = "DISTRIBUTEDLOCK_SERVER_CAN_USE"; 8 | /** 9 | * 整合消息包(锁服务器) 10 | */ 11 | public static String MERGE_TCPPACKET = "MERGE_TCPPACKET"; 12 | } 13 | -------------------------------------------------------------------------------- /distributedlock/src/main/java/org/grain/distributedlock/DistributedlockServerHandler.java: -------------------------------------------------------------------------------- 1 | package org.grain.distributedlock; 2 | 3 | import org.apache.mina.core.session.IoSession; 4 | import org.grain.rpc.ThreadTcpManager; 5 | import org.grain.tcp.MinaConfig; 6 | import org.grain.tcp.MinaHandler; 7 | import org.grain.tcp.TcpMsg; 8 | import org.grain.tcp.TcpPacket; 9 | import org.grain.threadmsg.ThreadMsgManager; 10 | 11 | public class DistributedlockServerHandler extends MinaHandler { 12 | 13 | @Override 14 | public void messageReceived(IoSession session, Object message) throws Exception { 15 | super.messageReceived(session, message); 16 | if (MinaConfig.log != null) { 17 | MinaConfig.log.info("minaserver messageReceived"); 18 | } 19 | TcpPacket pt = (TcpPacket) message; 20 | // 如果是获取锁,需要汇集到一个线程 21 | if (pt.gettOpCode() == DistributedlockTCode.DISTRIBUTED_LOCK_C1) { 22 | ThreadMsgManager.dispatchThreadMsg(DistributedlockMsg.MERGE_TCPPACKET, message, null); 23 | } else { 24 | // 其他情况不需要 25 | ThreadTcpManager.dispatchTcp(pt); 26 | } 27 | 28 | } 29 | 30 | @Override 31 | public void sessionClosed(IoSession session) throws Exception { 32 | super.sessionClosed(session); 33 | if (MinaConfig.log != null) { 34 | MinaConfig.log.warn("minaserver sessionClosed"); 35 | } 36 | ThreadMsgManager.dispatchThreadMsg(TcpMsg.MINA_CLIENT_DISCONNECT, null, session); 37 | } 38 | 39 | @Override 40 | public void sessionCreated(IoSession session) throws Exception { 41 | super.sessionCreated(session); 42 | if (MinaConfig.log != null) { 43 | MinaConfig.log.info("minaserver sessionCreated"); 44 | } 45 | ThreadMsgManager.dispatchThreadMsg(TcpMsg.MINA_CLIENT_CREATE_CONNECT, null, session); 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /distributedlock/src/main/java/org/grain/distributedlock/DistributedlockTCode.java: -------------------------------------------------------------------------------- 1 | package org.grain.distributedlock; 2 | 3 | public class DistributedlockTCode { 4 | /** 5 | * 获取锁 6 | */ 7 | public static int DISTRIBUTED_LOCK_C1 = 1; 8 | /** 9 | * 返回锁 10 | */ 11 | public static int DISTRIBUTED_LOCK_S1 = 2; 12 | /** 13 | * 释放锁 14 | */ 15 | public static int DISTRIBUTED_LOCK_C2 = 3; 16 | } 17 | -------------------------------------------------------------------------------- /distributedlock/src/main/java/org/grain/distributedlock/DistributedlockTcpManager.java: -------------------------------------------------------------------------------- 1 | package org.grain.distributedlock; 2 | 3 | import org.grain.rpc.ThreadTcpManager; 4 | import org.grain.tcp.MinaConfig; 5 | import org.grain.tcp.TcpPacket; 6 | import org.grain.thread.AsyncThreadManager; 7 | import org.grain.thread.ThreadHandle; 8 | 9 | public class DistributedlockTcpManager { 10 | 11 | public static boolean dispatchTcp(TcpPacket tcpPacket) { 12 | if (tcpPacket == null) { 13 | if (MinaConfig.log != null) { 14 | MinaConfig.log.warn("派发tcp包为空"); 15 | } 16 | return false; 17 | } 18 | // 打开监控日志 19 | if (MinaConfig.USE_TCP_MONITOR) { 20 | tcpPacket.openRunMonitor(); 21 | } 22 | 23 | int[] tcpTypeArray = null; 24 | // 说明是获取锁的 25 | // 分布式锁获取线程 26 | int threadId = DistributedLockServer.getTypeKeyThreadBelong(tcpPacket); 27 | if (threadId != 0) { 28 | tcpTypeArray = new int[] { threadId, 1 }; 29 | } 30 | // 没有说明还没人要,随机一个 31 | if (tcpTypeArray == null || tcpTypeArray.length != 2) { 32 | tcpTypeArray = AsyncThreadManager.getRandomThreadPriority(); 33 | } 34 | // 没存过,存一次 35 | if (threadId == 0) { 36 | DistributedLockServer.saveTypeKeyThreadBelong(tcpPacket, tcpTypeArray[0]); 37 | } 38 | 39 | tcpPacket.putMonitor("分发至线程:" + tcpTypeArray[0] + ",优先级:" + tcpTypeArray[1]); 40 | 41 | ThreadHandle threadHandle = new ThreadHandle(tcpPacket, ThreadTcpManager.method, null); 42 | 43 | boolean result = AsyncThreadManager.addHandle(threadHandle, tcpTypeArray[0], tcpTypeArray[1]); 44 | return result; 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /distributedlock/src/main/java/org/grain/distributedlock/MergeTCPService.java: -------------------------------------------------------------------------------- 1 | package org.grain.distributedlock; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | import org.grain.msg.IMsgListener; 7 | import org.grain.msg.MsgPacket; 8 | import org.grain.tcp.TcpPacket; 9 | 10 | public class MergeTCPService implements IMsgListener { 11 | 12 | @Override 13 | public Map getMsgs() throws Exception { 14 | HashMap map = new HashMap<>(); 15 | map.put(DistributedlockMsg.MERGE_TCPPACKET, "mergeTcppacketHandle"); 16 | return map; 17 | } 18 | 19 | /** 20 | * 合并tcp消息包归到一个线程,再进行分发 21 | * 22 | * @param msgPacket 23 | */ 24 | public void mergeTcppacketHandle(MsgPacket msgPacket) { 25 | // 进行分发 26 | DistributedlockTcpManager.dispatchTcp((TcpPacket) msgPacket.getData()); 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /distributedlock/src/main/java/org/grain/distributedlock/MinaClientService.java: -------------------------------------------------------------------------------- 1 | package org.grain.distributedlock; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | import org.apache.mina.core.session.IoSession; 7 | import org.grain.msg.IMsgListener; 8 | import org.grain.msg.MsgPacket; 9 | import org.grain.tcp.TcpMsg; 10 | import org.grain.threadmsg.ThreadMsgManager; 11 | 12 | public class MinaClientService implements IMsgListener { 13 | private HashMap ioSessionServerMap = new HashMap(); 14 | 15 | @Override 16 | public Map getMsgs() throws Exception { 17 | HashMap map = new HashMap<>(); 18 | map.put(TcpMsg.MINA_SERVER_CONNECTED, "minaServerConnected"); 19 | map.put(TcpMsg.MINA_SERVER_DISCONNECT, "minaServerDisConnect"); 20 | return map; 21 | } 22 | 23 | /** 24 | * 通知叫name的锁服务器可以使用了 25 | * 26 | * @param msgPacket 27 | */ 28 | public void minaServerConnected(MsgPacket msgPacket) { 29 | IoSession ioSession = (IoSession) msgPacket.getOtherData(); 30 | String name = (String) msgPacket.getData(); 31 | ioSessionServerMap.put(name, ioSession); 32 | ThreadMsgManager.dispatchThreadMsg(DistributedlockMsg.DISTRIBUTEDLOCK_SERVER_CAN_USE, name, null); 33 | } 34 | 35 | public void minaServerDisConnect(MsgPacket msgPacket) { 36 | String name = (String) msgPacket.getData(); 37 | ioSessionServerMap.remove(name); 38 | } 39 | 40 | public IoSession getServerIoSession(String name) { 41 | return ioSessionServerMap.get(name); 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /grain-framework.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dianbaer/grain/6dabee1f6ac4a9c845416057babdc0d059363f7f/grain-framework.png -------------------------------------------------------------------------------- /grain-framework.vsd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dianbaer/grain/6dabee1f6ac4a9c845416057babdc0d059363f7f/grain-framework.vsd -------------------------------------------------------------------------------- /httpclient/.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | .classpath 3 | .project 4 | .settings 5 | logs 6 | .idea 7 | *.iml 8 | dist -------------------------------------------------------------------------------- /httpclient/README.md: -------------------------------------------------------------------------------- 1 | # grain-httpclient 2 | 3 | grain-httpclient http客户端 4 | 5 | 6 | 此项目依赖 7 | 8 | grain-log 9 | commons-codec-1.10.jar 10 | commons-logging-1.2.jar 11 | httpclient-4.5.2.jar 12 | httpcore-4.4.6.jar 13 | httpmime-4.5.2.jar 14 | 15 | 使用 16 | 17 | 1、初始化 18 | 19 | HttpUtil.init("UTF-8", null); 20 | 21 | 2、发送GET请求 22 | 23 | byte[] result = HttpUtil.send(null, "http://172.27.108.74:8080/UCenter", null, HttpUtil.GET); 24 | String str = new String(result, "UTF-8"); 25 | 26 | 3、发送POST请求 27 | 28 | String str = "{hOpCode: 20, userName: \"admin\", userPassword: \"123456\"}"; 29 | HashMap headMap = new HashMap(); 30 | headMap.put("hOpCode", "20"); 31 | headMap.put("sendType", "sendTypeJson"); 32 | headMap.put("receiveType", "receiveTypeJson"); 33 | byte[] result = HttpUtil.send(str, "http://172.27.108.74:8080/UCenter/s", headMap, HttpUtil.POST); 34 | String returnStr = new String(result, "UTF-8"); 35 | 36 | 4、发送文件 37 | 38 | String tokenId = "38bfecab619b48db8466ea7dd064f0d8"; 39 | String str = "{hOpCode: 10, userName: \"dianbaer333\", userPassword: \"123456\"}"; 40 | HashMap headMap = new HashMap(); 41 | headMap.put("hOpCode", "10"); 42 | headMap.put("sendType", "sendTypeFileSaveSession"); 43 | headMap.put("receiveType", "receiveTypeJson"); 44 | headMap.put("token", tokenId); 45 | headMap.put("packet", URLEncoder.encode(str, HttpUtil.ENCODE)); 46 | File file = new File("C:\\Users\\admin\\Desktop\\github\\grain\\trunk\\grain-httpclient\\src\\test\\resources\\k_nearest_neighbors.png"); 47 | byte[] result = HttpUtil.sendFile(file, "http://172.27.108.74:8080/UCenter/s", headMap, HttpUtil.POST); 48 | String returnStr = new String(result, "UTF-8"); 49 | 50 | -------------------------------------------------------------------------------- /httpclient/build-httpclient.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /httpclient/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | com.github.dianbaer 6 | grain 7 | 1.0.0 8 | 9 | httpclient 10 | httpclient 11 | httpclient 12 | 13 | 1.8 14 | 1.8 15 | UTF-8 16 | 17 | 18 | 19 | com.github.dianbaer 20 | log 21 | 1.0.0 22 | 23 | 24 | 25 | org.apache.httpcomponents 26 | httpmime 27 | 4.5.2 28 | 29 | 30 | org.apache.httpcomponents 31 | httpclient 32 | 4.5.2 33 | 34 | 35 | org.apache.httpcomponents 36 | httpcore 37 | 4.4.6 38 | 39 | 40 | commons-codec 41 | commons-codec 42 | 1.10 43 | 44 | 45 | commons-logging 46 | commons-logging 47 | 1.2 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /httpclient/src/main/java/org/grain/httpclient/TrustStrategyAll.java: -------------------------------------------------------------------------------- 1 | package org.grain.httpclient; 2 | 3 | import java.security.cert.CertificateException; 4 | import java.security.cert.X509Certificate; 5 | 6 | import org.apache.http.conn.ssl.TrustStrategy; 7 | 8 | public class TrustStrategyAll implements TrustStrategy { 9 | 10 | @Override 11 | public boolean isTrusted(X509Certificate[] arg0, String arg1) throws CertificateException { 12 | return true; 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /httpclient/src/test/java/org/grain/httpclient/HttpUtilTest.java: -------------------------------------------------------------------------------- 1 | //package org.grain.httpclient; 2 | // 3 | //import static org.junit.Assert.assertEquals; 4 | // 5 | //import java.io.File; 6 | //import java.io.UnsupportedEncodingException; 7 | //import java.net.URLEncoder; 8 | //import java.util.HashMap; 9 | // 10 | //import org.junit.BeforeClass; 11 | //import org.junit.Test; 12 | // 13 | //public class HttpUtilTest { 14 | // 15 | // @BeforeClass 16 | // public static void setUpBeforeClass() throws Exception { 17 | // HttpUtil.init("UTF-8", null); 18 | // } 19 | // 20 | // @Test 21 | // public void testGet() throws UnsupportedEncodingException { 22 | // byte[] result = HttpUtil.send(null, "http://localhost:8080/httpserver-test/", null, HttpUtil.GET); 23 | // String str = new String(result, "UTF-8"); 24 | // System.out.println(str); 25 | // assertEquals(true, str != null); 26 | // } 27 | // 28 | // @Test 29 | // public void testPost() throws UnsupportedEncodingException { 30 | // String str = "{hOpCode: \"1\", userName: \"admin\", userPassword: \"123456\"}"; 31 | // byte[] result = HttpUtil.send(str, "http://localhost:8080/httpserver-test/s", null, HttpUtil.POST); 32 | // String returnStr = new String(result, "UTF-8"); 33 | // System.out.println(returnStr); 34 | // assertEquals(true, str != null); 35 | // } 36 | // 37 | // @Test 38 | // public void testSendFile() throws UnsupportedEncodingException { 39 | // String tokenId = "38bfecab619b48db8466ea7dd064f0d8"; 40 | // String str = "{hOpCode: \"1\", userName: \"dianbaer333\", userPassword: \"123456\"}"; 41 | // HashMap headMap = new HashMap(); 42 | // headMap.put("token", tokenId); 43 | // headMap.put("packet", URLEncoder.encode(str, HttpUtil.ENCODE)); 44 | // File file = new File("D:\\github\\product\\grain\\httpclient\\src\\test\\resources\\k_nearest_neighbors.png"); 45 | // System.out.println(file.exists()); 46 | // byte[] result = HttpUtil.sendFile(file, "http://localhost:8080/httpserver-test/s", headMap, HttpUtil.POST); 47 | // String returnStr = new String(result, "UTF-8"); 48 | // System.out.println(returnStr); 49 | // assertEquals(true, str != null); 50 | // 51 | // } 52 | // 53 | //} 54 | -------------------------------------------------------------------------------- /httpclient/src/test/resources/k_nearest_neighbors.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dianbaer/grain/6dabee1f6ac4a9c845416057babdc0d059363f7f/httpclient/src/test/resources/k_nearest_neighbors.png -------------------------------------------------------------------------------- /httpserver-test/.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | .classpath 3 | .project 4 | .settings 5 | logs 6 | .idea 7 | *.iml 8 | dist -------------------------------------------------------------------------------- /httpserver-test/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | com.github.dianbaer 6 | grain 7 | 1.0.0 8 | 9 | httpserver-test 10 | war 11 | httpserver-test 12 | httpserver-test 13 | 14 | 1.8 15 | 1.8 16 | UTF-8 17 | 18 | 19 | 20 | com.github.dianbaer 21 | httpserver 22 | 1.0.0 23 | 24 | 25 | 26 | org.slf4j 27 | slf4j-log4j12 28 | 1.7.22 29 | 30 | 31 | javax.servlet 32 | javax.servlet-api 33 | 3.1.0 34 | 35 | 36 | -------------------------------------------------------------------------------- /httpserver-test/protobuf/UserGroupProto.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package protobuf.http; 3 | message GetTokenC{ 4 | string hOpCode=1; 5 | string userName=2; 6 | string userPassword=3; 7 | } 8 | message GetTokenS{ 9 | string hOpCode=1; 10 | string tokenId=2; 11 | string tokenExpireTime=3; 12 | } 13 | -------------------------------------------------------------------------------- /httpserver-test/protobuf/protobuf编译.bat: -------------------------------------------------------------------------------- 1 | C: 2 | cd C:\Users\admin\Desktop\github\grain\trunk\grain-httpserver-test\protobuf 3 | protoc --java_out=./ UserGroupProto.proto 4 | pause -------------------------------------------------------------------------------- /httpserver-test/protobuf/protoc.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dianbaer/grain/6dabee1f6ac4a9c845416057babdc0d059363f7f/httpserver-test/protobuf/protoc.exe -------------------------------------------------------------------------------- /httpserver-test/src/main/java/log/MyAppender.java: -------------------------------------------------------------------------------- 1 | package log; 2 | 3 | import org.apache.log4j.DailyRollingFileAppender; 4 | import org.apache.log4j.Priority; 5 | 6 | public class MyAppender extends DailyRollingFileAppender { 7 | @Override 8 | public boolean isAsSevereAsThreshold(Priority priority) { 9 | return this.getThreshold().equals(priority); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /httpserver-test/src/main/java/server/ExpandServer.java: -------------------------------------------------------------------------------- 1 | package server; 2 | 3 | import javax.servlet.http.HttpServlet; 4 | 5 | import org.grain.httpserver.HttpManager; 6 | import org.grain.httpserver.IExpandServer; 7 | 8 | import protobuf.http.UserGroupProto.GetTokenC; 9 | import protobuf.http.UserGroupProto.GetTokenS; 10 | import test.TestHttpService; 11 | 12 | public class ExpandServer implements IExpandServer { 13 | @Override 14 | public void init(HttpServlet servlet) throws Exception { 15 | HttpManager.addMapping("1", GetTokenC.class, GetTokenS.class); 16 | HttpManager.addMapping("2", GetTokenC.class, GetTokenS.class); 17 | HttpManager.addMapping("3", GetTokenC.class, GetTokenS.class); 18 | HttpManager.addMapping("4", GetTokenC.class, GetTokenS.class); 19 | HttpManager.addMapping("5", GetTokenC.class, GetTokenS.class); 20 | HttpManager.addMapping("6", GetTokenC.class, GetTokenS.class); 21 | TestHttpService testHttpService = new TestHttpService(); 22 | HttpManager.addHttpListener(testHttpService); 23 | 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /httpserver-test/src/main/java/test/GrainLog.java: -------------------------------------------------------------------------------- 1 | package test; 2 | 3 | import org.grain.log.ILog; 4 | import org.slf4j.Logger; 5 | import org.slf4j.LoggerFactory; 6 | 7 | public class GrainLog implements ILog { 8 | private Logger log; 9 | 10 | public GrainLog() { 11 | this.log = LoggerFactory.getLogger("minaLog"); 12 | } 13 | 14 | @Override 15 | public void warn(String warn) { 16 | this.log.warn(warn); 17 | 18 | } 19 | 20 | @Override 21 | public void error(String error, Throwable e) { 22 | this.log.error(error, e); 23 | 24 | } 25 | 26 | @Override 27 | public void info(String info) { 28 | this.log.info(info); 29 | 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /httpserver-test/src/main/java/test/UploadProgressListener.java: -------------------------------------------------------------------------------- 1 | package test; 2 | 3 | import org.grain.httpserver.HttpConfig; 4 | import org.grain.httpserver.IUploadProgress; 5 | 6 | public class UploadProgressListener implements IUploadProgress { 7 | public UploadProgressListener() { 8 | 9 | } 10 | 11 | @Override 12 | public void update(long arg0, long arg1, int arg2) { 13 | if (HttpConfig.log != null) { 14 | HttpConfig.log.info("arg0:" + arg0 + ",arg1:" + arg1 + ",arg2" + arg2); 15 | } 16 | } 17 | 18 | @Override 19 | public void init(String uuid) { 20 | if (HttpConfig.log != null) { 21 | HttpConfig.log.info("上传文件开始"); 22 | } 23 | } 24 | 25 | @Override 26 | public void finish() { 27 | if (HttpConfig.log != null) { 28 | HttpConfig.log.info("上传文件完成"); 29 | } 30 | } 31 | 32 | @Override 33 | public void fail() { 34 | if (HttpConfig.log != null) { 35 | HttpConfig.log.info("上传文件失败"); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /httpserver-test/src/main/webapp/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Class-Path: 3 | 4 | -------------------------------------------------------------------------------- /httpserver-test/src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | grain-httpserver-test 4 | 5 | 6 | InitHttpServer 7 | org.grain.httpserver.InitHttpServer 8 | 0 9 | 10 | 11 | 12 | InitHttpServer 13 | /s 14 | 15 | 16 | 17 | Expand 18 | server.ExpandServer 19 | 20 | 21 | 22 | ILog 23 | test.GrainLog 24 | 25 | 26 | 27 | IUploadProgress 28 | test.UploadProgressListener 29 | 30 | 31 | index.html 32 | index.htm 33 | index.jsp 34 | default.html 35 | default.htm 36 | default.jsp 37 | 38 | -------------------------------------------------------------------------------- /httpserver/.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | .classpath 3 | .project 4 | .settings 5 | logs 6 | .idea 7 | *.iml 8 | dist -------------------------------------------------------------------------------- /httpserver/build-httpserver.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /httpserver/src/main/java/org/grain/httpserver/AllowParam.java: -------------------------------------------------------------------------------- 1 | package org.grain.httpserver; 2 | 3 | public class AllowParam { 4 | // 关键字--操作码,优先级from>param>header 5 | public static String HOPCODE = "hOpCode"; 6 | // 关键字--token值,标示用户身份,优先级from>param>header 7 | public static String TOKEN = "token"; 8 | // 发送内容的类型 9 | public static String CONTENT_TYPE = "Content-Type"; 10 | // 关键字-请求的唯一标示,一般用于异步访问文件上传进度,优先级from>param>header 11 | public static String FILE_UUID = "fileUuid"; 12 | // 关键字--消息包,如果含有packet说明是完整的,其他的参数忽略,优先级from>param>header 13 | public static String PACKET = "packet"; 14 | 15 | } 16 | -------------------------------------------------------------------------------- /httpserver/src/main/java/org/grain/httpserver/CrossDomainHttpFilter.java: -------------------------------------------------------------------------------- 1 | package org.grain.httpserver; 2 | 3 | public class CrossDomainHttpFilter implements IHttpFilter { 4 | 5 | /** 6 | * 允许跨域,头消息只允许5个关键字 7 | */ 8 | @Override 9 | public boolean httpFilter(HttpPacket httpPacket) { 10 | httpPacket.hSession.response.addHeader("Access-Control-Allow-Origin", httpPacket.hSession.request.getHeader("Origin")); 11 | httpPacket.hSession.response.addHeader("Access-Control-Allow-Headers", AllowParam.HOPCODE + "," + AllowParam.TOKEN + "," + AllowParam.CONTENT_TYPE + "," + AllowParam.FILE_UUID + "," + AllowParam.PACKET); 12 | httpPacket.hSession.response.addHeader("Access-Control-Allow-Credentials", "true"); 13 | httpPacket.putMonitor("返回可跨域格式"); 14 | return true; 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /httpserver/src/main/java/org/grain/httpserver/FileData.java: -------------------------------------------------------------------------------- 1 | package org.grain.httpserver; 2 | 3 | import java.io.File; 4 | 5 | public class FileData { 6 | /** 7 | * 上传文件 8 | */ 9 | private File file; 10 | /** 11 | * 上传文件名 12 | */ 13 | private String fileName; 14 | 15 | public FileData(File file, String fileName) { 16 | this.file = file; 17 | this.fileName = fileName; 18 | } 19 | 20 | public String getFileName() { 21 | return fileName; 22 | } 23 | 24 | public void setFileName(String fileName) { 25 | this.fileName = fileName; 26 | } 27 | 28 | public File getFile() { 29 | return file; 30 | } 31 | 32 | public void setFile(File file) { 33 | this.file = file; 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /httpserver/src/main/java/org/grain/httpserver/HSession.java: -------------------------------------------------------------------------------- 1 | package org.grain.httpserver; 2 | 3 | import javax.servlet.http.HttpServletRequest; 4 | import javax.servlet.http.HttpServletResponse; 5 | 6 | public class HSession { 7 | public HttpServletRequest request; 8 | public HttpServletResponse response; 9 | // 用于存其他数据,扩展用的 10 | public Object otherData; 11 | public HeadParam headParam; 12 | 13 | public void clear() { 14 | request = null; 15 | response = null; 16 | otherData = null; 17 | headParam.clear(); 18 | headParam = null; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /httpserver/src/main/java/org/grain/httpserver/HeadParam.java: -------------------------------------------------------------------------------- 1 | package org.grain.httpserver; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | public class HeadParam { 7 | // 操作码 8 | public String hOpCode; 9 | // 身份 10 | public String token; 11 | // 请求唯一id 12 | public String fileUuid; 13 | // 消息包 14 | public String packet; 15 | // 头消息map 16 | public Map headParam = new HashMap<>(); 17 | // param与from解析出来的参数 18 | public Map parameterParam = new HashMap<>(); 19 | 20 | public HeadParam() { 21 | 22 | } 23 | 24 | public void clear() { 25 | headParam.clear(); 26 | headParam = null; 27 | parameterParam.clear(); 28 | parameterParam = null; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /httpserver/src/main/java/org/grain/httpserver/HttpConfig.java: -------------------------------------------------------------------------------- 1 | package org.grain.httpserver; 2 | 3 | import org.grain.log.ILog; 4 | 5 | public class HttpConfig { 6 | public static String ENCODE = "UTF-8"; 7 | public static String CONTENT_TYPE_JSON = "application/json"; 8 | public static String PROJECT_PATH; 9 | public static String PROJECT_NAME; 10 | public static Class UPLOAD_PROGRESS_CLASS; 11 | /** 12 | * 下载块大小,默认大小(64kb)65536经测试,超过这个值传输速度完全依赖线程睡眠时间,低于这个值会影响传输速度 13 | */ 14 | public static int DOWNLOAD_BLOCK_SIZE = 65536; 15 | /** 16 | * 下载文件睡眠间隔,小于等于0说明不睡眠 17 | */ 18 | public static int DOWNLOAD_FILE_SLEEP_TIME = 256; 19 | /** 20 | * 下载图片睡眠间隔,小于等于0说明不睡眠 21 | */ 22 | public static int DOWNLOAD_IMAGE_SLEEP_TIME = 64; 23 | public static ILog log; 24 | } 25 | -------------------------------------------------------------------------------- /httpserver/src/main/java/org/grain/httpserver/HttpException.java: -------------------------------------------------------------------------------- 1 | package org.grain.httpserver; 2 | 3 | import com.google.protobuf.Message; 4 | 5 | public final class HttpException extends Exception { 6 | 7 | private static final long serialVersionUID = 1L; 8 | 9 | private String errorType; 10 | private Message errorData; 11 | 12 | public Message getErrorData() { 13 | return errorData; 14 | } 15 | 16 | public void setErrorData(Message errorData) { 17 | this.errorData = errorData; 18 | } 19 | 20 | public String getErrorType() { 21 | return errorType; 22 | } 23 | 24 | public void setErrorType(String errorType) { 25 | this.errorType = errorType; 26 | } 27 | 28 | public HttpException(String errorType, Message errorData) { 29 | this.errorType = errorType; 30 | this.errorData = errorData; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /httpserver/src/main/java/org/grain/httpserver/HttpPacket.java: -------------------------------------------------------------------------------- 1 | package org.grain.httpserver; 2 | 3 | import java.util.List; 4 | 5 | import org.grain.log.RunMonitor; 6 | 7 | import com.google.protobuf.Message; 8 | 9 | public class HttpPacket { 10 | private String hOpCode; 11 | private Message data; 12 | public RunMonitor runMonitor; 13 | public List fileList; 14 | public HSession hSession; 15 | public boolean isFromAnalysis = false; 16 | 17 | public HttpPacket() { 18 | 19 | } 20 | 21 | public HttpPacket(String hOpCode, Message data) { 22 | this.hOpCode = hOpCode; 23 | this.data = data; 24 | } 25 | 26 | public void putMonitor(String content) { 27 | if (runMonitor != null) { 28 | runMonitor.putMonitor(content); 29 | } 30 | } 31 | 32 | public void openRunMonitor() { 33 | if (runMonitor == null) { 34 | runMonitor = new RunMonitor("HTTP", this.hOpCode); 35 | } 36 | } 37 | 38 | public String gethOpCode() { 39 | return hOpCode; 40 | } 41 | 42 | public void sethOpCode(String hOpCode) { 43 | this.hOpCode = hOpCode; 44 | } 45 | 46 | public Message getData() { 47 | return data; 48 | } 49 | 50 | public void setData(Message data) { 51 | this.data = data; 52 | } 53 | 54 | public void clear() { 55 | data = null; 56 | runMonitor = null; 57 | if (fileList != null) { 58 | for (int i = 0; i < fileList.size(); i++) { 59 | FileData fileData = fileList.get(i); 60 | fileData.getFile().delete(); 61 | } 62 | fileList = null; 63 | } 64 | hSession.clear(); 65 | hSession = null; 66 | } 67 | 68 | public byte[] getByteData() { 69 | return this.data.toByteArray(); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /httpserver/src/main/java/org/grain/httpserver/IExpandServer.java: -------------------------------------------------------------------------------- 1 | package org.grain.httpserver; 2 | 3 | import javax.servlet.http.HttpServlet; 4 | 5 | public interface IExpandServer { 6 | public void init(HttpServlet servlet) throws Exception; 7 | } 8 | -------------------------------------------------------------------------------- /httpserver/src/main/java/org/grain/httpserver/IHttpFilter.java: -------------------------------------------------------------------------------- 1 | package org.grain.httpserver; 2 | 3 | public interface IHttpFilter { 4 | /** 5 | * 实现此接口,可以进行http预处理进行请求过滤 6 | * 7 | * @param httpPacket 8 | * @return 9 | */ 10 | public boolean httpFilter(HttpPacket httpPacket) throws HttpException; 11 | } 12 | -------------------------------------------------------------------------------- /httpserver/src/main/java/org/grain/httpserver/IHttpListener.java: -------------------------------------------------------------------------------- 1 | package org.grain.httpserver; 2 | 3 | import java.util.Map; 4 | 5 | public interface IHttpListener { 6 | /** 7 | * 实现此接口可以注册http对应消息处理函数 8 | * 9 | * @return 10 | */ 11 | public Map getHttps(); 12 | } 13 | -------------------------------------------------------------------------------- /httpserver/src/main/java/org/grain/httpserver/IUploadProgress.java: -------------------------------------------------------------------------------- 1 | package org.grain.httpserver; 2 | 3 | import org.apache.commons.fileupload.ProgressListener; 4 | 5 | public interface IUploadProgress extends ProgressListener { 6 | public void init(String uuid); 7 | 8 | public void finish(); 9 | 10 | public void fail(); 11 | } 12 | -------------------------------------------------------------------------------- /httpserver/src/main/java/org/grain/httpserver/PacketUtils.java: -------------------------------------------------------------------------------- 1 | package org.grain.httpserver; 2 | 3 | import java.io.IOException; 4 | import java.io.InputStream; 5 | 6 | import com.google.protobuf.Message; 7 | import com.google.protobuf.Message.Builder; 8 | import com.googlecode.protobuf.format.JsonFormat; 9 | import com.googlecode.protobuf.format.util.TextUtils; 10 | 11 | public class PacketUtils { 12 | public static JsonFormat jsonFormat = new JsonFormat(); 13 | 14 | public static Message jsonToProtoBuf(String jsonStr, Builder builder) { 15 | InputStream inputStream = null; 16 | try { 17 | inputStream = TextUtils.toInputStream(jsonStr); 18 | jsonFormat.merge(inputStream, builder); 19 | Message message = builder.build(); 20 | return message; 21 | } catch (Exception e) { 22 | if (HttpConfig.log != null) { 23 | HttpConfig.log.error("json转换成protobuf,异常", e); 24 | } 25 | return null; 26 | } finally { 27 | if (inputStream != null) { 28 | try { 29 | inputStream.close(); 30 | } catch (IOException e) { 31 | if (HttpConfig.log != null) { 32 | HttpConfig.log.error("json转换成protobuf,关闭输入流失败", e); 33 | } 34 | } 35 | } 36 | } 37 | } 38 | 39 | public static String protoBufToJson(Message message) { 40 | return jsonFormat.printToString(message); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /httpserver/src/main/java/org/grain/httpserver/ReadUtils.java: -------------------------------------------------------------------------------- 1 | package org.grain.httpserver; 2 | 3 | import java.io.IOException; 4 | import java.io.InputStream; 5 | import java.net.SocketTimeoutException; 6 | 7 | import javax.servlet.http.HttpServletRequest; 8 | 9 | public class ReadUtils { 10 | 11 | public static byte[] read(HttpServletRequest request) { 12 | InputStream inputStream = null; 13 | try { 14 | if (request.getContentLength() <= 0) { 15 | if (HttpConfig.log != null) { 16 | HttpConfig.log.warn("http请求内容为空"); 17 | } 18 | return null; 19 | } 20 | inputStream = request.getInputStream(); 21 | byte[] buffer = new byte[request.getContentLength()]; 22 | int size = inputStream.read(buffer); 23 | while (buffer.length != request.getContentLength() && size > -1) { 24 | size = inputStream.read(buffer, buffer.length, request.getContentLength() - buffer.length); 25 | } 26 | return buffer; 27 | } catch (SocketTimeoutException e) { 28 | if (HttpConfig.log != null) { 29 | HttpConfig.log.error("读取http输入流异常", e); 30 | } 31 | return null; 32 | } catch (Exception e) { 33 | if (HttpConfig.log != null) { 34 | HttpConfig.log.error("读取http输入流异常", e); 35 | } 36 | return null; 37 | } finally { 38 | if (inputStream != null) { 39 | try { 40 | inputStream.close(); 41 | } catch (IOException e) { 42 | if (HttpConfig.log != null) { 43 | HttpConfig.log.error("关闭http输入流异常", e); 44 | } 45 | } 46 | } 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /httpserver/src/main/java/org/grain/httpserver/ReplyFile.java: -------------------------------------------------------------------------------- 1 | package org.grain.httpserver; 2 | 3 | import java.io.File; 4 | 5 | public class ReplyFile { 6 | private String fileName; 7 | private File file; 8 | 9 | public ReplyFile(File file, String fileName) { 10 | this.file = file; 11 | this.fileName = fileName; 12 | } 13 | 14 | public String getFileName() { 15 | return fileName; 16 | } 17 | 18 | public void setFileName(String fileName) { 19 | this.fileName = fileName; 20 | } 21 | 22 | public File getFile() { 23 | return file; 24 | } 25 | 26 | public void setFile(File file) { 27 | this.file = file; 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /httpserver/src/main/java/org/grain/httpserver/ReplyImage.java: -------------------------------------------------------------------------------- 1 | package org.grain.httpserver; 2 | 3 | import java.io.File; 4 | 5 | public class ReplyImage { 6 | private File file; 7 | private String contentType = "image/jpeg"; 8 | 9 | public ReplyImage(File file) { 10 | this.file = file; 11 | } 12 | 13 | public File getFile() { 14 | return file; 15 | } 16 | 17 | public void setFile(File file) { 18 | this.file = file; 19 | } 20 | 21 | public String getContentType() { 22 | return contentType; 23 | } 24 | 25 | public void setContentType(String contentType) { 26 | this.contentType = contentType; 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /httpserver/src/main/java/org/grain/httpserver/ReplyString.java: -------------------------------------------------------------------------------- 1 | package org.grain.httpserver; 2 | 3 | public class ReplyString { 4 | private String str; 5 | private String contentType; 6 | public ReplyString(String str,String contentType) { 7 | this.str = str; 8 | this.contentType = contentType; 9 | } 10 | public String getStr() { 11 | return str; 12 | } 13 | public void setStr(String str) { 14 | this.str = str; 15 | } 16 | public String getContentType() { 17 | return contentType; 18 | } 19 | public void setContentType(String contentType) { 20 | this.contentType = contentType; 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /httpserver/src/main/java/org/grain/httpserver/URLUtil.java: -------------------------------------------------------------------------------- 1 | package org.grain.httpserver; 2 | 3 | import java.io.UnsupportedEncodingException; 4 | import java.net.URLEncoder; 5 | 6 | public class URLUtil { 7 | 8 | public static String getRequestUrl(HttpPacket httpPacket, String url, String token) { 9 | String packet; 10 | try { 11 | packet = URLEncoder.encode(CodeUtils.encodeJson(httpPacket), HttpConfig.ENCODE); 12 | } catch (UnsupportedEncodingException e) { 13 | HttpConfig.log.error("encode pakcet异常", e); 14 | return null; 15 | } 16 | return url + "?" + AllowParam.HOPCODE + "=" + httpPacket.gethOpCode() + "&" + AllowParam.TOKEN + "=" + token + "&" + AllowParam.PACKET + "=" + packet; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /log/.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | .classpath 3 | .project 4 | .settings 5 | logs 6 | .idea 7 | *.iml 8 | dist -------------------------------------------------------------------------------- /log/README.md: -------------------------------------------------------------------------------- 1 | # grain-log 2 | 3 | ## grain-log 日志接口,所有组件想打印日志必须关联这个库 4 | 5 | 6 | 此项目依赖 7 | 8 | 无 9 | 10 | 使用 11 | 12 | 1、实现Ilog接口 13 | 14 | GrainLog-----------实现ILog接口,把可以打印日志的类的对象传递进来,例如org.slf4j.Logger 15 | 16 | package test; 17 | import org.grain.log.ILog; 18 | import org.slf4j.Logger; 19 | public class GrainLog implements ILog { 20 | private Logger log; 21 | public GrainLog(Logger log) { 22 | this.log = log; 23 | } 24 | @Override 25 | public void warn(String warn) { 26 | this.log.warn(warn); 27 | } 28 | @Override 29 | public void error(String error, Throwable e) { 30 | this.log.error(error, e); 31 | } 32 | @Override 33 | public void info(String info) { 34 | this.log.info(info); 35 | } 36 | } 37 | 38 | 39 | 2、将实现ILog接口的实例传递给依赖此接口的组件。例如:grain-msg项目 40 | 41 | GrainLog grainLog1 = new GrainLog(LoggerFactory.getLogger("msgLog")); 42 | // 初始化消息 43 | MsgManager.init(true, grainLog1); 44 | -------------------------------------------------------------------------------- /log/build-log.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /log/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | com.github.dianbaer 6 | grain 7 | 1.0.0 8 | 9 | log 10 | log 11 | log 12 | 13 | 1.8 14 | 1.8 15 | UTF-8 16 | 17 | -------------------------------------------------------------------------------- /log/src/main/java/org/grain/log/ILog.java: -------------------------------------------------------------------------------- 1 | package org.grain.log; 2 | 3 | public interface ILog { 4 | /** 5 | * 警告,用于未抛异常,但是业务错误 6 | * 7 | * @param warn 8 | * 警告字符串 9 | */ 10 | public void warn(String warn); 11 | 12 | /** 13 | * 抛异常 14 | * 15 | * @param error 16 | * 错误字符串 17 | * @param e 18 | * 错误的异常信息 19 | */ 20 | public void error(String error, Throwable e); 21 | 22 | /** 23 | * 普通日志 24 | * 25 | * @param info 26 | * 普通日志字符串 27 | */ 28 | public void info(String info); 29 | } 30 | -------------------------------------------------------------------------------- /log/src/test/java/org/grain/log/LogObjTest.java: -------------------------------------------------------------------------------- 1 | package org.grain.log; 2 | 3 | public class LogObjTest implements ILog { 4 | 5 | @Override 6 | public void warn(String warn) { 7 | // TODO Auto-generated method stub 8 | 9 | } 10 | 11 | @Override 12 | public void error(String error, Throwable e) { 13 | // TODO Auto-generated method stub 14 | 15 | } 16 | 17 | @Override 18 | public void info(String info) { 19 | // TODO Auto-generated method stub 20 | 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /log/src/test/java/org/grain/log/LogTest.java: -------------------------------------------------------------------------------- 1 | package org.grain.log; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | 5 | import org.junit.BeforeClass; 6 | import org.junit.Test; 7 | 8 | public class LogTest { 9 | 10 | @BeforeClass 11 | public static void setUpBeforeClass() throws Exception { 12 | } 13 | 14 | @Test 15 | public void test() { 16 | LogObjTest logObjTest = new LogObjTest(); 17 | logObjTest.error(null, null); 18 | logObjTest.info(null); 19 | logObjTest.warn(null); 20 | assertEquals(true, true); 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /log/src/test/java/org/grain/log/RunMonitorTest.java: -------------------------------------------------------------------------------- 1 | package org.grain.log; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | 5 | import org.junit.AfterClass; 6 | import org.junit.BeforeClass; 7 | import org.junit.Test; 8 | 9 | public class RunMonitorTest { 10 | private static RunMonitor runMonitor; 11 | 12 | @BeforeClass 13 | public static void setUpBeforeClass() throws Exception { 14 | runMonitor = new RunMonitor("TCP", "connect"); 15 | } 16 | 17 | @AfterClass 18 | public static void tearDownAfterClass() throws Exception { 19 | String str = runMonitor.toString(); 20 | System.out.println(str); 21 | str = runMonitor.toString("disconnect"); 22 | System.out.println(str); 23 | assertEquals(true, str != null); 24 | } 25 | 26 | @Test 27 | public void testPutMonitor() { 28 | runMonitor.putMonitor("链接"); 29 | runMonitor.putMonitor("发送"); 30 | runMonitor.putMonitor("断开"); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /mariadb/.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | .classpath 3 | .project 4 | .settings 5 | logs 6 | .idea 7 | *.iml 8 | dist -------------------------------------------------------------------------------- /mariadb/README.md: -------------------------------------------------------------------------------- 1 | # grain-mariadb 2 | 3 | grain-mariadb mariadb工具类,快速操作mariadb 4 | 5 | 6 | 此项目依赖 7 | 8 | grain-log 9 | mariadb-java-client-1.5.7.jar 10 | mybatis-3.4.2.jar 11 | mybatis-generator-core-1.3.5.jar 12 | mariadb数据库 13 | 14 | 使用 15 | 16 | 17 | 1、创建数据库 18 | 19 | src/test/resources/TestConfigData/mariadbtest.sql 20 | 21 | 2、生成映射文件,修改PaginationPlugin.java与generatorConfig.xml并执行PaginationPlugin.java文件main函数 22 | 23 | src/test/java/org/grain/mariadb/PaginationPlugin.java 24 | src/test/resources/TestConfigData/generatorConfig.xml 25 | 26 | 生成文件示例 27 | 28 | org.grain.mariadb.dao.base-----接口 29 | org.grain.mariadb.mappers.base----xml 30 | org.grain.mariadb.model.base----实体类 31 | 32 | 3、修改mybatis-config.xml文件 33 | 34 | src/test/resources/TestConfigData/mybatis-config.xml 35 | 36 | 4、启动程序 37 | 38 | MybatisManager.init("C:\\Users\\admin\\Desktop\\github\\grain\\trunk\\grain-mariadb\\src\\test\\resources\\TestConfigData\\", "mybatis-config.xml", null); 39 | 40 | 5、操作数据库 41 | 42 | Testtable testtable = new Testtable(); 43 | testtable.setId(UUID.randomUUID().toString()); 44 | testtable.setName("test"); 45 | testtable.setTime(new Date()); 46 | SqlSession sqlSession = null; 47 | int result = 0; 48 | try { 49 | sqlSession = MybatisManager.getSqlSession(); 50 | TesttableMapper testtableMapper = sqlSession.getMapper(TesttableMapper.class); 51 | result = testtableMapper.insert(testtable); 52 | if (result == 0) { 53 | throw new Exception(); 54 | } 55 | sqlSession.commit(); 56 | } catch (Exception e) { 57 | if (sqlSession != null) { 58 | sqlSession.rollback(); 59 | } 60 | } finally { 61 | if (sqlSession != null) { 62 | sqlSession.close(); 63 | } 64 | } 65 | 66 | 67 | -------------------------------------------------------------------------------- /mariadb/build-mariadb.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /mariadb/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | com.github.dianbaer 6 | grain 7 | 1.0.0 8 | 9 | mariadb 10 | mariadb 11 | mariadb 12 | 13 | 1.8 14 | 1.8 15 | UTF-8 16 | 17 | 18 | 19 | com.github.dianbaer 20 | log 21 | 1.0.0 22 | 23 | 24 | 25 | org.mariadb.jdbc 26 | mariadb-java-client 27 | 1.5.7 28 | 29 | 30 | org.mybatis 31 | mybatis 32 | 3.4.2 33 | 34 | 35 | org.mybatis.generator 36 | mybatis-generator-core 37 | 1.3.5 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /mariadb/src/main/java/org/grain/mariadb/MybatisManager.java: -------------------------------------------------------------------------------- 1 | package org.grain.mariadb; 2 | 3 | import java.io.FileInputStream; 4 | import java.io.InputStream; 5 | 6 | import org.apache.ibatis.session.SqlSession; 7 | import org.apache.ibatis.session.SqlSessionFactory; 8 | import org.apache.ibatis.session.SqlSessionFactoryBuilder; 9 | import org.grain.log.ILog; 10 | 11 | public class MybatisManager { 12 | private static SqlSessionFactory sqlSessionFactory; 13 | public static ILog log; 14 | 15 | /** 16 | * 初始化链接mariadb 17 | * 18 | * @param configDir 19 | * 地址 20 | * @param configName 21 | * 配置文件名 22 | * @param log 23 | * 日志可为null 24 | * @throws Exception 25 | */ 26 | public static void init(String configDir, String configName, ILog log) throws Exception { 27 | if (configDir == null || configDir.equals("")) { 28 | throw new Exception("配置文件信息为空"); 29 | } 30 | MybatisManager.log = log; 31 | if (!configDir.endsWith("/") && !configDir.endsWith("\\")) { 32 | configDir += "/"; 33 | } 34 | String xmlPath = configDir + configName; 35 | InputStream inputStream = new FileInputStream(xmlPath); 36 | SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder(); 37 | sqlSessionFactory = builder.build(inputStream); 38 | } 39 | 40 | /** 41 | * 获取session 42 | * 43 | * @return 44 | */ 45 | public static SqlSession getSqlSession() { 46 | return sqlSessionFactory.openSession(); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /mariadb/src/test/java/org/grain/mariadb/MybatisManagerTest.java: -------------------------------------------------------------------------------- 1 | //package org.grain.mariadb; 2 | // 3 | //import static org.junit.Assert.assertEquals; 4 | // 5 | //import java.util.Date; 6 | //import java.util.UUID; 7 | // 8 | //import org.apache.ibatis.session.SqlSession; 9 | //import org.grain.mariadb.dao.base.TesttableMapper; 10 | //import org.grain.mariadb.model.base.Testtable; 11 | //import org.junit.BeforeClass; 12 | //import org.junit.Test; 13 | // 14 | //public class MybatisManagerTest { 15 | // 16 | // @BeforeClass 17 | // public static void setUpBeforeClass() throws Exception { 18 | // MybatisManager.init("D:\\github\\product\\grain\\mariadb\\src\\test\\resources\\TestConfigData\\", "mybatis-config.xml", null); 19 | // } 20 | // 21 | // @Test 22 | // public void test() { 23 | // Testtable testtable = new Testtable(); 24 | // testtable.setId(UUID.randomUUID().toString()); 25 | // testtable.setName("test"); 26 | // testtable.setTime(new Date()); 27 | // SqlSession sqlSession = null; 28 | // int result = 0; 29 | // try { 30 | // sqlSession = MybatisManager.getSqlSession(); 31 | // TesttableMapper testtableMapper = sqlSession.getMapper(TesttableMapper.class); 32 | // result = testtableMapper.insert(testtable); 33 | // if (result == 0) { 34 | // throw new Exception(); 35 | // } 36 | // sqlSession.commit(); 37 | // } catch (Exception e) { 38 | // if (sqlSession != null) { 39 | // sqlSession.rollback(); 40 | // } 41 | // } finally { 42 | // if (sqlSession != null) { 43 | // sqlSession.close(); 44 | // } 45 | // } 46 | // assertEquals(1, result); 47 | // } 48 | // 49 | //} 50 | -------------------------------------------------------------------------------- /mariadb/src/test/resources/TestConfigData/mariadbtest.sql: -------------------------------------------------------------------------------- 1 | /* 2 | Navicat MySQL Data Transfer 3 | 4 | Source Server : localhost_3307 5 | Source Server Version : 50505 6 | Source Host : localhost:3307 7 | Source Database : mariadbtest 8 | 9 | Target Server Type : MYSQL 10 | Target Server Version : 50505 11 | File Encoding : 65001 12 | 13 | Date: 2017-09-29 14:33:00 14 | */ 15 | 16 | SET FOREIGN_KEY_CHECKS=0; 17 | 18 | -- ---------------------------- 19 | -- Table structure for testtable 20 | -- ---------------------------- 21 | DROP TABLE IF EXISTS `testtable`; 22 | CREATE TABLE `testtable` ( 23 | `id` varchar(64) NOT NULL, 24 | `name` varchar(255) NOT NULL, 25 | `time` datetime NOT NULL, 26 | PRIMARY KEY (`id`) 27 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 28 | -------------------------------------------------------------------------------- /mongodb/.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | .classpath 3 | .project 4 | .settings 5 | logs 6 | .idea 7 | *.iml 8 | dist -------------------------------------------------------------------------------- /mongodb/README.md: -------------------------------------------------------------------------------- 1 | # grain-mongodb 2 | 3 | grain-mongodb mongodb工具类,快速操作mongodb 4 | 5 | 6 | 此项目依赖 7 | 8 | grain-log 9 | gson-2.8.0.jar 10 | mongo-java-driver-3.4.2.jar 11 | mongodb数据库 12 | 13 | 使用 14 | 15 | 1、创建数据库 16 | 17 | mongo --host 172.27.108.73 --eval 'db = db.getSiblingDB("test");db.createUser({user: "test",pwd: "test",roles: [ "readWrite", "dbAdmin" ]})' 18 | 19 | 20 | 2、链接mongodb某数据库 21 | 22 | MongodbManager.init("172.27.108.73", 27017, "test", "test", "test", null); 23 | 24 | 3、创建表 25 | 26 | boolean result = MongodbManager.createCollection("test_table"); 27 | 28 | 4、插入数据 29 | 30 | TestMongo---------数据类型都需要继承MongoObj对象,为了方便删除和修改 31 | 32 | package org.grain.mongo; 33 | public class TestMongo extends MongoObj { 34 | private String id; 35 | private String name; 36 | public TestMongo(String id, String name) { 37 | this.id = id; 38 | this.name = name; 39 | } 40 | public String getId() { 41 | return id; 42 | } 43 | public void setId(String id) { 44 | this.id = id; 45 | } 46 | public String getName() { 47 | return name; 48 | } 49 | public void setName(String name) { 50 | this.name = name; 51 | } 52 | } 53 | 54 | TestMongo testMongo = new TestMongo(UUID.randomUUID().toString(), "name"); 55 | boolean result = MongodbManager.insertOne("test_table", testMongo); 56 | 57 | 5、插入列表 58 | 59 | TestMongo testMongo = new TestMongo(UUID.randomUUID().toString(), "name"); 60 | TestMongo testMongo1 = new TestMongo(UUID.randomUUID().toString(), "name1"); 61 | List list = new ArrayList<>(); 62 | list.add(testMongo); 63 | list.add(testMongo1); 64 | boolean result = MongodbManager.insertMany("test_table", list); 65 | 66 | 6、查询列表 67 | 68 | Bson filter = Filters.and(Filters.eq("id", "222")); 69 | List list = MongodbManager.find("test_table", filter, TestMongo.class, 0, 0); 70 | 71 | 7、删除数据 72 | 73 | boolean result = MongodbManager.deleteById("test_table", testMongo); 74 | 75 | 8、修改数据 76 | 77 | boolean result = MongodbManager.updateById("test_table", testMongo); 78 | 79 | 9、获取个数 80 | 81 | long count = MongodbManager.count("test_table", null); -------------------------------------------------------------------------------- /mongodb/build-mongodb.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /mongodb/createdb.txt: -------------------------------------------------------------------------------- 1 | mongo --host 127.0.0.1 --eval 'db = db.getSiblingDB("test");db.createUser({user: "test",pwd: "test",roles: [ "readWrite", "dbAdmin" ]})' 2 | -------------------------------------------------------------------------------- /mongodb/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | com.github.dianbaer 6 | grain 7 | 1.0.0 8 | 9 | mongodb 10 | mongodb 11 | mongodb 12 | 13 | 1.8 14 | 1.8 15 | UTF-8 16 | 17 | 18 | 19 | com.github.dianbaer 20 | log 21 | 1.0.0 22 | 23 | 24 | org.mongodb 25 | mongo-java-driver 26 | 3.4.2 27 | 28 | 29 | com.google.code.gson 30 | gson 31 | 2.8.0 32 | 33 | 34 | -------------------------------------------------------------------------------- /mongodb/src/main/java/org/grain/mongo/MongoConfig.java: -------------------------------------------------------------------------------- 1 | package org.grain.mongo; 2 | 3 | public class MongoConfig { 4 | public static String MONGO_ID = "_id"; 5 | public static String $SET = "$set"; 6 | } 7 | -------------------------------------------------------------------------------- /mongodb/src/main/java/org/grain/mongo/MongoObj.java: -------------------------------------------------------------------------------- 1 | package org.grain.mongo; 2 | 3 | import org.bson.Document; 4 | 5 | /** 6 | * 所有mongodb实体类需要继承的对象,需要保存Document才可以进行删除与修改操作 7 | * 8 | */ 9 | public class MongoObj { 10 | private Document document; 11 | 12 | public Document getDocument() { 13 | return document; 14 | } 15 | 16 | public void setDocument(Document document) { 17 | this.document = document; 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /mongodb/src/test/java/org/grain/mongo/TestMongo.java: -------------------------------------------------------------------------------- 1 | package org.grain.mongo; 2 | 3 | public class TestMongo extends MongoObj { 4 | private String id; 5 | private String name; 6 | 7 | public TestMongo(String id, String name) { 8 | this.id = id; 9 | this.name = name; 10 | } 11 | 12 | public String getId() { 13 | return id; 14 | } 15 | 16 | public void setId(String id) { 17 | this.id = id; 18 | } 19 | 20 | public String getName() { 21 | return name; 22 | } 23 | 24 | public void setName(String name) { 25 | this.name = name; 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /msg/.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | .classpath 3 | .project 4 | .settings 5 | logs 6 | .idea 7 | *.iml 8 | dist -------------------------------------------------------------------------------- /msg/README.md: -------------------------------------------------------------------------------- 1 | # grain-msg 2 | 3 | ## grain-msg 通用消息管理工具,可以进行消息注册,消息分发,消息回调 4 | 5 | 6 | 此项目依赖 7 | 8 | grain-log 9 | 10 | 使用 11 | 12 | 1、初始化消息管理器,设定打印日志参数 13 | 14 | MsgManager.init(true, null); 15 | 16 | 2、将实现IMsgListener接口的类的实例注册到消息管理器 17 | 18 | TestMsgListener---实现IMsgListener接口的类 19 | 20 | package org.grain.msg; 21 | import java.util.HashMap; 22 | import java.util.Map; 23 | public class TestMsgListener implements IMsgListener { 24 | @Override 25 | public Map getMsgs() throws Exception { 26 | HashMap map = new HashMap<>(); 27 | map.put("createuser", "createUserHandle"); 28 | return map; 29 | } 30 | public void createUserHandle(MsgPacket msgPacket) { 31 | System.out.println("接到消息:" + msgPacket.getMsgOpCode()); 32 | } 33 | } 34 | 35 | 36 | 进行注册 37 | 38 | TestMsgListener testMsgListener = new TestMsgListener(); 39 | boolean result = MsgManager.addMsgListener(testMsgListener); 40 | 41 | 3、通过发布消息,已经注册好监听消息的函数会接到回调 42 | 43 | MsgManager.dispatchMsg("createuser", 111, 222); 44 | 45 | -------------------------------------------------------------------------------- /msg/build-msg.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /msg/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | com.github.dianbaer 6 | grain 7 | 1.0.0 8 | 9 | msg 10 | msg 11 | msg 12 | 13 | 1.8 14 | 1.8 15 | UTF-8 16 | 17 | 18 | 19 | com.github.dianbaer 20 | log 21 | 1.0.0 22 | 23 | 24 | -------------------------------------------------------------------------------- /msg/src/main/java/org/grain/msg/IMsgListener.java: -------------------------------------------------------------------------------- 1 | package org.grain.msg; 2 | 3 | import java.util.Map; 4 | 5 | public interface IMsgListener { 6 | /** 7 | * 实现此接口可以关注消息,消息分发器会回调消息处理函数 8 | * 9 | * @return Map 消息类型,消息处理函数 10 | * @throws Exception 11 | */ 12 | public Map getMsgs() throws Exception; 13 | } 14 | -------------------------------------------------------------------------------- /msg/src/main/java/org/grain/msg/MsgPacket.java: -------------------------------------------------------------------------------- 1 | package org.grain.msg; 2 | 3 | import org.grain.log.RunMonitor; 4 | 5 | public class MsgPacket { 6 | private String msgOpCode; 7 | private Object data; 8 | private Object otherData; 9 | public RunMonitor runMonitor; 10 | 11 | /** 12 | * 初始化 13 | * 14 | * @param msgOpCode 15 | * 消息操作码 16 | * @param data 17 | * 消息数据 可以为null,一般为字符类,可以序列化 18 | * @param otherData 19 | * 其他数据 可以为null,一般为不能序列化的 20 | * @param useMsgMonitor 21 | * 是否初始化监控 22 | */ 23 | public MsgPacket(String msgOpCode, Object data, Object otherData, boolean useMsgMonitor) { 24 | this.msgOpCode = msgOpCode; 25 | this.data = data; 26 | this.otherData = otherData; 27 | if (useMsgMonitor) { 28 | runMonitor = new RunMonitor("Msg", msgOpCode); 29 | putMonitor("生成Msg消息包"); 30 | } 31 | } 32 | 33 | /** 34 | * 添加监控内容 35 | * 36 | * @param content 37 | * 内容 38 | */ 39 | public void putMonitor(String content) { 40 | if (runMonitor != null) { 41 | runMonitor.putMonitor(content); 42 | } 43 | } 44 | 45 | /** 46 | * 清理 47 | */ 48 | public void clear() { 49 | data = null; 50 | otherData = null; 51 | runMonitor = null; 52 | } 53 | 54 | /** 55 | * 获取操作码 56 | * 57 | * @return 58 | */ 59 | public String getMsgOpCode() { 60 | return msgOpCode; 61 | } 62 | 63 | /** 64 | * 设置操作码 65 | * 66 | * @param msgOpCode 67 | */ 68 | public void setMsgOpCode(String msgOpCode) { 69 | this.msgOpCode = msgOpCode; 70 | } 71 | 72 | /** 73 | * 获取数据 74 | * 75 | * @return 76 | */ 77 | public Object getData() { 78 | return data; 79 | } 80 | 81 | /** 82 | * 设置数据 83 | * 84 | * @param data 85 | */ 86 | public void setData(Object data) { 87 | this.data = data; 88 | } 89 | 90 | /** 91 | * 获取其他数据 92 | * 93 | * @return 94 | */ 95 | public Object getOtherData() { 96 | return otherData; 97 | } 98 | 99 | /** 100 | * 设置其他数据 101 | * 102 | * @param otherData 103 | */ 104 | public void setOtherData(Object otherData) { 105 | this.otherData = otherData; 106 | } 107 | 108 | } 109 | -------------------------------------------------------------------------------- /msg/src/test/java/org/grain/msg/MsgManagerTest.java: -------------------------------------------------------------------------------- 1 | package org.grain.msg; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | 5 | import org.junit.BeforeClass; 6 | import org.junit.Test; 7 | 8 | public class MsgManagerTest { 9 | 10 | @BeforeClass 11 | public static void setUpBeforeClass() throws Exception { 12 | MsgManager.init(true, null); 13 | } 14 | 15 | @Test 16 | public void testAddMsgListener() throws Exception { 17 | TestMsgListener testMsgListener = new TestMsgListener(); 18 | boolean result = MsgManager.addMsgListener(testMsgListener); 19 | 20 | MsgManager.dispatchMsg("createuser", 111, 222); 21 | assertEquals(true, result); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /msg/src/test/java/org/grain/msg/TestMsgListener.java: -------------------------------------------------------------------------------- 1 | package org.grain.msg; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | public class TestMsgListener implements IMsgListener { 7 | 8 | @Override 9 | public Map getMsgs() throws Exception { 10 | HashMap map = new HashMap<>(); 11 | map.put("createuser", "createUserHandle"); 12 | return map; 13 | } 14 | 15 | public void createUserHandle(MsgPacket msgPacket) { 16 | System.out.println("接到消息:" + msgPacket.getMsgOpCode()); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | com.github.dianbaer 6 | grain 7 | 1.0.0 8 | pom 9 | grain 10 | grain 11 | 12 | 1.8 13 | 1.8 14 | UTF-8 15 | 16 | 17 | log 18 | thread 19 | msg 20 | threadmsg 21 | threadkeylock 22 | httpclient 23 | httpserver 24 | httpserver-test 25 | websocket-lib 26 | websocket 27 | websocket-test 28 | threadwebsocket 29 | threadwebsocket-test 30 | tcp 31 | tcp-clienttest 32 | tcp-servertest 33 | rpc 34 | rpc-clienttest 35 | rpc-servertest 36 | distributedlock 37 | distributedlock-clienttest 38 | distributedlock-servertest 39 | config 40 | redis 41 | mariadb 42 | mongodb 43 | 44 | 45 | 46 | 47 | junit 48 | junit 49 | 4.13.1 50 | test 51 | 52 | 53 | -------------------------------------------------------------------------------- /redis/.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | .classpath 3 | .project 4 | .settings 5 | logs 6 | .idea 7 | *.iml 8 | dist -------------------------------------------------------------------------------- /redis/README.md: -------------------------------------------------------------------------------- 1 | # grain-redis 2 | 3 | grain-redis redis工具类,快速操作redis 4 | 5 | 6 | 此项目依赖 7 | 8 | grain-log 9 | commons-pool2-2.4.2.jar 10 | jedis-2.9.0.jar 11 | redis缓存数据库 12 | 13 | 使用 14 | 15 | 16 | 1、链接redis 17 | 18 | RedisManager.init("127.0.0.1", 6379, null); 19 | 20 | 2、存取字符串数据 21 | 22 | RedisManager.setStringValue("111", "222"); 23 | String str = RedisManager.getStringValue("111"); 24 | 25 | 3、存取序列化对象数据 26 | 27 | 28 | RedisTest------实现Serializable接口的可序列化对象 29 | 30 | package org.grain.redis; 31 | import java.io.Serializable; 32 | public class RedisTest implements Serializable { 33 | private static final long serialVersionUID = 1L; 34 | private String id; 35 | private String name; 36 | public RedisTest(String id, String name) { 37 | this.id = id; 38 | this.name = name; 39 | } 40 | public String getId() { 41 | return id; 42 | } 43 | public void setId(String id) { 44 | this.id = id; 45 | } 46 | public String getName() { 47 | return name; 48 | } 49 | public void setName(String name) { 50 | this.name = name; 51 | } 52 | } 53 | 54 | 存取操作 55 | 56 | RedisTest test = new RedisTest("3333", "4444"); 57 | RedisManager.setObjValue("3333", test); 58 | RedisTest test1 = (RedisTest) RedisManager.getObjValue("3333"); -------------------------------------------------------------------------------- /redis/build-redis.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /redis/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | com.github.dianbaer 6 | grain 7 | 1.0.0 8 | 9 | redis 10 | redis 11 | redis 12 | 13 | 14 | com.github.dianbaer 15 | log 16 | 1.0.0 17 | 18 | 19 | 20 | redis.clients 21 | jedis 22 | 2.9.0 23 | 24 | 25 | org.apache.commons 26 | commons-pool2 27 | 2.4.2 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /redis/src/main/java/org/grain/redis/DeserializingConverter.java: -------------------------------------------------------------------------------- 1 | package org.grain.redis; 2 | 3 | import java.io.ByteArrayInputStream; 4 | import java.io.IOException; 5 | import java.io.ObjectInputStream; 6 | 7 | import org.grain.log.ILog; 8 | 9 | public class DeserializingConverter implements IConverter { 10 | private ILog log; 11 | 12 | public DeserializingConverter(ILog log) { 13 | this.log = log; 14 | } 15 | 16 | @Override 17 | public Object convert(byte[] source) { 18 | ByteArrayInputStream byteArrayInputStream = null; 19 | ObjectInputStream objectInputStream = null; 20 | try { 21 | byteArrayInputStream = new ByteArrayInputStream(source); 22 | objectInputStream = new ObjectInputStream(byteArrayInputStream); 23 | return objectInputStream.readObject(); 24 | } catch (Exception e) { 25 | if (log != null) { 26 | log.error("redis反序列化异常", e); 27 | } 28 | return null; 29 | } finally { 30 | if (byteArrayInputStream != null) { 31 | try { 32 | byteArrayInputStream.close(); 33 | } catch (IOException e) { 34 | if (log != null) { 35 | log.error("redi关闭流异常", e); 36 | } 37 | } 38 | } 39 | if (objectInputStream != null) { 40 | try { 41 | objectInputStream.close(); 42 | } catch (IOException e) { 43 | if (log != null) { 44 | log.error("redi关闭流异常", e); 45 | } 46 | } 47 | } 48 | } 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /redis/src/main/java/org/grain/redis/IConverter.java: -------------------------------------------------------------------------------- 1 | package org.grain.redis; 2 | 3 | public interface IConverter { 4 | T convert(S source); 5 | } 6 | -------------------------------------------------------------------------------- /redis/src/main/java/org/grain/redis/SerializingConverter.java: -------------------------------------------------------------------------------- 1 | package org.grain.redis; 2 | 3 | import java.io.ByteArrayOutputStream; 4 | import java.io.IOException; 5 | import java.io.ObjectOutputStream; 6 | import java.io.Serializable; 7 | 8 | import org.grain.log.ILog; 9 | 10 | public class SerializingConverter implements IConverter { 11 | private ILog log; 12 | 13 | public SerializingConverter(ILog log) { 14 | this.log = log; 15 | } 16 | 17 | @Override 18 | public byte[] convert(Object source) { 19 | ByteArrayOutputStream byteArrayOutputStream = null; 20 | ObjectOutputStream objectOutputStream = null; 21 | try { 22 | if (!(source instanceof Serializable)) { 23 | throw new IllegalArgumentException("该对象未实现序列化接口"); 24 | } 25 | byteArrayOutputStream = new ByteArrayOutputStream(256); 26 | objectOutputStream = new ObjectOutputStream(byteArrayOutputStream); 27 | objectOutputStream.writeObject(source); 28 | objectOutputStream.flush(); 29 | return byteArrayOutputStream.toByteArray(); 30 | } catch (Exception e) { 31 | if (log != null) { 32 | log.error("redis序列化异常", e); 33 | } 34 | return null; 35 | } finally { 36 | if (byteArrayOutputStream != null) { 37 | try { 38 | byteArrayOutputStream.close(); 39 | } catch (IOException e) { 40 | if (log != null) { 41 | log.error("redi关闭流异常", e); 42 | } 43 | } 44 | } 45 | if (objectOutputStream != null) { 46 | try { 47 | objectOutputStream.close(); 48 | } catch (IOException e) { 49 | if (log != null) { 50 | log.error("redi关闭流异常", e); 51 | } 52 | } 53 | } 54 | } 55 | 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /redis/src/test/java/org/grain/redis/RedisManagerTest.java: -------------------------------------------------------------------------------- 1 | //package org.grain.redis; 2 | // 3 | //import static org.junit.Assert.assertEquals; 4 | // 5 | //import org.junit.BeforeClass; 6 | //import org.junit.Test; 7 | // 8 | //public class RedisManagerTest { 9 | // 10 | // @BeforeClass 11 | // public static void setUpBeforeClass() throws Exception { 12 | // RedisManager.init("127.0.0.1", 6379, null); 13 | // } 14 | // 15 | // @Test 16 | // public void testSetStringValue() { 17 | // RedisManager.setStringValue("111", "222"); 18 | // String str = RedisManager.getStringValue("111"); 19 | // assertEquals(true, (str != null && str.equals("222"))); 20 | // } 21 | // 22 | // @Test 23 | // public void testSetObjValue() { 24 | // RedisTest test = new RedisTest("3333", "4444"); 25 | // RedisManager.setObjValue("3333", test); 26 | // RedisTest test1 = (RedisTest) RedisManager.getObjValue("3333"); 27 | // assertEquals(true, test1 != null); 28 | // } 29 | // 30 | //} 31 | -------------------------------------------------------------------------------- /redis/src/test/java/org/grain/redis/RedisTest.java: -------------------------------------------------------------------------------- 1 | package org.grain.redis; 2 | 3 | import java.io.Serializable; 4 | 5 | public class RedisTest implements Serializable { 6 | 7 | /** 8 | * 9 | */ 10 | private static final long serialVersionUID = 1L; 11 | private String id; 12 | private String name; 13 | 14 | public RedisTest(String id, String name) { 15 | this.id = id; 16 | this.name = name; 17 | } 18 | 19 | public String getId() { 20 | return id; 21 | } 22 | 23 | public void setId(String id) { 24 | this.id = id; 25 | } 26 | 27 | public String getName() { 28 | return name; 29 | } 30 | 31 | public void setName(String name) { 32 | this.name = name; 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /rpc-clienttest/.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | .classpath 3 | .project 4 | .settings 5 | logs 6 | .idea 7 | *.iml 8 | dist -------------------------------------------------------------------------------- /rpc-clienttest/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | com.github.dianbaer 6 | grain 7 | 1.0.0 8 | 9 | rpc-clienttest 10 | rpc-clienttest 11 | rpc-clienttest 12 | 13 | 1.8 14 | 1.8 15 | UTF-8 16 | 17 | 18 | 19 | com.github.dianbaer 20 | rpc 21 | 1.0.0 22 | 23 | 24 | org.slf4j 25 | slf4j-log4j12 26 | 1.7.22 27 | 28 | 29 | -------------------------------------------------------------------------------- /rpc-clienttest/src/main/java/log/MyAppender.java: -------------------------------------------------------------------------------- 1 | package log; 2 | 3 | import org.apache.log4j.DailyRollingFileAppender; 4 | import org.apache.log4j.Priority; 5 | 6 | public class MyAppender extends DailyRollingFileAppender { 7 | @Override 8 | public boolean isAsSevereAsThreshold(Priority priority) { 9 | return this.getThreshold().equals(priority); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /rpc-clienttest/src/main/java/test/GrainLog.java: -------------------------------------------------------------------------------- 1 | package test; 2 | 3 | import org.grain.log.ILog; 4 | import org.slf4j.Logger; 5 | 6 | public class GrainLog implements ILog { 7 | private Logger log; 8 | 9 | public GrainLog(Logger log) { 10 | this.log = log; 11 | } 12 | 13 | @Override 14 | public void warn(String warn) { 15 | this.log.warn(warn); 16 | 17 | } 18 | 19 | @Override 20 | public void error(String error, Throwable e) { 21 | this.log.error(error, e); 22 | 23 | } 24 | 25 | @Override 26 | public void info(String info) { 27 | this.log.info(info); 28 | 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /rpc-clienttest/src/main/java/test/RPCClientTest.java: -------------------------------------------------------------------------------- 1 | package test; 2 | 3 | import org.grain.msg.MsgManager; 4 | import org.grain.rpc.ThreadMinaClientHandler; 5 | import org.grain.rpc.ThreadTcpManager; 6 | import org.grain.tcp.MinaClient; 7 | import org.grain.tcp.TcpManager; 8 | import org.grain.tcp.TcpMsg; 9 | import org.grain.rpc.WaitLockManager; 10 | import org.grain.thread.AsyncThreadManager; 11 | import org.grain.threadmsg.ThreadMsgManager; 12 | import org.slf4j.LoggerFactory; 13 | 14 | import protobuf.tcp.Test.RPCTestC; 15 | import protobuf.tcp.Test.RPCTestS; 16 | 17 | public class RPCClientTest { 18 | 19 | public static void main(String[] args) throws Exception { 20 | GrainLog grainLog = new GrainLog(LoggerFactory.getLogger("minaLog")); 21 | GrainLog grainLog1 = new GrainLog(LoggerFactory.getLogger("msgLog")); 22 | // 初始化线程消息 23 | AsyncThreadManager.init(100, 10, 3, 1, grainLog1); 24 | AsyncThreadManager.start(); 25 | MsgManager.init(true, grainLog1); 26 | // 设置消息归属线程,不设置则随机分配 27 | ThreadMsgManager.addMapping(TcpMsg.MINA_SERVER_CONNECTED, new int[] { 1, 1 }); 28 | ThreadMsgManager.addMapping(TcpMsg.MINA_SERVER_DISCONNECT, new int[] { 1, 1 }); 29 | // 注册关注的消息 30 | TestMsgService testService = new TestMsgService(); 31 | MsgManager.addMsgListener(testService); 32 | // 映射操作码解析类 33 | ThreadTcpManager.addThreadMapping(TestTCode.TEST_RPC_C, RPCTestC.class, null); 34 | ThreadTcpManager.addThreadMapping(TestTCode.TEST_RPC_S, RPCTestS.class, null); 35 | ThreadTcpManager.addThreadMapping(TestTCode.TEST_RPC_SERVER, RPCTestS.class, null); 36 | ThreadTcpManager.addThreadMapping(TestTCode.TEST_RPC_CLIENT, RPCTestC.class, null); 37 | 38 | TestRPCServiceC testRPCServiceC = new TestRPCServiceC(); 39 | TcpManager.addTcpListener(testRPCServiceC); 40 | WaitLockManager.init(120000); 41 | ThreadTcpManager.init(); 42 | // 创建TCP客户端 43 | MinaClient.init(new String[] { "0.0.0.0" }, new int[] { 7005 }, new String[] { "testserver" }, ThreadMinaClientHandler.class, 10, true, grainLog); 44 | 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /rpc-clienttest/src/main/java/test/TestMsgService.java: -------------------------------------------------------------------------------- 1 | package test; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | import org.apache.mina.core.session.IoSession; 7 | import org.grain.msg.IMsgListener; 8 | import org.grain.msg.MsgPacket; 9 | import org.grain.rpc.WaitLockManager; 10 | import org.grain.tcp.TcpMsg; 11 | import org.grain.tcp.TcpPacket; 12 | 13 | import protobuf.tcp.Test.RPCTestC; 14 | import protobuf.tcp.Test.RPCTestS; 15 | 16 | public class TestMsgService implements IMsgListener { 17 | 18 | @Override 19 | public Map getMsgs() throws Exception { 20 | HashMap map = new HashMap<>(); 21 | map.put(TcpMsg.MINA_SERVER_CONNECTED, "onServerConnected"); 22 | return map; 23 | } 24 | 25 | public void onServerConnected(MsgPacket msgPacket) { 26 | IoSession session = (IoSession) msgPacket.getOtherData(); 27 | System.out.println("接到消息:" + msgPacket.getMsgOpCode()); 28 | RPCTestC.Builder builder = RPCTestC.newBuilder(); 29 | builder.setName("RPC你好啊"); 30 | TcpPacket pt = new TcpPacket(TestTCode.TEST_RPC_C, builder.build()); 31 | 32 | TcpPacket ptReturn = WaitLockManager.lock(session, pt); 33 | RPCTestS rpcTestS = (RPCTestS) ptReturn.getData(); 34 | System.out.println("接到RPC消息:" + rpcTestS.getName()); 35 | 36 | RPCTestC.Builder builder1 = RPCTestC.newBuilder(); 37 | builder1.setName("TCP你好啊"); 38 | TcpPacket pt1 = new TcpPacket(TestTCode.TEST_RPC_C, builder1.build()); 39 | session.write(pt1); 40 | 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /rpc-clienttest/src/main/java/test/TestRPCServiceC.java: -------------------------------------------------------------------------------- 1 | package test; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | import org.grain.tcp.ITcpListener; 7 | import org.grain.tcp.TcpPacket; 8 | 9 | import protobuf.tcp.Test.RPCTestC; 10 | import protobuf.tcp.Test.RPCTestS; 11 | 12 | public class TestRPCServiceC implements ITcpListener { 13 | 14 | @Override 15 | public Map getTcps() throws Exception { 16 | HashMap map = new HashMap<>(); 17 | map.put(TestTCode.TEST_RPC_SERVER, "onTestRPCServer"); 18 | return map; 19 | } 20 | 21 | public TcpPacket onTestRPCServer(TcpPacket tcpPacket) { 22 | tcpPacket.putMonitor("接到服务器发来的消息"); 23 | RPCTestS tests = (RPCTestS) tcpPacket.getData(); 24 | tcpPacket.putMonitor("发来名字为:" + tests.getName()); 25 | RPCTestC.Builder builder = RPCTestC.newBuilder(); 26 | builder.setName("服务器你好"); 27 | TcpPacket pt = new TcpPacket(TestTCode.TEST_RPC_CLIENT, builder.build()); 28 | return pt; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /rpc-clienttest/src/main/java/test/TestTCode.java: -------------------------------------------------------------------------------- 1 | package test; 2 | 3 | public class TestTCode { 4 | public static int TEST_RPC_C = 1; 5 | public static int TEST_RPC_S = 2; 6 | public static int TEST_RPC_SERVER = 3; 7 | public static int TEST_RPC_CLIENT = 4; 8 | } 9 | -------------------------------------------------------------------------------- /rpc-servertest/.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | .classpath 3 | .project 4 | .settings 5 | logs 6 | .idea 7 | *.iml 8 | dist -------------------------------------------------------------------------------- /rpc-servertest/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | com.github.dianbaer 6 | grain 7 | 1.0.0 8 | 9 | rpc-servertest 10 | rpc-servertest 11 | rpc-servertest 12 | 13 | 1.8 14 | 1.8 15 | UTF-8 16 | 17 | 18 | 19 | com.github.dianbaer 20 | rpc 21 | 1.0.0 22 | 23 | 24 | org.slf4j 25 | slf4j-log4j12 26 | 1.7.22 27 | 28 | 29 | -------------------------------------------------------------------------------- /rpc-servertest/protobuf/Test.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package protobuf.tcp; 3 | message RPCTestC{ 4 | string name=1; 5 | } 6 | message RPCTestS{ 7 | string name=1; 8 | } -------------------------------------------------------------------------------- /rpc-servertest/protobuf/protobuf编译.bat: -------------------------------------------------------------------------------- 1 | C: 2 | cd C:\Users\admin\Desktop\github\grain\trunk\grain-rpc-servertest\protobuf 3 | protoc --java_out=./ Test.proto 4 | -------------------------------------------------------------------------------- /rpc-servertest/protobuf/protoc.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dianbaer/grain/6dabee1f6ac4a9c845416057babdc0d059363f7f/rpc-servertest/protobuf/protoc.exe -------------------------------------------------------------------------------- /rpc-servertest/src/main/java/log/MyAppender.java: -------------------------------------------------------------------------------- 1 | package log; 2 | 3 | import org.apache.log4j.DailyRollingFileAppender; 4 | import org.apache.log4j.Priority; 5 | 6 | public class MyAppender extends DailyRollingFileAppender { 7 | @Override 8 | public boolean isAsSevereAsThreshold(Priority priority) { 9 | return this.getThreshold().equals(priority); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /rpc-servertest/src/main/java/test/GrainLog.java: -------------------------------------------------------------------------------- 1 | package test; 2 | 3 | import org.grain.log.ILog; 4 | import org.slf4j.Logger; 5 | 6 | public class GrainLog implements ILog { 7 | private Logger log; 8 | 9 | public GrainLog(Logger log) { 10 | this.log = log; 11 | } 12 | 13 | @Override 14 | public void warn(String warn) { 15 | this.log.warn(warn); 16 | 17 | } 18 | 19 | @Override 20 | public void error(String error, Throwable e) { 21 | this.log.error(error, e); 22 | 23 | } 24 | 25 | @Override 26 | public void info(String info) { 27 | this.log.info(info); 28 | 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /rpc-servertest/src/main/java/test/RPCServerTest.java: -------------------------------------------------------------------------------- 1 | package test; 2 | 3 | import org.grain.msg.MsgManager; 4 | import org.grain.rpc.ThreadMinaServerHandler; 5 | import org.grain.rpc.ThreadTcpManager; 6 | import org.grain.rpc.WaitLockManager; 7 | import org.grain.tcp.MinaServer; 8 | import org.grain.tcp.TcpManager; 9 | import org.grain.tcp.TcpMsg; 10 | import org.grain.thread.AsyncThreadManager; 11 | import org.grain.threadmsg.ThreadMsgManager; 12 | import org.slf4j.LoggerFactory; 13 | 14 | import protobuf.tcp.Test.RPCTestC; 15 | import protobuf.tcp.Test.RPCTestS; 16 | 17 | public class RPCServerTest { 18 | 19 | public static void main(String[] args) throws Exception { 20 | GrainLog grainLog = new GrainLog(LoggerFactory.getLogger("minaLog")); 21 | GrainLog grainLog1 = new GrainLog(LoggerFactory.getLogger("msgLog")); 22 | 23 | // 初始化线程消息 24 | AsyncThreadManager.init(100, 10, 3, 1, grainLog1); 25 | AsyncThreadManager.start(); 26 | MsgManager.init(true, grainLog1); 27 | // 设置消息归属线程,不设置则随机分配 28 | ThreadMsgManager.addMapping(TcpMsg.MINA_CLIENT_CREATE_CONNECT, new int[] { 1, 1 }); 29 | ThreadMsgManager.addMapping(TcpMsg.MINA_CLIENT_DISCONNECT, new int[] { 1, 1 }); 30 | // 注册关注的消息 31 | TestMsgService testService = new TestMsgService(); 32 | MsgManager.addMsgListener(testService); 33 | // 映射操作码解析类 34 | ThreadTcpManager.addThreadMapping(TestTCode.TEST_RPC_C, RPCTestC.class, null); 35 | ThreadTcpManager.addThreadMapping(TestTCode.TEST_RPC_S, RPCTestS.class, null); 36 | ThreadTcpManager.addThreadMapping(TestTCode.TEST_RPC_SERVER, RPCTestS.class, null); 37 | ThreadTcpManager.addThreadMapping(TestTCode.TEST_RPC_CLIENT, RPCTestC.class, null); 38 | // 注册tcp回调函数 39 | TestRPCServiceS testRPCServiceS = new TestRPCServiceS(); 40 | TcpManager.addTcpListener(testRPCServiceS); 41 | WaitLockManager.init(120000); 42 | ThreadTcpManager.init(); 43 | // 创建TCP服务器 44 | MinaServer.init("0.0.0.0", 7005, ThreadMinaServerHandler.class, true, grainLog); 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /rpc-servertest/src/main/java/test/TestMsgService.java: -------------------------------------------------------------------------------- 1 | package test; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | import org.apache.mina.core.session.IoSession; 7 | import org.grain.msg.IMsgListener; 8 | import org.grain.msg.MsgPacket; 9 | import org.grain.rpc.WaitLockManager; 10 | import org.grain.tcp.TcpMsg; 11 | import org.grain.tcp.TcpPacket; 12 | 13 | import protobuf.tcp.Test.RPCTestC; 14 | import protobuf.tcp.Test.RPCTestS; 15 | 16 | public class TestMsgService implements IMsgListener { 17 | 18 | @Override 19 | public Map getMsgs() throws Exception { 20 | HashMap map = new HashMap<>(); 21 | map.put(TcpMsg.MINA_CLIENT_CREATE_CONNECT, "onClientConnected"); 22 | return map; 23 | } 24 | 25 | public void onClientConnected(MsgPacket msgPacket) { 26 | IoSession session = (IoSession) msgPacket.getOtherData(); 27 | System.out.println("接到消息:" + msgPacket.getMsgOpCode()); 28 | RPCTestS.Builder builder = RPCTestS.newBuilder(); 29 | builder.setName("RPC你好啊"); 30 | TcpPacket pt = new TcpPacket(TestTCode.TEST_RPC_SERVER, builder.build()); 31 | 32 | TcpPacket ptReturn = WaitLockManager.lock(session, pt); 33 | RPCTestC rpcTestC = (RPCTestC) ptReturn.getData(); 34 | System.out.println("接到RPC消息:" + rpcTestC.getName()); 35 | 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /rpc-servertest/src/main/java/test/TestRPCServiceS.java: -------------------------------------------------------------------------------- 1 | package test; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | import org.grain.tcp.ITcpListener; 7 | import org.grain.tcp.TcpPacket; 8 | 9 | import protobuf.tcp.Test.RPCTestC; 10 | import protobuf.tcp.Test.RPCTestS; 11 | 12 | public class TestRPCServiceS implements ITcpListener { 13 | 14 | @Override 15 | public Map getTcps() throws Exception { 16 | HashMap map = new HashMap<>(); 17 | map.put(TestTCode.TEST_RPC_C, "onTestRPCC"); 18 | return map; 19 | } 20 | 21 | public TcpPacket onTestRPCC(TcpPacket tcpPacket) { 22 | tcpPacket.putMonitor("接到客户端发来的消息"); 23 | RPCTestC testc = (RPCTestC) tcpPacket.getData(); 24 | tcpPacket.putMonitor("发来名字为:" + testc.getName()); 25 | RPCTestS.Builder builder = RPCTestS.newBuilder(); 26 | builder.setName("客户端你好"); 27 | TcpPacket pt = new TcpPacket(TestTCode.TEST_RPC_S, builder.build()); 28 | return pt; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /rpc-servertest/src/main/java/test/TestTCode.java: -------------------------------------------------------------------------------- 1 | package test; 2 | 3 | public class TestTCode { 4 | public static int TEST_RPC_C = 1; 5 | public static int TEST_RPC_S = 2; 6 | public static int TEST_RPC_SERVER = 3; 7 | public static int TEST_RPC_CLIENT = 4; 8 | } 9 | -------------------------------------------------------------------------------- /rpc/.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | .classpath 3 | .project 4 | .settings 5 | logs 6 | .idea 7 | *.iml 8 | dist -------------------------------------------------------------------------------- /rpc/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | com.github.dianbaer 6 | grain 7 | 1.0.0 8 | 9 | rpc 10 | rpc 11 | rpc 12 | 13 | 1.8 14 | 1.8 15 | UTF-8 16 | 17 | 18 | 19 | com.github.dianbaer 20 | threadmsg 21 | 1.0.0 22 | 23 | 24 | com.github.dianbaer 25 | tcp 26 | 1.0.0 27 | 28 | 29 | -------------------------------------------------------------------------------- /rpc/rpc-client.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dianbaer/grain/6dabee1f6ac4a9c845416057babdc0d059363f7f/rpc/rpc-client.png -------------------------------------------------------------------------------- /rpc/rpc-client.vsd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dianbaer/grain/6dabee1f6ac4a9c845416057babdc0d059363f7f/rpc/rpc-client.vsd -------------------------------------------------------------------------------- /rpc/rpc-server.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dianbaer/grain/6dabee1f6ac4a9c845416057babdc0d059363f7f/rpc/rpc-server.png -------------------------------------------------------------------------------- /rpc/rpc-server.vsd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dianbaer/grain/6dabee1f6ac4a9c845416057babdc0d059363f7f/rpc/rpc-server.vsd -------------------------------------------------------------------------------- /rpc/src/main/java/org/grain/rpc/ThreadMinaClientHandler.java: -------------------------------------------------------------------------------- 1 | package org.grain.rpc; 2 | 3 | import org.apache.mina.core.session.IoSession; 4 | import org.grain.tcp.MinaClient; 5 | import org.grain.tcp.MinaConfig; 6 | import org.grain.tcp.MinaHandler; 7 | import org.grain.tcp.TcpMsg; 8 | import org.grain.tcp.TcpPacket; 9 | import org.grain.threadmsg.ThreadMsgManager; 10 | 11 | public class ThreadMinaClientHandler extends MinaHandler { 12 | 13 | @Override 14 | public void messageReceived(IoSession session, Object message) throws Exception { 15 | super.messageReceived(session, message); 16 | if (MinaConfig.log != null) { 17 | MinaConfig.log.info("minaclient messageReceived"); 18 | } 19 | // 派发tcp 20 | ThreadTcpManager.dispatchTcp((TcpPacket) message); 21 | } 22 | 23 | @Override 24 | public void sessionClosed(IoSession session) throws Exception { 25 | super.sessionClosed(session); 26 | if (MinaConfig.log != null) { 27 | MinaConfig.log.warn("minaclient sessionClosed"); 28 | } 29 | // 设置链接已断开,断线过会儿会断线重连 30 | MinaClient.getInstance().ioConnectorStateMap.put(ioConnector, false); 31 | // 发布与服务器断开的消息 32 | ThreadMsgManager.dispatchThreadMsg(TcpMsg.MINA_SERVER_DISCONNECT, this.name, session); 33 | } 34 | 35 | @Override 36 | public void sessionCreated(IoSession session) throws Exception { 37 | super.sessionCreated(session); 38 | if (MinaConfig.log != null) { 39 | MinaConfig.log.info("minaclient sessionCreated"); 40 | } 41 | // 发布与服务器链接成功的消息 42 | ThreadMsgManager.dispatchThreadMsg(TcpMsg.MINA_SERVER_CONNECTED, this.name, session); 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /rpc/src/main/java/org/grain/rpc/ThreadMinaServerHandler.java: -------------------------------------------------------------------------------- 1 | package org.grain.rpc; 2 | 3 | import org.apache.mina.core.session.IoSession; 4 | import org.grain.tcp.MinaConfig; 5 | import org.grain.tcp.MinaHandler; 6 | import org.grain.tcp.TcpMsg; 7 | import org.grain.tcp.TcpPacket; 8 | import org.grain.threadmsg.ThreadMsgManager; 9 | 10 | public class ThreadMinaServerHandler extends MinaHandler { 11 | 12 | @Override 13 | public void messageReceived(IoSession session, Object message) throws Exception { 14 | super.messageReceived(session, message); 15 | if (MinaConfig.log != null) { 16 | MinaConfig.log.info("minaserver messageReceived"); 17 | } 18 | ThreadTcpManager.dispatchTcp((TcpPacket) message); 19 | } 20 | 21 | @Override 22 | public void sessionClosed(IoSession session) throws Exception { 23 | super.sessionClosed(session); 24 | if (MinaConfig.log != null) { 25 | MinaConfig.log.warn("minaserver sessionClosed"); 26 | } 27 | ThreadMsgManager.dispatchThreadMsg(TcpMsg.MINA_CLIENT_DISCONNECT, null, session); 28 | } 29 | 30 | @Override 31 | public void sessionCreated(IoSession session) throws Exception { 32 | super.sessionCreated(session); 33 | if (MinaConfig.log != null) { 34 | MinaConfig.log.info("minaserver sessionCreated"); 35 | } 36 | ThreadMsgManager.dispatchThreadMsg(TcpMsg.MINA_CLIENT_CREATE_CONNECT, null, session); 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /rpc/src/main/java/org/grain/rpc/WaitLock.java: -------------------------------------------------------------------------------- 1 | package org.grain.rpc; 2 | 3 | import java.util.concurrent.atomic.AtomicInteger; 4 | 5 | import org.grain.tcp.TcpPacket; 6 | 7 | public class WaitLock { 8 | /** 9 | * 自增 10 | */ 11 | private static AtomicInteger atomicInteger = new AtomicInteger(0); 12 | /** 13 | * 对于每个进程都是唯一的id 14 | */ 15 | private int instanceId; 16 | /** 17 | * 消息包 18 | */ 19 | private TcpPacket tcpPacket; 20 | 21 | public WaitLock() { 22 | instanceId = atomicInteger.incrementAndGet(); 23 | } 24 | 25 | public int getInstanceId() { 26 | return instanceId; 27 | } 28 | 29 | public void setInstanceId(int instanceId) { 30 | this.instanceId = instanceId; 31 | } 32 | 33 | public TcpPacket getTcpPacket() { 34 | return tcpPacket; 35 | } 36 | 37 | public void setTcpPacket(TcpPacket tcpPacket) { 38 | this.tcpPacket = tcpPacket; 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /rpc/src/main/java/org/grain/rpc/WaitLockManager.java: -------------------------------------------------------------------------------- 1 | package org.grain.rpc; 2 | 3 | import java.util.Map; 4 | import java.util.concurrent.ConcurrentHashMap; 5 | 6 | import org.apache.mina.core.session.IoSession; 7 | import org.grain.tcp.MinaConfig; 8 | import org.grain.tcp.TcpPacket; 9 | 10 | public class WaitLockManager { 11 | public static Map waitLockMap = new ConcurrentHashMap(); 12 | public static int waitLockTime; 13 | 14 | /** 15 | * 初始化 设置rpc过期时间 16 | * 17 | * @param waitLockTime 18 | * 过期时间一般为120000毫秒 2分钟 19 | */ 20 | public static void init(int waitLockTime) { 21 | WaitLockManager.waitLockTime = waitLockTime; 22 | } 23 | 24 | /** 25 | * 获取锁 26 | * 27 | * @return 28 | */ 29 | private static WaitLock getWaitLock() { 30 | WaitLock waitLock = new WaitLock(); 31 | waitLockMap.put(waitLock.getInstanceId(), waitLock); 32 | return waitLock; 33 | } 34 | 35 | /** 36 | * 获取数据 37 | * 38 | * @param ioSession 39 | * 链接句柄 40 | * @param tcpPacket 41 | * 消息包 42 | * @return 43 | */ 44 | public static TcpPacket lock(IoSession ioSession, TcpPacket tcpPacket) { 45 | // 获取锁 46 | WaitLock waitLock = getWaitLock(); 47 | // 设置此进程唯一id 48 | tcpPacket.lockedId = waitLock.getInstanceId(); 49 | // 同步块 50 | synchronized (waitLock) { 51 | // 发送消息 52 | ioSession.write(tcpPacket); 53 | try { 54 | // 等待解锁 55 | waitLock.wait(waitLockTime); 56 | } catch (InterruptedException e) { 57 | if (MinaConfig.log != null) { 58 | MinaConfig.log.error("获取数据超时", e); 59 | } 60 | } 61 | } 62 | // 解锁成功返回数据 63 | return waitLock.getTcpPacket(); 64 | } 65 | 66 | /** 67 | * 唤醒同步块 68 | * 69 | * @param tcpPacket 70 | * 返回的消息包 71 | */ 72 | public static void unLock(TcpPacket tcpPacket) { 73 | // 如果没有此进程唯一的唤醒id则返回 74 | if (tcpPacket.unlockedId == 0) { 75 | return; 76 | } 77 | // 根据唤醒id获取锁对象 78 | WaitLock waitLock = waitLockMap.get(tcpPacket.unlockedId); 79 | // 携带消息包 80 | waitLock.setTcpPacket(tcpPacket); 81 | // 唤醒 82 | synchronized (waitLock) { 83 | waitLock.notify(); 84 | } 85 | // 移除数组 86 | waitLockMap.remove(tcpPacket.unlockedId); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /tcp-clienttest/.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | .classpath 3 | .project 4 | .settings 5 | logs 6 | .idea 7 | *.iml 8 | dist -------------------------------------------------------------------------------- /tcp-clienttest/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | com.github.dianbaer 6 | grain 7 | 1.0.0 8 | 9 | tcp-clienttest 10 | tcp-clienttest 11 | tcp-clienttest 12 | 13 | 1.8 14 | 1.8 15 | UTF-8 16 | 17 | 18 | 19 | com.github.dianbaer 20 | tcp 21 | 1.0.0 22 | 23 | 24 | org.slf4j 25 | slf4j-log4j12 26 | 1.7.22 27 | 28 | 29 | -------------------------------------------------------------------------------- /tcp-clienttest/src/main/java/log/MyAppender.java: -------------------------------------------------------------------------------- 1 | package log; 2 | 3 | import org.apache.log4j.DailyRollingFileAppender; 4 | import org.apache.log4j.Priority; 5 | 6 | public class MyAppender extends DailyRollingFileAppender { 7 | @Override 8 | public boolean isAsSevereAsThreshold(Priority priority) { 9 | return this.getThreshold().equals(priority); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /tcp-clienttest/src/main/java/test/GrainLog.java: -------------------------------------------------------------------------------- 1 | package test; 2 | 3 | import org.grain.log.ILog; 4 | import org.slf4j.Logger; 5 | 6 | public class GrainLog implements ILog { 7 | private Logger log; 8 | 9 | public GrainLog(Logger log) { 10 | this.log = log; 11 | } 12 | 13 | @Override 14 | public void warn(String warn) { 15 | this.log.warn(warn); 16 | 17 | } 18 | 19 | @Override 20 | public void error(String error, Throwable e) { 21 | this.log.error(error, e); 22 | 23 | } 24 | 25 | @Override 26 | public void info(String info) { 27 | this.log.info(info); 28 | 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /tcp-clienttest/src/main/java/test/TCPClientTest.java: -------------------------------------------------------------------------------- 1 | package test; 2 | 3 | import org.grain.msg.MsgManager; 4 | import org.grain.tcp.MinaClient; 5 | import org.grain.tcp.MinaClientHandler; 6 | import org.grain.tcp.TcpManager; 7 | import org.slf4j.LoggerFactory; 8 | 9 | import protobuf.tcp.Test.TestC; 10 | import protobuf.tcp.Test.TestS; 11 | 12 | public class TCPClientTest { 13 | public static void main(String[] args) throws Exception { 14 | GrainLog grainLog = new GrainLog(LoggerFactory.getLogger("minaLog")); 15 | GrainLog grainLog1 = new GrainLog(LoggerFactory.getLogger("msgLog")); 16 | // 初始化消息 17 | MsgManager.init(true, grainLog1); 18 | // 注册关注的消息 19 | TestMsgService testService = new TestMsgService(); 20 | MsgManager.addMsgListener(testService); 21 | // 映射操作码解析类 22 | TcpManager.addMapping(TestTCode.TESTC, TestC.class); 23 | TcpManager.addMapping(TestTCode.TESTS, TestS.class); 24 | // 注册tcp回调函数 25 | TestTcpServiceC testTcpServiceC = new TestTcpServiceC(); 26 | TcpManager.addTcpListener(testTcpServiceC); 27 | // 创建TCP客户端 28 | MinaClient.init(new String[] { "0.0.0.0" }, new int[] { 7005 }, new String[] { "testserver" }, MinaClientHandler.class, 10, true, grainLog); 29 | 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /tcp-clienttest/src/main/java/test/TestMsgService.java: -------------------------------------------------------------------------------- 1 | package test; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | import org.apache.mina.core.session.IoSession; 7 | import org.grain.msg.IMsgListener; 8 | import org.grain.msg.MsgPacket; 9 | import org.grain.tcp.TcpMsg; 10 | import org.grain.tcp.TcpPacket; 11 | 12 | import protobuf.tcp.Test.TestC; 13 | 14 | public class TestMsgService implements IMsgListener { 15 | 16 | @Override 17 | public Map getMsgs() throws Exception { 18 | HashMap map = new HashMap<>(); 19 | map.put(TcpMsg.MINA_SERVER_CONNECTED, "onServerConnected"); 20 | return map; 21 | } 22 | 23 | public void onServerConnected(MsgPacket msgPacket) { 24 | IoSession session = (IoSession) msgPacket.getOtherData(); 25 | System.out.println("接到消息:" + msgPacket.getMsgOpCode()); 26 | TestC.Builder builder = TestC.newBuilder(); 27 | builder.setName("你好啊"); 28 | TcpPacket pt = new TcpPacket(TestTCode.TESTC, builder.build()); 29 | session.write(pt); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /tcp-clienttest/src/main/java/test/TestTCode.java: -------------------------------------------------------------------------------- 1 | package test; 2 | 3 | public class TestTCode { 4 | public static int TESTC = 1; 5 | public static int TESTS = 2; 6 | } 7 | -------------------------------------------------------------------------------- /tcp-clienttest/src/main/java/test/TestTcpServiceC.java: -------------------------------------------------------------------------------- 1 | package test; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | import org.grain.tcp.ITcpListener; 7 | import org.grain.tcp.TcpPacket; 8 | 9 | import protobuf.tcp.Test.TestS; 10 | 11 | public class TestTcpServiceC implements ITcpListener { 12 | 13 | @Override 14 | public Map getTcps() throws Exception { 15 | HashMap map = new HashMap<>(); 16 | map.put(TestTCode.TESTS, "onTestS"); 17 | return map; 18 | } 19 | 20 | public void onTestS(TcpPacket tcpPacket) { 21 | tcpPacket.putMonitor("接到客户端发来的消息"); 22 | TestS tests = (TestS) tcpPacket.getData(); 23 | tcpPacket.putMonitor("发来名字为:" + tests.getName()); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /tcp-servertest/.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | .classpath 3 | .project 4 | .settings 5 | logs 6 | .idea 7 | *.iml 8 | dist -------------------------------------------------------------------------------- /tcp-servertest/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | com.github.dianbaer 6 | grain 7 | 1.0.0 8 | 9 | tcp-servertest 10 | tcp-servertest 11 | tcp-servertest 12 | 13 | 1.8 14 | 1.8 15 | UTF-8 16 | 17 | 18 | 19 | com.github.dianbaer 20 | tcp 21 | 1.0.0 22 | 23 | 24 | org.slf4j 25 | slf4j-log4j12 26 | 1.7.22 27 | 28 | 29 | -------------------------------------------------------------------------------- /tcp-servertest/protobuf/Test.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package protobuf.tcp; 3 | message TestC{ 4 | string name=1; 5 | } 6 | message TestS{ 7 | string name=1; 8 | } -------------------------------------------------------------------------------- /tcp-servertest/protobuf/protobuf编译.bat: -------------------------------------------------------------------------------- 1 | D: 2 | cd D:\github\grain\trunk\grain-tcp-servertest\protobuf 3 | protoc --java_out=./ Test.proto 4 | -------------------------------------------------------------------------------- /tcp-servertest/protobuf/protoc.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dianbaer/grain/6dabee1f6ac4a9c845416057babdc0d059363f7f/tcp-servertest/protobuf/protoc.exe -------------------------------------------------------------------------------- /tcp-servertest/src/main/java/log/MyAppender.java: -------------------------------------------------------------------------------- 1 | package log; 2 | 3 | import org.apache.log4j.DailyRollingFileAppender; 4 | import org.apache.log4j.Priority; 5 | 6 | public class MyAppender extends DailyRollingFileAppender { 7 | @Override 8 | public boolean isAsSevereAsThreshold(Priority priority) { 9 | return this.getThreshold().equals(priority); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /tcp-servertest/src/main/java/test/GrainLog.java: -------------------------------------------------------------------------------- 1 | package test; 2 | 3 | import org.grain.log.ILog; 4 | import org.slf4j.Logger; 5 | 6 | public class GrainLog implements ILog { 7 | private Logger log; 8 | 9 | public GrainLog(Logger log) { 10 | this.log = log; 11 | } 12 | 13 | @Override 14 | public void warn(String warn) { 15 | this.log.warn(warn); 16 | 17 | } 18 | 19 | @Override 20 | public void error(String error, Throwable e) { 21 | this.log.error(error, e); 22 | 23 | } 24 | 25 | @Override 26 | public void info(String info) { 27 | this.log.info(info); 28 | 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /tcp-servertest/src/main/java/test/TCPServerTest.java: -------------------------------------------------------------------------------- 1 | package test; 2 | 3 | import org.grain.msg.MsgManager; 4 | import org.grain.tcp.MinaServer; 5 | import org.grain.tcp.MinaServerHandler; 6 | import org.grain.tcp.TcpManager; 7 | import org.slf4j.LoggerFactory; 8 | 9 | import protobuf.tcp.Test.TestC; 10 | import protobuf.tcp.Test.TestS; 11 | 12 | public class TCPServerTest { 13 | public static void main(String[] args) throws Exception { 14 | GrainLog grainLog = new GrainLog(LoggerFactory.getLogger("minaLog")); 15 | GrainLog grainLog1 = new GrainLog(LoggerFactory.getLogger("msgLog")); 16 | 17 | // 初始化消息 18 | MsgManager.init(true, grainLog1); 19 | // 映射操作码解析类 20 | TcpManager.addMapping(TestTCode.TESTC, TestC.class); 21 | TcpManager.addMapping(TestTCode.TESTS, TestS.class); 22 | // 注册tcp回调函数 23 | TestTcpServiceS testTcpServiceS = new TestTcpServiceS(); 24 | TcpManager.addTcpListener(testTcpServiceS); 25 | // 创建TCP服务器 26 | MinaServer.init("0.0.0.0", 7005, MinaServerHandler.class, true, grainLog); 27 | 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /tcp-servertest/src/main/java/test/TestTCode.java: -------------------------------------------------------------------------------- 1 | package test; 2 | 3 | public class TestTCode { 4 | public static int TESTC = 1; 5 | public static int TESTS = 2; 6 | } 7 | -------------------------------------------------------------------------------- /tcp-servertest/src/main/java/test/TestTcpServiceS.java: -------------------------------------------------------------------------------- 1 | package test; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | import org.apache.mina.core.session.IoSession; 7 | import org.grain.tcp.ITcpListener; 8 | import org.grain.tcp.TcpPacket; 9 | 10 | import protobuf.tcp.Test.TestC; 11 | import protobuf.tcp.Test.TestS; 12 | 13 | public class TestTcpServiceS implements ITcpListener { 14 | 15 | @Override 16 | public Map getTcps() throws Exception { 17 | HashMap map = new HashMap<>(); 18 | map.put(TestTCode.TESTC, "onTestC"); 19 | return map; 20 | } 21 | 22 | public void onTestC(TcpPacket tcpPacket) { 23 | tcpPacket.putMonitor("接到客户端发来的消息"); 24 | TestC testc = (TestC) tcpPacket.getData(); 25 | tcpPacket.putMonitor("发来名字为:" + testc.getName()); 26 | TestS.Builder builder = TestS.newBuilder(); 27 | builder.setName("客户端你好"); 28 | TcpPacket pt = new TcpPacket(TestTCode.TESTS, builder.build()); 29 | ((IoSession) tcpPacket.session).write(pt); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /tcp/.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | .classpath 3 | .project 4 | .settings 5 | logs 6 | .idea 7 | *.iml 8 | dist -------------------------------------------------------------------------------- /tcp/build-tcp.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /tcp/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | com.github.dianbaer 6 | grain 7 | 1.0.0 8 | 9 | tcp 10 | tcp 11 | tcp 12 | 13 | 1.8 14 | 1.8 15 | UTF-8 16 | 17 | 18 | 19 | com.github.dianbaer 20 | msg 21 | 1.0.0 22 | 23 | 24 | com.google.protobuf 25 | protobuf-java 26 | 3.1.0 27 | 28 | 29 | org.apache.mina 30 | mina-core 31 | 2.0.16 32 | 33 | 34 | org.slf4j 35 | slf4j-api 36 | 1.7.22 37 | 38 | 39 | -------------------------------------------------------------------------------- /tcp/src/main/java/org/grain/tcp/ITcpListener.java: -------------------------------------------------------------------------------- 1 | package org.grain.tcp; 2 | 3 | import java.util.Map; 4 | 5 | public interface ITcpListener { 6 | /** 7 | * 关注的tcp消息类型,实现此接口,tcp分发器会回调这些注册的函数 8 | * 9 | * @return Map tcp操作码,处理函数名 10 | * @throws Exception 11 | */ 12 | public Map getTcps() throws Exception; 13 | } 14 | -------------------------------------------------------------------------------- /tcp/src/main/java/org/grain/tcp/MinaClientHandler.java: -------------------------------------------------------------------------------- 1 | package org.grain.tcp; 2 | 3 | import org.apache.mina.core.session.IoSession; 4 | import org.grain.msg.MsgManager; 5 | 6 | public class MinaClientHandler extends MinaHandler { 7 | 8 | @Override 9 | public void messageReceived(IoSession session, Object message) throws Exception { 10 | super.messageReceived(session, message); 11 | if (MinaConfig.log != null) { 12 | MinaConfig.log.info("minaclient messageReceived"); 13 | } 14 | // 派发tcp 15 | TcpManager.dispatchTcp((TcpPacket) message); 16 | } 17 | 18 | @Override 19 | public void sessionClosed(IoSession session) throws Exception { 20 | super.sessionClosed(session); 21 | if (MinaConfig.log != null) { 22 | MinaConfig.log.warn("minaclient sessionClosed"); 23 | } 24 | // 设置链接已断开,断线过会儿会断线重连 25 | MinaClient.getInstance().ioConnectorStateMap.put(ioConnector, false); 26 | // 发布与服务器断开的消息 27 | MsgManager.dispatchMsg(TcpMsg.MINA_SERVER_DISCONNECT, this.name, session); 28 | } 29 | 30 | @Override 31 | public void sessionCreated(IoSession session) throws Exception { 32 | super.sessionCreated(session); 33 | if (MinaConfig.log != null) { 34 | MinaConfig.log.info("minaclient sessionCreated"); 35 | } 36 | // 发布与服务器链接成功的消息 37 | MsgManager.dispatchMsg(TcpMsg.MINA_SERVER_CONNECTED, this.name, session); 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /tcp/src/main/java/org/grain/tcp/MinaConfig.java: -------------------------------------------------------------------------------- 1 | package org.grain.tcp; 2 | 3 | import org.grain.log.ILog; 4 | 5 | public class MinaConfig { 6 | public static boolean USE_TCP_MONITOR; 7 | public static ILog log; 8 | } 9 | -------------------------------------------------------------------------------- /tcp/src/main/java/org/grain/tcp/MinaEncoder.java: -------------------------------------------------------------------------------- 1 | 2 | package org.grain.tcp; 3 | 4 | import org.apache.mina.core.buffer.IoBuffer; 5 | import org.apache.mina.core.session.IoSession; 6 | import org.apache.mina.filter.codec.ProtocolEncoderAdapter; 7 | import org.apache.mina.filter.codec.ProtocolEncoderOutput; 8 | 9 | public class MinaEncoder extends ProtocolEncoderAdapter { 10 | public static final byte[] HEAD = { 'U', 'A' }; 11 | 12 | @Override 13 | public void encode(IoSession session, Object obj, ProtocolEncoderOutput out) throws Exception { 14 | TcpPacket packet = (TcpPacket) obj; 15 | byte[] byteData = packet.getByteData(); 16 | int len = 18 + byteData.length; 17 | IoBuffer buf = IoBuffer.allocate(len); 18 | buf.put(HEAD); 19 | buf.putInt(len); 20 | buf.putInt(packet.gettOpCode()); 21 | buf.putInt(packet.lockedId); 22 | buf.putInt(packet.unlockedId); 23 | buf.put(byteData); 24 | buf.flip(); 25 | out.write(buf); 26 | 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /tcp/src/main/java/org/grain/tcp/MinaHandler.java: -------------------------------------------------------------------------------- 1 | package org.grain.tcp; 2 | 3 | import org.apache.mina.core.service.IoConnector; 4 | import org.apache.mina.core.service.IoHandlerAdapter; 5 | 6 | public class MinaHandler extends IoHandlerAdapter { 7 | public IoConnector ioConnector; 8 | public String name; 9 | } 10 | -------------------------------------------------------------------------------- /tcp/src/main/java/org/grain/tcp/MinaServer.java: -------------------------------------------------------------------------------- 1 | package org.grain.tcp; 2 | 3 | import java.net.InetSocketAddress; 4 | 5 | import org.apache.mina.core.service.IoAcceptor; 6 | import org.apache.mina.filter.codec.ProtocolCodecFilter; 7 | import org.apache.mina.transport.socket.nio.NioSocketAcceptor; 8 | import org.grain.log.ILog; 9 | 10 | public class MinaServer { 11 | private static IoAcceptor ioAcceptor; 12 | 13 | /** 14 | * 初始化tcp服务器 15 | * 16 | * @param ip 17 | * 监听ip 0.0.0.0最好 18 | * @param port 19 | * 监听端口 20 | * @param HandlerClass 21 | * 继承MinaHandler的类 22 | * @param useTcpMonitor 23 | * 是否输出监控日志 24 | * @param log 25 | * 日志可以为null 26 | * @throws Throwable 27 | */ 28 | public static void init(String ip, int port, Class HandlerClass, boolean useTcpMonitor, ILog log) throws Exception { 29 | MinaConfig.USE_TCP_MONITOR = useTcpMonitor; 30 | MinaConfig.log = log; 31 | // 初始化 32 | ioAcceptor = new NioSocketAcceptor(); 33 | // 设置编码解码 34 | ioAcceptor.getFilterChain().addLast("codec", new ProtocolCodecFilter(new MinaEncoder(), new MinaDecoder())); 35 | // 设置处理函数实现IoHandler接口 36 | MinaHandler minaHandler = (MinaHandler) HandlerClass.newInstance(); 37 | ioAcceptor.setHandler(minaHandler); 38 | // 绑定ip地址与端口 39 | ioAcceptor.bind(new InetSocketAddress(ip, port)); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /tcp/src/main/java/org/grain/tcp/MinaServerHandler.java: -------------------------------------------------------------------------------- 1 | package org.grain.tcp; 2 | 3 | import org.apache.mina.core.session.IoSession; 4 | import org.grain.msg.MsgManager; 5 | 6 | public class MinaServerHandler extends MinaHandler { 7 | 8 | @Override 9 | public void messageReceived(IoSession session, Object message) throws Exception { 10 | super.messageReceived(session, message); 11 | if (MinaConfig.log != null) { 12 | MinaConfig.log.info("minaserver messageReceived"); 13 | } 14 | TcpManager.dispatchTcp((TcpPacket) message); 15 | } 16 | 17 | @Override 18 | public void sessionClosed(IoSession session) throws Exception { 19 | super.sessionClosed(session); 20 | if (MinaConfig.log != null) { 21 | MinaConfig.log.warn("minaserver sessionClosed"); 22 | } 23 | MsgManager.dispatchMsg(TcpMsg.MINA_CLIENT_DISCONNECT, null, session); 24 | } 25 | 26 | @Override 27 | public void sessionCreated(IoSession session) throws Exception { 28 | super.sessionCreated(session); 29 | if (MinaConfig.log != null) { 30 | MinaConfig.log.info("minaserver sessionCreated"); 31 | } 32 | MsgManager.dispatchMsg(TcpMsg.MINA_CLIENT_CREATE_CONNECT, null, session); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /tcp/src/main/java/org/grain/tcp/TcpMsg.java: -------------------------------------------------------------------------------- 1 | package org.grain.tcp; 2 | 3 | public class TcpMsg { 4 | public static String MINA_SERVER_CONNECTED = "MINA_SERVER_CONNECTED"; 5 | public static String MINA_SERVER_DISCONNECT = "MINA_SERVER_DISCONNECT"; 6 | public static String MINA_CLIENT_CREATE_CONNECT = "MINA_CLIENT_CREATE_CONNECT"; 7 | public static String MINA_CLIENT_DISCONNECT = "MINA_CLIENT_DISCONNECT"; 8 | } 9 | -------------------------------------------------------------------------------- /tcp/src/main/java/org/grain/tcp/TcpPacket.java: -------------------------------------------------------------------------------- 1 | package org.grain.tcp; 2 | 3 | import org.grain.log.RunMonitor; 4 | 5 | import com.google.protobuf.Message; 6 | 7 | public class TcpPacket { 8 | private int tOpCode; 9 | public int lockedId = 0; 10 | public int unlockedId = 0; 11 | private Message data; 12 | public Object session; 13 | public RunMonitor runMonitor; 14 | 15 | /** 16 | * 17 | * @param tOpCode 18 | * 操作码 19 | * @param data 20 | * 数据 21 | * @param useTcpMonitor 22 | * 是否打开监控 23 | */ 24 | public TcpPacket(int tOpCode, Message data, boolean useTcpMonitor) { 25 | this.tOpCode = tOpCode; 26 | this.data = data; 27 | if (useTcpMonitor) { 28 | runMonitor = new RunMonitor("TCP", String.valueOf(this.tOpCode)); 29 | putMonitor("解析完Tcp包"); 30 | } 31 | } 32 | 33 | /** 34 | * 35 | * @param tOpCode 36 | * 操作码 37 | * @param data 38 | * 数据 39 | */ 40 | public TcpPacket(int tOpCode, Message data) { 41 | this.tOpCode = tOpCode; 42 | this.data = data; 43 | 44 | } 45 | 46 | /** 47 | * 增加监控内容 48 | * 49 | * @param content 50 | * 内容 51 | */ 52 | public void putMonitor(String content) { 53 | if (runMonitor != null) { 54 | runMonitor.putMonitor(content); 55 | } 56 | } 57 | 58 | /** 59 | * 打开监控日志 60 | */ 61 | public void openRunMonitor() { 62 | if (runMonitor == null) { 63 | runMonitor = new RunMonitor("TCP", String.valueOf(this.tOpCode)); 64 | } 65 | } 66 | 67 | /** 68 | * 清理 69 | */ 70 | public void clear() { 71 | data = null; 72 | session = null; 73 | runMonitor = null; 74 | } 75 | 76 | public int gettOpCode() { 77 | return tOpCode; 78 | } 79 | 80 | public void settOpCode(int tOpCode) { 81 | this.tOpCode = tOpCode; 82 | } 83 | 84 | public Message getData() { 85 | return data; 86 | } 87 | 88 | public void setData(Message data) { 89 | this.data = data; 90 | } 91 | 92 | /** 93 | * 获取二进制数据 94 | * 95 | * @return byte[] 96 | */ 97 | public byte[] getByteData() { 98 | return this.data.toByteArray(); 99 | } 100 | 101 | } 102 | -------------------------------------------------------------------------------- /thread.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dianbaer/grain/6dabee1f6ac4a9c845416057babdc0d059363f7f/thread.png -------------------------------------------------------------------------------- /thread.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dianbaer/grain/6dabee1f6ac4a9c845416057babdc0d059363f7f/thread.pptx -------------------------------------------------------------------------------- /thread/.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | .classpath 3 | .project 4 | .settings 5 | logs 6 | .idea 7 | *.iml 8 | dist -------------------------------------------------------------------------------- /thread/build-thread.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /thread/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | com.github.dianbaer 6 | grain 7 | 1.0.0 8 | 9 | thread 10 | thread 11 | thread 12 | 13 | 1.8 14 | 1.8 15 | UTF-8 16 | 17 | 18 | 19 | com.github.dianbaer 20 | log 21 | 1.0.0 22 | 23 | 24 | -------------------------------------------------------------------------------- /thread/src/main/java/org/grain/thread/AsyncHandleData.java: -------------------------------------------------------------------------------- 1 | package org.grain.thread; 2 | 3 | import java.util.ArrayList; 4 | import java.util.concurrent.LinkedBlockingQueue; 5 | 6 | public class AsyncHandleData { 7 | /** 8 | * 等待的处理队列 9 | */ 10 | public LinkedBlockingQueue waitHandleQueue = new LinkedBlockingQueue(); 11 | /** 12 | * 帮助类,减少垃圾回收 13 | */ 14 | private ArrayList handleArray = new ArrayList(); 15 | /** 16 | * 轮训队列 17 | */ 18 | public ArrayList cycleArray = new ArrayList(); 19 | /** 20 | * 等待加入的轮训队列 21 | */ 22 | public LinkedBlockingQueue waitAddCycleQueue = new LinkedBlockingQueue(); 23 | /** 24 | * 帮助类,减少垃圾回收 25 | */ 26 | private ArrayList addCycleArray = new ArrayList(); 27 | /** 28 | * 等待移除的轮训队列 29 | */ 30 | public LinkedBlockingQueue waitRemoveCycleQueue = new LinkedBlockingQueue(); 31 | /** 32 | * 帮助类,减少垃圾回收 33 | */ 34 | private ArrayList removeCycleArray = new ArrayList(); 35 | 36 | /** 37 | * 获取本次轮训处理的数组 38 | * 39 | * @return 40 | */ 41 | public ArrayList getHandleArray() { 42 | handleArray.clear(); 43 | waitHandleQueue.drainTo(handleArray); 44 | return handleArray; 45 | } 46 | 47 | /** 48 | * 获取本次轮训处理的加入轮训 49 | * 50 | * @return 51 | */ 52 | public ArrayList getAddCycleArray() { 53 | addCycleArray.clear(); 54 | waitAddCycleQueue.drainTo(addCycleArray); 55 | return addCycleArray; 56 | } 57 | 58 | /** 59 | * 获取本次轮训处理的移除轮训 60 | * 61 | * @return 62 | */ 63 | public ArrayList getRemoveCycleArray() { 64 | removeCycleArray.clear(); 65 | waitRemoveCycleQueue.drainTo(removeCycleArray); 66 | return removeCycleArray; 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /thread/src/main/java/org/grain/thread/ICycle.java: -------------------------------------------------------------------------------- 1 | package org.grain.thread; 2 | 3 | public interface ICycle { 4 | /** 5 | * 每次轮训的业务 6 | * 7 | * @throws Exception 8 | */ 9 | public void cycle() throws Exception; 10 | 11 | /** 12 | * 加入动作的业务 13 | * 14 | * @throws Exception 15 | */ 16 | public void onAdd() throws Exception; 17 | 18 | /** 19 | * 移除动作的业务 20 | * 21 | * @throws Exception 22 | */ 23 | public void onRemove() throws Exception; 24 | } 25 | -------------------------------------------------------------------------------- /thread/src/main/java/org/grain/thread/IHandle.java: -------------------------------------------------------------------------------- 1 | package org.grain.thread; 2 | 3 | import java.lang.reflect.Method; 4 | 5 | public interface IHandle { 6 | /** 7 | * 消息包 8 | * 9 | * @return 10 | */ 11 | public Object getPacket(); 12 | 13 | /** 14 | * 处理消息包的方法 15 | * 16 | * @return 17 | */ 18 | public Method getMethod(); 19 | 20 | /** 21 | * 处理消息包方法的实例对象 22 | * 23 | * @return 24 | */ 25 | public Object getInstance(); 26 | } 27 | -------------------------------------------------------------------------------- /thread/src/main/java/org/grain/thread/ThreadHandle.java: -------------------------------------------------------------------------------- 1 | package org.grain.thread; 2 | 3 | import java.lang.reflect.Method; 4 | 5 | public class ThreadHandle implements IHandle { 6 | private Object packet; 7 | private Method method; 8 | private Object instance; 9 | 10 | /** 11 | * 12 | * @param packet 13 | * 消息包 14 | * @param method 15 | * 回调方法 16 | * @param instance 17 | * 回调实例对象,为null则是说明是静态方法 18 | */ 19 | public ThreadHandle(Object packet, Method method, Object instance) { 20 | this.packet = packet; 21 | this.method = method; 22 | this.instance = instance; 23 | } 24 | 25 | @Override 26 | public Object getPacket() { 27 | return packet; 28 | } 29 | 30 | @Override 31 | public Method getMethod() { 32 | return method; 33 | } 34 | 35 | @Override 36 | public Object getInstance() { 37 | return instance; 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /thread/src/test/java/org/grain/thread/AsyncThreadManagerTest.java: -------------------------------------------------------------------------------- 1 | package org.grain.thread; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | 5 | import java.lang.reflect.Method; 6 | 7 | import org.junit.BeforeClass; 8 | import org.junit.Test; 9 | 10 | public class AsyncThreadManagerTest { 11 | 12 | @BeforeClass 13 | public static void setUpBeforeClass() throws Exception { 14 | AsyncThreadManager.init(100, 10, 3, 0, null); 15 | AsyncThreadManager.start(); 16 | } 17 | 18 | @Test 19 | public void testAddHandle() throws NoSuchMethodException, SecurityException, InterruptedException { 20 | PacketTest packetTest = new PacketTest(); 21 | Method method = HandlerManagerTest.class.getMethod("handle", new Class[] { Object.class }); 22 | ThreadHandle threadHandle = new ThreadHandle(packetTest, method, null); 23 | boolean result = AsyncThreadManager.addHandle(threadHandle, 1, 1); 24 | Thread.sleep(1000); 25 | assertEquals(true, result); 26 | } 27 | 28 | @Test 29 | public void testAddCycle() { 30 | CycleTest cycleTest = new CycleTest(); 31 | cycleTest.name = "testAddCycle"; 32 | boolean result = AsyncThreadManager.addCycle(cycleTest, 1, 1); 33 | assertEquals(true, result); 34 | } 35 | 36 | @Test 37 | public void testRemoveCycle() { 38 | CycleTest cycleTest = new CycleTest(); 39 | cycleTest.name = "testRemoveCycle"; 40 | boolean result = AsyncThreadManager.addCycle(cycleTest, 1, 1); 41 | result = AsyncThreadManager.removeCycle(cycleTest, 1, 1); 42 | assertEquals(true, result); 43 | } 44 | 45 | @Test 46 | public void testGetRandomThreadPriority() { 47 | int[] threadPriority = AsyncThreadManager.getRandomThreadPriority(); 48 | assertEquals(true, threadPriority != null); 49 | } 50 | 51 | @Test 52 | public void testGetRandomThread() { 53 | int[] threadPriority = AsyncThreadManager.getRandomThread(); 54 | assertEquals(true, threadPriority != null); 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /thread/src/test/java/org/grain/thread/CycleTest.java: -------------------------------------------------------------------------------- 1 | package org.grain.thread; 2 | 3 | public class CycleTest implements ICycle { 4 | public String name; 5 | 6 | @Override 7 | public void cycle() throws Exception { 8 | System.out.println(name + "业务轮训,线程:" + Thread.currentThread().getName()); 9 | } 10 | 11 | @Override 12 | public void onAdd() throws Exception { 13 | System.out.println(name + "加入动作,线程:" + Thread.currentThread().getName()); 14 | } 15 | 16 | @Override 17 | public void onRemove() throws Exception { 18 | System.out.println(name + "离开动作,线程:" + Thread.currentThread().getName()); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /thread/src/test/java/org/grain/thread/HandlerManagerTest.java: -------------------------------------------------------------------------------- 1 | package org.grain.thread; 2 | 3 | public class HandlerManagerTest { 4 | 5 | public static void handle(Object packet) { 6 | System.out.println("HandlerManagerTest.handle,线程:" + Thread.currentThread().getName()); 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /thread/src/test/java/org/grain/thread/PacketTest.java: -------------------------------------------------------------------------------- 1 | package org.grain.thread; 2 | 3 | public class PacketTest { 4 | public PacketTest() { 5 | 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /threadkeylock/.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | .classpath 3 | .project 4 | .settings 5 | logs 6 | .idea 7 | *.iml 8 | dist -------------------------------------------------------------------------------- /threadkeylock/build-threadkeylock.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /threadkeylock/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | com.github.dianbaer 6 | grain 7 | 1.0.0 8 | 9 | threadkeylock 10 | threadkeylock 11 | threadkeylock 12 | 13 | 1.8 14 | 1.8 15 | UTF-8 16 | 17 | 18 | 19 | com.github.dianbaer 20 | log 21 | 1.0.0 22 | 23 | 24 | -------------------------------------------------------------------------------- /threadkeylock/src/main/java/org/grain/threadkeylock/KeyLockException.java: -------------------------------------------------------------------------------- 1 | package org.grain.threadkeylock; 2 | 3 | public class KeyLockException extends Exception { 4 | 5 | private static final long serialVersionUID = 1L; 6 | 7 | public KeyLockException(String message) { 8 | super(message); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /threadkeylock/src/main/java/org/grain/threadkeylock/KeylockFunction.java: -------------------------------------------------------------------------------- 1 | package org.grain.threadkeylock; 2 | 3 | @FunctionalInterface 4 | public interface KeylockFunction { 5 | public Object apply(Object... params); 6 | } 7 | -------------------------------------------------------------------------------- /threadmsg/.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | .classpath 3 | .project 4 | .settings 5 | logs 6 | .idea 7 | *.iml 8 | dist -------------------------------------------------------------------------------- /threadmsg/README.md: -------------------------------------------------------------------------------- 1 | # grain-threadmsg 2 | 3 | ## grain-threadmsg 通用消息与通用线程整合,可以进行异步线程消息分发处理 4 | 5 | 6 | 此项目依赖 7 | 8 | grain-log 9 | grain-thread 10 | grain-msg 11 | 12 | 使用 13 | 14 | 1、初始化线程和消息 15 | 16 | AsyncThreadManager.init(100, 10, 3, 0, null); 17 | AsyncThreadManager.start(); 18 | MsgManager.init(true, null); 19 | 20 | 2、初始化操作码归属线程优先级,如果不初始化则随机选线程和优先级 21 | 22 | ThreadMsgManager.addMapping("createuser", new int[] { 1, 1 }); 23 | 24 | 3、实现IMsgListener接口并放入监听 25 | 26 | TestThreadMsgListener---实现IMsgListener的类 27 | 28 | package org.grain.threadmsg; 29 | import java.util.HashMap; 30 | import java.util.Map; 31 | import org.grain.msg.IMsgListener; 32 | import org.grain.msg.MsgPacket; 33 | public class TestThreadMsgListener implements IMsgListener { 34 | @Override 35 | public Map getMsgs() throws Exception { 36 | HashMap map = new HashMap<>(); 37 | map.put("createuser", "createUserHandle"); 38 | map.put("updateuser", "updateUserHandle"); 39 | return map; 40 | } 41 | public void createUserHandle(MsgPacket msgPacket) { 42 | System.out.println("createUserHandle接到消息:" + msgPacket.getMsgOpCode()); 43 | } 44 | public void updateUserHandle(MsgPacket msgPacket) { 45 | System.out.println("updateUserHandle接到消息:" + msgPacket.getMsgOpCode()); 46 | } 47 | } 48 | 49 | 50 | 放入监听,关注消息 51 | 52 | TestThreadMsgListener testThreadMsgListener = new TestThreadMsgListener(); 53 | MsgManager.addMsgListener(testThreadMsgListener); 54 | 55 | 4、发布消息,进行关注消息推送至异步线程,异步线程进行关注消息函数回调 56 | 57 | ThreadMsgManager.dispatchThreadMsg("createuser", 111, 222); 58 | ThreadMsgManager.dispatchThreadMsg("updateuser", 111, 222); 59 | 60 | -------------------------------------------------------------------------------- /threadmsg/build-threadmsg.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /threadmsg/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | com.github.dianbaer 6 | grain 7 | 1.0.0 8 | 9 | threadmsg 10 | threadmsg 11 | threadmsg 12 | 13 | 1.8 14 | 1.8 15 | UTF-8 16 | 17 | 18 | 19 | com.github.dianbaer 20 | thread 21 | 1.0.0 22 | 23 | 24 | com.github.dianbaer 25 | msg 26 | 1.0.0 27 | 28 | 29 | -------------------------------------------------------------------------------- /threadmsg/src/main/java/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Class-Path: 3 | 4 | -------------------------------------------------------------------------------- /threadmsg/src/main/java/org/grain/threadmsg/ThreadMsgManager.java: -------------------------------------------------------------------------------- 1 | package org.grain.threadmsg; 2 | 3 | import java.util.HashMap; 4 | 5 | import org.grain.msg.MsgManager; 6 | import org.grain.msg.MsgPacket; 7 | import org.grain.thread.AsyncThreadManager; 8 | import org.grain.thread.ThreadHandle; 9 | 10 | public class ThreadMsgManager { 11 | /** 12 | * 操作类型属于哪个线程哪个优先级,为空算作随机 13 | */ 14 | public static HashMap msgOpcodeType = new HashMap(); 15 | 16 | /** 17 | * 添加操作码与线程优先级的映射 18 | * 19 | * @param msgOpCode 20 | * 操作码 21 | * @param threadPriority 22 | * 线程优先级 可以为null 23 | */ 24 | public static boolean addMapping(String msgOpCode, int[] threadPriority) { 25 | if (msgOpcodeType.containsKey(msgOpCode)) { 26 | return false; 27 | } 28 | if (threadPriority != null) { 29 | msgOpcodeType.put(msgOpCode, threadPriority); 30 | } 31 | return true; 32 | } 33 | 34 | /** 35 | * 发布消息,推送至异步线程 36 | * 37 | * @param msgOpCode 38 | * 消息操作码 39 | * @param data 40 | * 可序列化数据 41 | * @param otherData 42 | * 其他数据 43 | * @return 44 | */ 45 | public static boolean dispatchThreadMsg(String msgOpCode, Object data, Object otherData) { 46 | // 消息未被注册过,不能发送 47 | if (!MsgManager.msgListenerMap.containsKey(msgOpCode)) { 48 | if (MsgManager.log != null) { 49 | MsgManager.log.warn("消息类型:" + msgOpCode + ",不存在,无法注册"); 50 | } 51 | return false; 52 | } 53 | // 创建消息包 54 | MsgPacket msgPacket = new MsgPacket(msgOpCode, data, otherData, MsgManager.USE_MSG_MONITOR); 55 | // 获取归属线程和优先级,如果为空则随机一个 56 | int[] msgTypeArray = msgOpcodeType.get(msgPacket.getMsgOpCode()); 57 | if (msgTypeArray == null || msgTypeArray.length != 2) { 58 | msgTypeArray = AsyncThreadManager.getRandomThreadPriority(); 59 | } 60 | msgPacket.putMonitor("分发至线程:" + msgTypeArray[0] + ",优先级:" + msgTypeArray[1]); 61 | // 初始化回调函数 62 | 63 | ThreadHandle threadHandle = new ThreadHandle(msgPacket, MsgManager.method, null); 64 | // 加入异步线程 65 | boolean result = AsyncThreadManager.addHandle(threadHandle, msgTypeArray[0], msgTypeArray[1]); 66 | return result; 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /threadmsg/src/test/java/org/grain/threadmsg/TestThreadMsgListener.java: -------------------------------------------------------------------------------- 1 | package org.grain.threadmsg; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | import org.grain.msg.IMsgListener; 7 | import org.grain.msg.MsgPacket; 8 | 9 | public class TestThreadMsgListener implements IMsgListener { 10 | 11 | @Override 12 | public Map getMsgs() throws Exception { 13 | HashMap map = new HashMap<>(); 14 | map.put("createuser", "createUserHandle"); 15 | map.put("updateuser", "updateUserHandle"); 16 | return map; 17 | } 18 | 19 | public void createUserHandle(MsgPacket msgPacket) { 20 | System.out.println("createUserHandle接到消息:" + msgPacket.getMsgOpCode()); 21 | } 22 | 23 | public void updateUserHandle(MsgPacket msgPacket) { 24 | System.out.println("updateUserHandle接到消息:" + msgPacket.getMsgOpCode()); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /threadmsg/src/test/java/org/grain/threadmsg/ThreadMsgManagerTest.java: -------------------------------------------------------------------------------- 1 | package org.grain.threadmsg; 2 | 3 | import org.grain.msg.MsgManager; 4 | import org.grain.thread.AsyncThreadManager; 5 | import org.junit.BeforeClass; 6 | import org.junit.Test; 7 | 8 | public class ThreadMsgManagerTest { 9 | 10 | @BeforeClass 11 | public static void setUpBeforeClass() throws Exception { 12 | AsyncThreadManager.init(100, 10, 3, 0, null); 13 | AsyncThreadManager.start(); 14 | MsgManager.init(true, null); 15 | ThreadMsgManager.addMapping("createuser", new int[] { 1, 1 }); 16 | TestThreadMsgListener testThreadMsgListener = new TestThreadMsgListener(); 17 | MsgManager.addMsgListener(testThreadMsgListener); 18 | } 19 | 20 | @Test 21 | public void testAddMapping() throws InterruptedException { 22 | ThreadMsgManager.dispatchThreadMsg("createuser", 111, 222); 23 | ThreadMsgManager.dispatchThreadMsg("updateuser", 111, 222); 24 | Thread.sleep(1000); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /threadwebsocket-test/.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | .classpath 3 | .project 4 | .settings 5 | logs 6 | .idea 7 | *.iml 8 | dist -------------------------------------------------------------------------------- /threadwebsocket-test/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | com.github.dianbaer 6 | grain 7 | 1.0.0 8 | 9 | threadwebsocket-test 10 | war 11 | threadwebsocket-test 12 | threadwebsocket-test 13 | 14 | 1.8 15 | 1.8 16 | UTF-8 17 | 18 | 19 | 20 | com.github.dianbaer 21 | threadwebsocket 22 | 1.0.0 23 | 24 | 25 | org.slf4j 26 | slf4j-log4j12 27 | 1.7.22 28 | 29 | 30 | javax.websocket 31 | javax.websocket-api 32 | 1.1 33 | 34 | 35 | javax.servlet 36 | javax.servlet-api 37 | 3.1.0 38 | 39 | 40 | -------------------------------------------------------------------------------- /threadwebsocket-test/protobuf/Test.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package protobuf.ws; 3 | message TestC{ 4 | string wsOpCode=1; 5 | string msg=2; 6 | } 7 | message TestS{ 8 | string wsOpCode=1; 9 | string msg=2; 10 | } -------------------------------------------------------------------------------- /threadwebsocket-test/protobuf/protobuf编译.bat: -------------------------------------------------------------------------------- 1 | C: 2 | cd C:\Users\admin\Desktop\github\grain\trunk\grain-websocket-test\protobuf 3 | protoc --java_out=./ Test.proto 4 | -------------------------------------------------------------------------------- /threadwebsocket-test/protobuf/protoc.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dianbaer/grain/6dabee1f6ac4a9c845416057babdc0d059363f7f/threadwebsocket-test/protobuf/protoc.exe -------------------------------------------------------------------------------- /threadwebsocket-test/src/main/java/init/InitServlet.java: -------------------------------------------------------------------------------- 1 | package init; 2 | 3 | import javax.servlet.ServletException; 4 | import javax.servlet.http.HttpServlet; 5 | 6 | import org.grain.msg.MsgManager; 7 | import org.grain.thread.AsyncThreadManager; 8 | import org.grain.threadwebsocket.ThreadWSManager; 9 | import org.grain.websokcetlib.WSManager; 10 | import org.slf4j.LoggerFactory; 11 | 12 | import protobuf.ws.Test.TestC; 13 | import protobuf.ws.Test.TestS; 14 | import test.GrainLog; 15 | import test.TestWSService; 16 | 17 | public class InitServlet extends HttpServlet { 18 | 19 | /** 20 | * 21 | */ 22 | private static final long serialVersionUID = 1L; 23 | 24 | @Override 25 | public void init() throws ServletException { 26 | // TODO Auto-generated method stub 27 | super.init(); 28 | 29 | try { 30 | GrainLog grainLog = new GrainLog(LoggerFactory.getLogger("minaLog")); 31 | GrainLog grainLog1 = new GrainLog(LoggerFactory.getLogger("msgLog")); 32 | // 初始化线程消息 33 | AsyncThreadManager.init(100, 10, 3, 0, grainLog1); 34 | AsyncThreadManager.start(); 35 | MsgManager.init(true, grainLog1); 36 | WSManager.init(grainLog1); 37 | // 映射操作码解析类,如果不设置线程优先级则随机线程优先级 38 | ThreadWSManager.addThreadMapping("testc", TestC.class, new int[] { 2, 1 }); 39 | ThreadWSManager.addThreadMapping("tests", TestS.class, null); 40 | 41 | // 注册tcp回调函数 42 | TestWSService testWSService = new TestWSService(); 43 | WSManager.addWSListener(testWSService); 44 | 45 | } catch (Exception e) { 46 | // TODO: handle exception 47 | } 48 | 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /threadwebsocket-test/src/main/java/log/MyAppender.java: -------------------------------------------------------------------------------- 1 | package log; 2 | 3 | import org.apache.log4j.DailyRollingFileAppender; 4 | import org.apache.log4j.Priority; 5 | 6 | public class MyAppender extends DailyRollingFileAppender { 7 | @Override 8 | public boolean isAsSevereAsThreshold(Priority priority) { 9 | return this.getThreshold().equals(priority); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /threadwebsocket-test/src/main/java/test/GrainLog.java: -------------------------------------------------------------------------------- 1 | package test; 2 | 3 | import org.grain.log.ILog; 4 | import org.slf4j.Logger; 5 | 6 | public class GrainLog implements ILog { 7 | private Logger log; 8 | 9 | public GrainLog(Logger log) { 10 | this.log = log; 11 | } 12 | 13 | @Override 14 | public void warn(String warn) { 15 | this.log.warn(warn); 16 | 17 | } 18 | 19 | @Override 20 | public void error(String error, Throwable e) { 21 | this.log.error(error, e); 22 | 23 | } 24 | 25 | @Override 26 | public void info(String info) { 27 | this.log.info(info); 28 | 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /threadwebsocket-test/src/main/java/test/TestWSService.java: -------------------------------------------------------------------------------- 1 | package test; 2 | 3 | import java.io.IOException; 4 | import java.util.HashMap; 5 | import java.util.Map; 6 | 7 | import javax.websocket.EncodeException; 8 | import javax.websocket.Session; 9 | 10 | import org.grain.websokcetlib.IWSListener; 11 | import org.grain.websokcetlib.WsPacket; 12 | 13 | import protobuf.ws.Test.TestC; 14 | import protobuf.ws.Test.TestS; 15 | 16 | public class TestWSService implements IWSListener { 17 | 18 | @Override 19 | public Map getWSs() throws Exception { 20 | HashMap map = new HashMap<>(); 21 | map.put("testc", "onTestC"); 22 | return map; 23 | } 24 | 25 | public void onTestC(WsPacket wsPacket) throws IOException, EncodeException { 26 | TestC testc = (TestC) wsPacket.getData(); 27 | wsPacket.putMonitor("接到客户端发来的消息:" + testc.getMsg()); 28 | TestS.Builder tests = TestS.newBuilder(); 29 | tests.setWsOpCode("tests"); 30 | tests.setMsg("你好客户端,我是服务器"); 31 | WsPacket pt = new WsPacket("tests", tests.build()); 32 | Session session = (Session) wsPacket.session; 33 | session.getBasicRemote().sendObject(pt); 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /threadwebsocket-test/src/main/webapp/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Class-Path: 3 | 4 | -------------------------------------------------------------------------------- /threadwebsocket-test/src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | grain-websocket-test 7 | 8 | InitServlet 9 | init.InitServlet 10 | 0 11 | 12 | 13 | index.html 14 | index.htm 15 | index.jsp 16 | default.html 17 | default.htm 18 | default.jsp 19 | 20 | -------------------------------------------------------------------------------- /threadwebsocket-test/src/main/webapp/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Title 6 | 7 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /threadwebsocket/.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | .classpath 3 | .project 4 | .settings 5 | logs 6 | .idea 7 | *.iml 8 | dist -------------------------------------------------------------------------------- /threadwebsocket/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | com.github.dianbaer 6 | grain 7 | 1.0.0 8 | 9 | threadwebsocket 10 | threadwebsocket 11 | threadwebsocket 12 | 13 | 1.8 14 | 1.8 15 | UTF-8 16 | 17 | 18 | 19 | com.github.dianbaer 20 | websocket-lib 21 | 1.0.0 22 | 23 | 24 | com.github.dianbaer 25 | threadmsg 26 | 1.0.0 27 | 28 | 29 | javax.websocket 30 | javax.websocket-api 31 | 1.1 32 | provided 33 | 34 | 35 | -------------------------------------------------------------------------------- /threadwebsocket/src/main/java/org/grain/threadwebsocket/ThreadWSManager.java: -------------------------------------------------------------------------------- 1 | package org.grain.threadwebsocket; 2 | 3 | import java.util.HashMap; 4 | 5 | import org.grain.thread.AsyncThreadManager; 6 | import org.grain.thread.ThreadHandle; 7 | import org.grain.websokcetlib.WSManager; 8 | import org.grain.websokcetlib.WsPacket; 9 | 10 | public class ThreadWSManager { 11 | public static HashMap wsOpCodeType = new HashMap(); 12 | 13 | /** 14 | * 注册操作码与映射类和线程优先级的映射 15 | * 16 | * @param wsOpCode 17 | * 操作码 18 | * @param clazz 19 | * 映射类 20 | * @param threadPriority 21 | * 线程优先级,传空说明随机线程 22 | * @return 23 | */ 24 | public static boolean addThreadMapping(String wsOpCode, Class clazz, int[] threadPriority) { 25 | if (WSManager.wsOpCodeMap.containsKey(wsOpCode) || wsOpCodeType.containsKey(wsOpCode)) { 26 | return false; 27 | } 28 | WSManager.wsOpCodeMap.put(wsOpCode, clazz); 29 | if (threadPriority != null) { 30 | wsOpCodeType.put(wsOpCode, threadPriority); 31 | } 32 | return true; 33 | } 34 | 35 | /** 36 | * 将消息包分发到系统多线程模型进行处理 37 | * 38 | * @param wsPacket 39 | * @return 40 | */ 41 | public static boolean dispatchWS(WsPacket wsPacket) { 42 | if (wsPacket == null) { 43 | if (WSManager.log != null) { 44 | WSManager.log.warn("派发ws包为空"); 45 | } 46 | return false; 47 | } 48 | wsPacket.openRunMonitor(); 49 | int[] wsTypeArray = wsOpCodeType.get(wsPacket.getWsOpCode()); 50 | 51 | if (wsTypeArray == null || wsTypeArray.length != 2) { 52 | wsTypeArray = AsyncThreadManager.getRandomThreadPriority(); 53 | } 54 | 55 | wsPacket.putMonitor("分发至线程:" + wsTypeArray[0] + ",优先级:" + wsTypeArray[1]); 56 | 57 | ThreadHandle threadHandle = new ThreadHandle(wsPacket, WSManager.method, null); 58 | 59 | boolean result = AsyncThreadManager.addHandle(threadHandle, wsTypeArray[0], wsTypeArray[1]); 60 | return result; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /threadwebsocket/src/main/java/org/grain/threadwebsocket/WebSocketServer.java: -------------------------------------------------------------------------------- 1 | package org.grain.threadwebsocket; 2 | 3 | import javax.websocket.CloseReason; 4 | import javax.websocket.OnClose; 5 | import javax.websocket.OnMessage; 6 | import javax.websocket.OnOpen; 7 | import javax.websocket.Session; 8 | import javax.websocket.server.ServerEndpoint; 9 | 10 | import org.grain.threadmsg.ThreadMsgManager; 11 | import org.grain.websokcetlib.WSManager; 12 | import org.grain.websokcetlib.WSMsg; 13 | import org.grain.websokcetlib.WebSocketDeCoder; 14 | import org.grain.websokcetlib.WebSocketEnCoder; 15 | import org.grain.websokcetlib.WsPacket; 16 | 17 | @ServerEndpoint(value = "/ws", decoders = { WebSocketDeCoder.class }, encoders = { WebSocketEnCoder.class }) 18 | public class WebSocketServer { 19 | @OnOpen 20 | public void onOpen(Session session) { 21 | 22 | try { 23 | ThreadMsgManager.dispatchThreadMsg(WSMsg.WEBSOCKET_CLIENT_CREATE_CONNECT, null, session); 24 | } catch (Exception e) { 25 | if (WSManager.log != null) { 26 | WSManager.log.error("MsgManager.dispatchMsg error", e); 27 | } 28 | } 29 | } 30 | 31 | @OnMessage 32 | public void onMessage(Session session, WsPacket wsPacket) { 33 | wsPacket.session = session; 34 | ThreadWSManager.dispatchWS(wsPacket); 35 | } 36 | 37 | @OnClose 38 | public void onClose(Session session, CloseReason closeReason) { 39 | try { 40 | ThreadMsgManager.dispatchThreadMsg(WSMsg.WEBSOCKET_CLIENT_DISCONNECT, null, session); 41 | } catch (Exception e) { 42 | if (WSManager.log != null) { 43 | WSManager.log.error("MsgManager.dispatchMsg error", e); 44 | } 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /websocket-lib/.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | .classpath 3 | .project 4 | .settings 5 | logs 6 | .idea 7 | *.iml 8 | dist -------------------------------------------------------------------------------- /websocket-lib/README.md: -------------------------------------------------------------------------------- 1 | # grain-websocket-lib 2 | 3 | grain-websocket-lib 定义了序列化与反序列化,消息包分发等。 4 | 5 | 6 | 此项目依赖 7 | 8 | grain-log 9 | commons-beanutils-1.9.3.jar 10 | commons-collections-3.2.2.jar 11 | commons-lang-2.6.jar 12 | commons-logging-1.2.jar 13 | ezmorph-1.0.6.jar 14 | javax.websocket-api-1.1.jar 15 | json-lib-2.4-jdk15.jar 16 | protobuf-java-3.1.0.jar 17 | protobuf-java-format-1.4.jar 18 | 19 | 使用(不能单独使用) 20 | 21 | 请使用grain-websocket或grain-threadwebsocket 22 | -------------------------------------------------------------------------------- /websocket-lib/build-websocket-lib.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /websocket-lib/src/main/java/org/grain/websokcetlib/IWSListener.java: -------------------------------------------------------------------------------- 1 | package org.grain.websokcetlib; 2 | 3 | import java.util.Map; 4 | 5 | public interface IWSListener { 6 | /** 7 | * 实现此接口,可以进行webscoket关注消息注册,并在接到消息时回调 8 | * 9 | * @return Map 操作码,回调函数名 10 | * @throws Exception 11 | */ 12 | public Map getWSs() throws Exception; 13 | } 14 | -------------------------------------------------------------------------------- /websocket-lib/src/main/java/org/grain/websokcetlib/PacketUtils.java: -------------------------------------------------------------------------------- 1 | package org.grain.websokcetlib; 2 | 3 | import java.io.IOException; 4 | import java.io.InputStream; 5 | 6 | import com.google.protobuf.Message; 7 | import com.google.protobuf.Message.Builder; 8 | import com.googlecode.protobuf.format.JsonFormat; 9 | import com.googlecode.protobuf.format.util.TextUtils; 10 | 11 | public class PacketUtils { 12 | public static JsonFormat jsonFormat = new JsonFormat(); 13 | 14 | /** 15 | * json字符串转protobuf 16 | * 17 | * @param jsonStr 18 | * json字符串 19 | * @param builder 20 | * 解析类 21 | * @return 22 | */ 23 | public static Message jsonToProtoBuf(String jsonStr, Builder builder) { 24 | InputStream inputStream = null; 25 | try { 26 | inputStream = TextUtils.toInputStream(jsonStr); 27 | jsonFormat.merge(inputStream, builder); 28 | Message message = builder.build(); 29 | return message; 30 | } catch (Exception e) { 31 | if (WSManager.log != null) { 32 | WSManager.log.error("json转换成protobuf,异常", e); 33 | } 34 | return null; 35 | } finally { 36 | if (inputStream != null) { 37 | try { 38 | inputStream.close(); 39 | } catch (IOException e) { 40 | if (WSManager.log != null) { 41 | WSManager.log.error("json转换成protobuf,关闭输入流失败", e); 42 | } 43 | } 44 | } 45 | } 46 | 47 | } 48 | 49 | /** 50 | * protobuf转json字符串 51 | * 52 | * @param message 53 | * @return 54 | */ 55 | public static String protoBufToJson(Message message) { 56 | return jsonFormat.printToString(message); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /websocket-lib/src/main/java/org/grain/websokcetlib/WSMsg.java: -------------------------------------------------------------------------------- 1 | package org.grain.websokcetlib; 2 | 3 | public class WSMsg { 4 | public static String WEBSOCKET_CLIENT_CREATE_CONNECT = "WEBSOCKET_CLIENT_CREATE_CONNECT"; 5 | public static String WEBSOCKET_CLIENT_DISCONNECT = "WEBSOCKET_CLIENT_DISCONNECT"; 6 | } 7 | -------------------------------------------------------------------------------- /websocket-lib/src/main/java/org/grain/websokcetlib/WebSocketDeCoder.java: -------------------------------------------------------------------------------- 1 | package org.grain.websokcetlib; 2 | 3 | import java.nio.ByteBuffer; 4 | 5 | import javax.websocket.DecodeException; 6 | import javax.websocket.Decoder; 7 | import javax.websocket.EndpointConfig; 8 | 9 | public class WebSocketDeCoder implements Decoder.Binary { 10 | 11 | @Override 12 | public void destroy() { 13 | 14 | } 15 | 16 | @Override 17 | public void init(EndpointConfig arg0) { 18 | 19 | } 20 | 21 | @Override 22 | public WsPacket decode(ByteBuffer arg0) throws DecodeException { 23 | return WSCodeUtil.decodeJson(arg0); 24 | } 25 | 26 | @Override 27 | public boolean willDecode(ByteBuffer arg0) { 28 | 29 | return true; 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /websocket-lib/src/main/java/org/grain/websokcetlib/WebSocketEnCoder.java: -------------------------------------------------------------------------------- 1 | package org.grain.websokcetlib; 2 | 3 | import javax.websocket.EncodeException; 4 | import javax.websocket.Encoder; 5 | import javax.websocket.EndpointConfig; 6 | 7 | public class WebSocketEnCoder implements Encoder.Text { 8 | 9 | @Override 10 | public void destroy() { 11 | 12 | } 13 | 14 | @Override 15 | public void init(EndpointConfig arg0) { 16 | 17 | } 18 | 19 | @Override 20 | public String encode(WsPacket arg0) throws EncodeException { 21 | return WSCodeUtil.encodeJson(arg0); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /websocket-lib/src/main/java/org/grain/websokcetlib/WsPacket.java: -------------------------------------------------------------------------------- 1 | package org.grain.websokcetlib; 2 | 3 | import org.grain.log.RunMonitor; 4 | 5 | import com.google.protobuf.Message; 6 | 7 | public class WsPacket { 8 | private String wsOpCode; 9 | private Message data; 10 | public Object session; 11 | public RunMonitor runMonitor; 12 | 13 | public WsPacket(String wsOpCode, Message data, boolean useWSMonitor) { 14 | this.wsOpCode = wsOpCode; 15 | this.data = data; 16 | if (useWSMonitor) { 17 | runMonitor = new RunMonitor("WS", this.wsOpCode); 18 | putMonitor("解析完WS包"); 19 | } 20 | } 21 | 22 | public WsPacket(String wsOpCode, Message data) { 23 | this.wsOpCode = wsOpCode; 24 | this.data = data; 25 | } 26 | 27 | public void putMonitor(String content) { 28 | if (runMonitor != null) { 29 | runMonitor.putMonitor(content); 30 | } 31 | } 32 | 33 | public void openRunMonitor() { 34 | if (runMonitor == null) { 35 | runMonitor = new RunMonitor("WS", this.wsOpCode); 36 | } 37 | } 38 | 39 | public String getWsOpCode() { 40 | return wsOpCode; 41 | } 42 | 43 | public void setWsOpCode(String wsOpCode) { 44 | this.wsOpCode = wsOpCode; 45 | } 46 | 47 | public Message getData() { 48 | return data; 49 | } 50 | 51 | public void setData(Message data) { 52 | this.data = data; 53 | } 54 | 55 | public byte[] getByteData() { 56 | return this.data.toByteArray(); 57 | } 58 | 59 | public void clear() { 60 | data = null; 61 | session = null; 62 | runMonitor = null; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /websocket-test/.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | .classpath 3 | .project 4 | .settings 5 | logs 6 | .idea 7 | *.iml 8 | dist -------------------------------------------------------------------------------- /websocket-test/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | com.github.dianbaer 6 | grain 7 | 1.0.0 8 | 9 | websocket-test 10 | war 11 | websocket-test 12 | websocket-test 13 | 14 | 1.8 15 | 1.8 16 | UTF-8 17 | 18 | 19 | 20 | com.github.dianbaer 21 | websocket 22 | 1.0.0 23 | 24 | 25 | 26 | org.slf4j 27 | slf4j-log4j12 28 | 1.7.22 29 | 30 | 31 | javax.websocket 32 | javax.websocket-api 33 | 1.1 34 | 35 | 36 | javax.servlet 37 | javax.servlet-api 38 | 3.1.0 39 | 40 | 41 | -------------------------------------------------------------------------------- /websocket-test/protobuf/Test.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package protobuf.ws; 3 | message TestC{ 4 | string wsOpCode=1; 5 | string msg=2; 6 | } 7 | message TestS{ 8 | string wsOpCode=1; 9 | string msg=2; 10 | } -------------------------------------------------------------------------------- /websocket-test/protobuf/protobuf编译.bat: -------------------------------------------------------------------------------- 1 | C: 2 | cd C:\Users\admin\Desktop\github\grain\trunk\grain-websocket-test\protobuf 3 | protoc --java_out=./ Test.proto 4 | -------------------------------------------------------------------------------- /websocket-test/protobuf/protoc.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dianbaer/grain/6dabee1f6ac4a9c845416057babdc0d059363f7f/websocket-test/protobuf/protoc.exe -------------------------------------------------------------------------------- /websocket-test/src/main/java/init/InitServlet.java: -------------------------------------------------------------------------------- 1 | package init; 2 | 3 | import javax.servlet.ServletException; 4 | import javax.servlet.http.HttpServlet; 5 | 6 | import org.grain.msg.MsgManager; 7 | import org.grain.websokcetlib.WSManager; 8 | import org.slf4j.LoggerFactory; 9 | 10 | import protobuf.ws.Test.TestC; 11 | import protobuf.ws.Test.TestS; 12 | import test.GrainLog; 13 | import test.TestWSService; 14 | 15 | public class InitServlet extends HttpServlet { 16 | 17 | /** 18 | * 19 | */ 20 | private static final long serialVersionUID = 1L; 21 | 22 | @Override 23 | public void init() throws ServletException { 24 | // TODO Auto-generated method stub 25 | super.init(); 26 | 27 | try { 28 | GrainLog grainLog = new GrainLog(LoggerFactory.getLogger("minaLog")); 29 | GrainLog grainLog1 = new GrainLog(LoggerFactory.getLogger("msgLog")); 30 | // 初始化消息 31 | MsgManager.init(true, grainLog1); 32 | WSManager.init(grainLog1); 33 | // 映射操作码解析类 34 | WSManager.addMapping("testc", TestC.class); 35 | WSManager.addMapping("tests", TestS.class); 36 | 37 | // 注册tcp回调函数 38 | TestWSService testWSService = new TestWSService(); 39 | WSManager.addWSListener(testWSService); 40 | 41 | } catch (Exception e) { 42 | // TODO: handle exception 43 | } 44 | 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /websocket-test/src/main/java/log/MyAppender.java: -------------------------------------------------------------------------------- 1 | package log; 2 | 3 | import org.apache.log4j.DailyRollingFileAppender; 4 | import org.apache.log4j.Priority; 5 | 6 | public class MyAppender extends DailyRollingFileAppender { 7 | @Override 8 | public boolean isAsSevereAsThreshold(Priority priority) { 9 | return this.getThreshold().equals(priority); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /websocket-test/src/main/java/test/GrainLog.java: -------------------------------------------------------------------------------- 1 | package test; 2 | 3 | import org.grain.log.ILog; 4 | import org.slf4j.Logger; 5 | 6 | public class GrainLog implements ILog { 7 | private Logger log; 8 | 9 | public GrainLog(Logger log) { 10 | this.log = log; 11 | } 12 | 13 | @Override 14 | public void warn(String warn) { 15 | this.log.warn(warn); 16 | 17 | } 18 | 19 | @Override 20 | public void error(String error, Throwable e) { 21 | this.log.error(error, e); 22 | 23 | } 24 | 25 | @Override 26 | public void info(String info) { 27 | this.log.info(info); 28 | 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /websocket-test/src/main/java/test/TestWSService.java: -------------------------------------------------------------------------------- 1 | package test; 2 | 3 | import java.io.IOException; 4 | import java.util.HashMap; 5 | import java.util.Map; 6 | 7 | import javax.websocket.EncodeException; 8 | import javax.websocket.Session; 9 | 10 | import org.grain.websokcetlib.IWSListener; 11 | import org.grain.websokcetlib.WsPacket; 12 | 13 | import protobuf.ws.Test.TestC; 14 | import protobuf.ws.Test.TestS; 15 | 16 | public class TestWSService implements IWSListener { 17 | 18 | @Override 19 | public Map getWSs() throws Exception { 20 | HashMap map = new HashMap<>(); 21 | map.put("testc", "onTestC"); 22 | return map; 23 | } 24 | 25 | public void onTestC(WsPacket wsPacket) throws IOException, EncodeException { 26 | TestC testc = (TestC) wsPacket.getData(); 27 | wsPacket.putMonitor("接到客户端发来的消息:" + testc.getMsg()); 28 | TestS.Builder tests = TestS.newBuilder(); 29 | tests.setWsOpCode("tests"); 30 | tests.setMsg("你好客户端,我是服务器"); 31 | WsPacket pt = new WsPacket("tests", tests.build()); 32 | Session session = (Session) wsPacket.session; 33 | session.getBasicRemote().sendObject(pt); 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /websocket-test/src/main/webapp/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Class-Path: 3 | 4 | -------------------------------------------------------------------------------- /websocket-test/src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | grain-websocket-test 4 | 5 | InitServlet 6 | init.InitServlet 7 | 0 8 | 9 | 10 | index.html 11 | index.htm 12 | index.jsp 13 | default.html 14 | default.htm 15 | default.jsp 16 | 17 | -------------------------------------------------------------------------------- /websocket-test/src/main/webapp/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Title 6 | 7 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /websocket/.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | .classpath 3 | .project 4 | .settings 5 | logs 6 | .idea 7 | *.iml 8 | dist -------------------------------------------------------------------------------- /websocket/build-websocket.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /websocket/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | com.github.dianbaer 6 | grain 7 | 1.0.0 8 | 9 | websocket 10 | websocket 11 | websocket 12 | 13 | 1.8 14 | 1.8 15 | UTF-8 16 | 17 | 18 | 19 | com.github.dianbaer 20 | websocket-lib 21 | 1.0.0 22 | 23 | 24 | com.github.dianbaer 25 | msg 26 | 1.0.0 27 | 28 | 29 | javax.websocket 30 | javax.websocket-api 31 | 1.1 32 | provided 33 | 34 | 35 | -------------------------------------------------------------------------------- /websocket/src/main/java/org/grain/websocket/WebSocketServer.java: -------------------------------------------------------------------------------- 1 | package org.grain.websocket; 2 | 3 | import javax.websocket.CloseReason; 4 | import javax.websocket.OnClose; 5 | import javax.websocket.OnMessage; 6 | import javax.websocket.OnOpen; 7 | import javax.websocket.Session; 8 | import javax.websocket.server.ServerEndpoint; 9 | 10 | import org.grain.msg.MsgManager; 11 | import org.grain.websokcetlib.WSManager; 12 | import org.grain.websokcetlib.WSMsg; 13 | import org.grain.websokcetlib.WebSocketDeCoder; 14 | import org.grain.websokcetlib.WebSocketEnCoder; 15 | import org.grain.websokcetlib.WsPacket; 16 | 17 | @ServerEndpoint(value = "/ws", decoders = { WebSocketDeCoder.class }, encoders = { WebSocketEnCoder.class }) 18 | public class WebSocketServer { 19 | @OnOpen 20 | public void onOpen(Session session) { 21 | 22 | try { 23 | MsgManager.dispatchMsg(WSMsg.WEBSOCKET_CLIENT_CREATE_CONNECT, null, session); 24 | } catch (Exception e) { 25 | if (WSManager.log != null) { 26 | WSManager.log.error("MsgManager.dispatchMsg error", e); 27 | } 28 | } 29 | } 30 | 31 | @OnMessage 32 | public void onMessage(Session session, WsPacket wsPacket) { 33 | wsPacket.session = session; 34 | WSManager.dispatchWS(wsPacket); 35 | } 36 | 37 | @OnClose 38 | public void onClose(Session session, CloseReason closeReason) { 39 | try { 40 | MsgManager.dispatchMsg(WSMsg.WEBSOCKET_CLIENT_DISCONNECT, null, session); 41 | } catch (Exception e) { 42 | if (WSManager.log != null) { 43 | WSManager.log.error("MsgManager.dispatchMsg error", e); 44 | } 45 | } 46 | } 47 | } 48 | --------------------------------------------------------------------------------