From 98c53d95a097cd70acbeae6f719060a8569300e1 Mon Sep 17 00:00:00 2001 From: MySelf <1341933031@qq.com> Date: Sat, 17 Aug 2019 18:23:56 +0800 Subject: [PATCH 1/7] update --- Front-End-Testing/chat70.html | 156 ------ Front-End-Testing/chat90.html | 186 ------- README.md | 80 +-- doc/Project-Log-cn.md | 37 -- doc/advice/advice.md | 27 -- doc/design_cn.md | 39 -- doc/detail/Login-cn.md | 213 -------- doc/detail/login_rect.md | 34 -- doc/goal/goal.md | 78 --- doc/netty-study.md | 40 -- doc/study/1-st.md | 34 -- doc/study/2-st.md | 195 -------- doc/study/mulu.md | 4 - doc/version/v1.0.0.md | 295 ----------- .../github/unclecatmyself/application.java | 13 - .../unclecatmyself/auto/AutoConfig.java | 12 - .../unclecatmyself/auto/ConfigFactory.java | 29 -- .../unclecatmyself/auto/InitServer.java | 47 -- .../unclecatmyself/auto/RedisConfig.java | 36 -- .../bootstrap/AbstractBootstrapServer.java | 99 ---- .../bootstrap/BootstrapServer.java | 16 - .../bootstrap/NettyBootstrapServer.java | 128 ----- .../backmsg/InChatBackMapService.java | 55 --- .../backmsg/InChatBackMapServiceImpl.java | 66 --- .../bootstrap/channel/HandlerServiceImpl.java | 203 -------- .../bootstrap/channel/cache/CacheMap.java | 134 ----- .../bootstrap/channel/cache/WsCacheMap.java | 150 ------ .../channel/http/FromServerService.java | 55 --- .../channel/http/HttpChannelService.java | 30 -- .../channel/http/HttpChannelServiceImpl.java | 134 ----- .../bootstrap/channel/http/HttpClient.java | 94 ---- .../channel/ws/WebSocketChannelService.java | 51 -- .../channel/ws/WsChannelService.java | 47 -- .../data/InChatToDataBaseService.java | 14 - .../bootstrap/handler/DefaultHandler.java | 154 ------ .../redisclient/testApplication.java | 22 - .../bootstrap/verify/InChatVerifyService.java | 15 - .../unclecatmyself/common/base/Handler.java | 64 --- .../common/base/HandlerApi.java | 14 - .../common/base/HandlerService.java | 88 ---- .../common/bean/InChatMessage.java | 113 ----- .../unclecatmyself/common/bean/InitNetty.java | 243 ---------- .../common/bean/SendInChat.java | 39 -- .../common/bean/vo/GetListVO.java | 25 - .../common/bean/vo/GetSizeVO.java | 34 -- .../common/bean/vo/NotFindUriVO.java | 21 - .../common/bean/vo/ResultVO.java | 40 -- .../common/bean/vo/SendServer.java | 33 -- .../common/bean/vo/SendServerVO.java | 27 -- .../common/constant/BootstrapConstant.java | 18 - .../common/constant/Constans.java | 43 -- .../common/constant/HttpConstant.java | 33 -- .../common/constant/LogConstant.java | 53 -- .../common/constant/NotInChatConstant.java | 20 - .../common/constant/UtilConstant.java | 12 - .../exception/NoFindHandlerException.java | 15 - .../NotFindLoginChannlException.java | 14 - .../unclecatmyself/common/ip/IpUtils.java | 66 --- .../common/pool/DefaultThreadFactory.java | 41 -- .../common/pool/ExecutorQueue.java | 56 --- .../common/pool/StandardThreadExecutor.java | 98 ---- .../common/ssl/SecureSocketKeyStore.java | 456 ------------------ .../ssl/SecureSocketSslContextFactory.java | 89 ---- .../ssl/SecureSokcetTrustManagerFactory.java | 63 --- .../common/ssl/StreamReader.java | 25 - .../common/ssl/X509CertTool.java | 69 --- .../unclecatmyself/common/utils/HttpUtil.java | 63 --- .../common/utils/MessageChangeUtil.java | 44 -- .../common/utils/RedisUtil.java | 59 --- .../common/utils/RemotingUtil.java | 187 ------- .../unclecatmyself/common/utils/SslUtil.java | 35 -- .../unclecatmyself/demo1/EchoClient.java | 60 +++ .../demo1/EchoClientHandler.java | 46 ++ .../unclecatmyself/demo1/EchoServer.java | 68 +++ .../demo1/EchoServerHandler.java | 31 ++ .../task/DataAsynchronousTask.java | 52 -- .../unclecatmyself/task/DataCallable.java | 30 -- .../users/DataBaseServiceImpl.java | 15 - .../users/FromServerServiceImpl.java | 49 -- .../github/unclecatmyself/users/MyInit.java | 25 - .../users/VerifyServiceImpl.java | 21 - src/main/resources/log4j.properties | 17 - .../common/utils/RedisUtilTests.java | 51 -- 83 files changed, 206 insertions(+), 5581 deletions(-) delete mode 100644 Front-End-Testing/chat70.html delete mode 100644 Front-End-Testing/chat90.html delete mode 100644 doc/Project-Log-cn.md delete mode 100644 doc/advice/advice.md delete mode 100644 doc/design_cn.md delete mode 100644 doc/detail/Login-cn.md delete mode 100644 doc/detail/login_rect.md delete mode 100644 doc/goal/goal.md delete mode 100644 doc/netty-study.md delete mode 100644 doc/study/1-st.md delete mode 100644 doc/study/2-st.md delete mode 100644 doc/study/mulu.md delete mode 100644 doc/version/v1.0.0.md delete mode 100644 src/main/java/com/github/unclecatmyself/auto/AutoConfig.java delete mode 100644 src/main/java/com/github/unclecatmyself/auto/ConfigFactory.java delete mode 100644 src/main/java/com/github/unclecatmyself/auto/InitServer.java delete mode 100644 src/main/java/com/github/unclecatmyself/auto/RedisConfig.java delete mode 100644 src/main/java/com/github/unclecatmyself/bootstrap/AbstractBootstrapServer.java delete mode 100644 src/main/java/com/github/unclecatmyself/bootstrap/BootstrapServer.java delete mode 100644 src/main/java/com/github/unclecatmyself/bootstrap/NettyBootstrapServer.java delete mode 100644 src/main/java/com/github/unclecatmyself/bootstrap/backmsg/InChatBackMapService.java delete mode 100644 src/main/java/com/github/unclecatmyself/bootstrap/backmsg/InChatBackMapServiceImpl.java delete mode 100644 src/main/java/com/github/unclecatmyself/bootstrap/channel/HandlerServiceImpl.java delete mode 100644 src/main/java/com/github/unclecatmyself/bootstrap/channel/cache/CacheMap.java delete mode 100644 src/main/java/com/github/unclecatmyself/bootstrap/channel/cache/WsCacheMap.java delete mode 100644 src/main/java/com/github/unclecatmyself/bootstrap/channel/http/FromServerService.java delete mode 100644 src/main/java/com/github/unclecatmyself/bootstrap/channel/http/HttpChannelService.java delete mode 100644 src/main/java/com/github/unclecatmyself/bootstrap/channel/http/HttpChannelServiceImpl.java delete mode 100644 src/main/java/com/github/unclecatmyself/bootstrap/channel/http/HttpClient.java delete mode 100644 src/main/java/com/github/unclecatmyself/bootstrap/channel/ws/WebSocketChannelService.java delete mode 100644 src/main/java/com/github/unclecatmyself/bootstrap/channel/ws/WsChannelService.java delete mode 100644 src/main/java/com/github/unclecatmyself/bootstrap/data/InChatToDataBaseService.java delete mode 100644 src/main/java/com/github/unclecatmyself/bootstrap/handler/DefaultHandler.java delete mode 100644 src/main/java/com/github/unclecatmyself/bootstrap/redisclient/testApplication.java delete mode 100644 src/main/java/com/github/unclecatmyself/bootstrap/verify/InChatVerifyService.java delete mode 100644 src/main/java/com/github/unclecatmyself/common/base/Handler.java delete mode 100644 src/main/java/com/github/unclecatmyself/common/base/HandlerApi.java delete mode 100644 src/main/java/com/github/unclecatmyself/common/base/HandlerService.java delete mode 100644 src/main/java/com/github/unclecatmyself/common/bean/InChatMessage.java delete mode 100644 src/main/java/com/github/unclecatmyself/common/bean/InitNetty.java delete mode 100644 src/main/java/com/github/unclecatmyself/common/bean/SendInChat.java delete mode 100644 src/main/java/com/github/unclecatmyself/common/bean/vo/GetListVO.java delete mode 100644 src/main/java/com/github/unclecatmyself/common/bean/vo/GetSizeVO.java delete mode 100644 src/main/java/com/github/unclecatmyself/common/bean/vo/NotFindUriVO.java delete mode 100644 src/main/java/com/github/unclecatmyself/common/bean/vo/ResultVO.java delete mode 100644 src/main/java/com/github/unclecatmyself/common/bean/vo/SendServer.java delete mode 100644 src/main/java/com/github/unclecatmyself/common/bean/vo/SendServerVO.java delete mode 100644 src/main/java/com/github/unclecatmyself/common/constant/BootstrapConstant.java delete mode 100644 src/main/java/com/github/unclecatmyself/common/constant/Constans.java delete mode 100644 src/main/java/com/github/unclecatmyself/common/constant/HttpConstant.java delete mode 100644 src/main/java/com/github/unclecatmyself/common/constant/LogConstant.java delete mode 100644 src/main/java/com/github/unclecatmyself/common/constant/NotInChatConstant.java delete mode 100644 src/main/java/com/github/unclecatmyself/common/constant/UtilConstant.java delete mode 100644 src/main/java/com/github/unclecatmyself/common/exception/NoFindHandlerException.java delete mode 100644 src/main/java/com/github/unclecatmyself/common/exception/NotFindLoginChannlException.java delete mode 100644 src/main/java/com/github/unclecatmyself/common/ip/IpUtils.java delete mode 100644 src/main/java/com/github/unclecatmyself/common/pool/DefaultThreadFactory.java delete mode 100644 src/main/java/com/github/unclecatmyself/common/pool/ExecutorQueue.java delete mode 100644 src/main/java/com/github/unclecatmyself/common/pool/StandardThreadExecutor.java delete mode 100644 src/main/java/com/github/unclecatmyself/common/ssl/SecureSocketKeyStore.java delete mode 100644 src/main/java/com/github/unclecatmyself/common/ssl/SecureSocketSslContextFactory.java delete mode 100644 src/main/java/com/github/unclecatmyself/common/ssl/SecureSokcetTrustManagerFactory.java delete mode 100644 src/main/java/com/github/unclecatmyself/common/ssl/StreamReader.java delete mode 100644 src/main/java/com/github/unclecatmyself/common/ssl/X509CertTool.java delete mode 100644 src/main/java/com/github/unclecatmyself/common/utils/HttpUtil.java delete mode 100644 src/main/java/com/github/unclecatmyself/common/utils/MessageChangeUtil.java delete mode 100644 src/main/java/com/github/unclecatmyself/common/utils/RedisUtil.java delete mode 100644 src/main/java/com/github/unclecatmyself/common/utils/RemotingUtil.java delete mode 100644 src/main/java/com/github/unclecatmyself/common/utils/SslUtil.java create mode 100644 src/main/java/com/github/unclecatmyself/demo1/EchoClient.java create mode 100644 src/main/java/com/github/unclecatmyself/demo1/EchoClientHandler.java create mode 100644 src/main/java/com/github/unclecatmyself/demo1/EchoServer.java create mode 100644 src/main/java/com/github/unclecatmyself/demo1/EchoServerHandler.java delete mode 100644 src/main/java/com/github/unclecatmyself/task/DataAsynchronousTask.java delete mode 100644 src/main/java/com/github/unclecatmyself/task/DataCallable.java delete mode 100644 src/main/java/com/github/unclecatmyself/users/DataBaseServiceImpl.java delete mode 100644 src/main/java/com/github/unclecatmyself/users/FromServerServiceImpl.java delete mode 100644 src/main/java/com/github/unclecatmyself/users/MyInit.java delete mode 100644 src/main/java/com/github/unclecatmyself/users/VerifyServiceImpl.java delete mode 100644 src/main/resources/log4j.properties delete mode 100644 src/test/java/com/github/unclecatmyself/common/utils/RedisUtilTests.java diff --git a/Front-End-Testing/chat70.html b/Front-End-Testing/chat70.html deleted file mode 100644 index 59d409d..0000000 --- a/Front-End-Testing/chat70.html +++ /dev/null @@ -1,156 +0,0 @@ - - - - - WebSocket Chat - - - - -
-

InChat 聊天室-8070

- -
- - - - - -
-
-
- - \ No newline at end of file diff --git a/Front-End-Testing/chat90.html b/Front-End-Testing/chat90.html deleted file mode 100644 index 3611b0f..0000000 --- a/Front-End-Testing/chat90.html +++ /dev/null @@ -1,186 +0,0 @@ - - - - - WebSocket Chat - - - - -
-

InChat 聊天室-8090

- -
- - - - - - - -
-
-
- - - \ No newline at end of file diff --git a/README.md b/README.md index 7273b8e..f1c27d2 100644 --- a/README.md +++ b/README.md @@ -15,88 +15,10 @@ 本项目入驻[**AwakenCN**](https://github.com/AwakenCN)开源组织,后续将继续更新调整,部分API后续会更改,感谢每一位朋友的支持与关注。 -## 简介 +## 官方教程 -***(InChat)Iot Netty Chat*** -一个轻量级、高效、分布式的异步通信框架, 支持聊天和物联网, 您可以使用它来快速构建具有后台的聊天服务器, 并快速自定义自己的通信 api, 包括具有不同的通讯可以支持的协议。 - -**欢迎参与QQ群交流与提供建议、业务场景、需求功能等** - -**[代码贡献指南](http://www.imooc.com/article/272573)** - -> 目前项目更新内容:补充文案、设计稿说明、使用说明等 - -## Maven版本 - -功能列表: - -> * 用户token登录校验 -> * 自我聊天 -> * 点对点聊天 -> * 群聊 -> * 获取在线用户数与用户标签列表 -> * 发送系统通知 -> * 1.1.3版本新增SSL加密,分布式测试点对点、群聊功能(分布式为试用版,暂不支持SSL加密) - -* [InChatV1.1.3版本使用说明](https://unclecatmyself.github.io/2019/01/15/inchatby113/) - -``` - - com.github.UncleCatMySelf - InChat - 1.1.3 - -``` - -## 里程碑 - -* [InChat项目里程碑-历史版本](doc/goal/goal.md) - -## 项目日志 - -* [项目研发日志更新](doc/Project-Log-cn.md) - -## 教程 - -### [Netty入门与源码讲解](doc/study/mulu.md) - -## 官方案例 - -- - -## 项目相关 - -> * [项目设计思路](doc/design_cn.md) -> * [登录模块详细设计](doc/detail/Login-cn.md) -> * [登录模块整改版V0.1](doc/detail/login_rect.md) - -## 相关资料(欢迎贡献) - -* [QQ群建议贡献](doc/advice/advice.md) - -## 效果展示 - -![加密](https://raw.githubusercontent.com/UncleCatMySelf/img-myself/master/img/inchatGIF/%E5%8A%A0%E5%AF%86.gif) -![分布式](https://raw.githubusercontent.com/UncleCatMySelf/img-myself/master/img/inchatGIF/%E5%88%86%E5%B8%83%E5%BC%8F.gif) -![demo](https://github.com/UncleCatMySelf/img-myself/blob/master/img/inchatGIF/inchat_demo.gif) -![log](https://github.com/UncleCatMySelf/img-myself/blob/master/img/inchatGIF/inchat_log.gif) -![postman](https://github.com/UncleCatMySelf/img-myself/blob/master/img/inchatGIF/inchat_postman.gif) -![send](https://github.com/UncleCatMySelf/img-myself/blob/master/img/inchatGIF/inchat_send.gif) - -## 下载地址 - -下载地址:https://github.com/UncleCatMySelf/SBToNettyChat/releases - -## 下载 & 问题 - -https://github.com/UncleCatMySelf/SBToNettyChat/issues - -## 关于贡献 - -[!Noseparte说: 开源项目InChat贡献记](https://www.imooc.com/article/272573) - ## 公众号:Java猫说 **学习交流群:728698035** diff --git a/doc/Project-Log-cn.md b/doc/Project-Log-cn.md deleted file mode 100644 index 4cae52c..0000000 --- a/doc/Project-Log-cn.md +++ /dev/null @@ -1,37 +0,0 @@ -# 项目研发日志更新 - -* 【2018-11-21】 目前Maven包开发目标,设计WebSocket登录接口[详情请看设计文档](design_cn.md) -* 【2018-11-22】 编码实现WebSocket聊天通讯的登录流程,[撰写说明文档](detail/Login-cn.md) -* 【2018-11-23】 添加贡献建议信息,重构修改登录检测常量代码,提取成接口形式 -* 【2018-11-26】 登录存储用户token与链接实例,发送给自己功能API,部分功能代码重构 -* 【2018-11-27】 发送消息给在线其他用户,代码部分模块加注释,[撰写设计文档](detail/login_rect.md),但是中途思路有所转变 -* 【2018-11-29】 修复登录下线关闭channel异常BUG,移除原始未重构代码,更新下线模块,与本地在线存储功能。 -* 【2018-11-30】 启动赞助功能,新增【服务端向API发送消息】接口功能,暂未测试 -* 【2018-12-02】 转变部分项目思路,减少用户对框架的依赖与开发成本。 -* 【2018-12-03】 构建【组建群聊】模块功能,整改数据接收Map转为Map,放弃【组建群聊】,仅作基本im业务,完成功能【发送群聊】 -* 【2018-12-04】 明确项目文档的重要性,并设定Netty相关文档说明,与Netty入门说明 -* 【2018-12-05】 移除部分Iot使用的代码(一版暂时还没使用到),清楚pom文件中不用的jar包,需添加【系统时间】参数 -* 【2018-12-06】 确定LOGO并上传,InChat QQ群项目组成立,移除对lombok的依赖,使用传统形式,统一注释说明 -* 【2018-12-14】 打包完成v1.0.0Maven版本,并提交说明文档与相关资料,正对v1.0.0提交对应demo分支。 -* 【2018-12-15】 [录制V1.0.0使用说明视频](https://v.qq.com/x/page/i0813oy0lov.html) -* 【2018-12-18】 明确移除对SpringBoot的依赖于环境,做成自纯应用。[添加NIO服务端与客户端Demo](https://github.com/UncleCatMySelf/InChat/wiki/Java-NIO%E4%B9%8BSelector%EF%BC%88%E9%80%89%E6%8B%A9%E5%99%A8%EF%BC%89) -* 【2018-12-19】 移除lombok,嵌入log4j的依赖,并配置日志信息,移除对SpringBoot的依赖成功,普通main方法既可以运行项目。 -* 【2018-12-21】 添加静态配置,添加服务端发送接口,发布V1.1.0-alpha版本,标识性版本。 -* 【2018-12-27】 添加部分注释,修改版本启动模式,并预定后期添加HTTP接入模式,修改日志配置。 -* 【2018-12-28】 预计整改常量、修改部分方法(类)命名,下一版加wss通道。 -* 【2018-12-30】 修改异步线程任务(FutureTask启动模式),整改目录与修改核心类名,捕获未注册时客户端异常断开的连接异常,新增Http接口功能整改(未完)。 -* 【2018-12-31】 下一版InChat 自带几个默认的Http接口 查询【在线用户数】、【服务端发送消息】、【用户在线用户列表】等,暂不支持自定义URI HTTP接口 -* 【2019-01-01】 添加工具方法 -* 【2019-01-02】 修复httpPOST请求接口 -* 【2019-01-03】 完成新版http接口处理与测试,预计发包,新版发布 InChatV1.1.2,更新README展示GIF,录制V1.1.2视频教程与使用说明书 -* 【2019-01-04】 修复文档,确定版本,新增Redis对接 -* 【2019-01-05】 初步转分布式、处理netty集群(未完成) -* 【2019-01-07】 完成netty集群,多用户跨服务器的消息通讯(HTTP版本) -* 【2019-01-08】 设定下一版本目标,完成ssl加密,构建代码贡献文档 -* 【2019-01-09】 noseparte贡献代码修改pom与README文件 -* 【2019-01-10】 整改设计文档 -* 【2019-01-15】 完成SSL加密的功能封装,完成分布式下群聊分发功能。发布1.1.3版本 -* 【2019-01-23】 上线InChat-Cloud分布式组件 -* 【2019-03-05】 重新整理添加注释 - - diff --git a/doc/advice/advice.md b/doc/advice/advice.md deleted file mode 100644 index 76b35e9..0000000 --- a/doc/advice/advice.md +++ /dev/null @@ -1,27 +0,0 @@ -## QQ群贡献建议 - -> 贡献者:小斑马 - -* 一个netty在物联网的应用,质量很高,有些模块可以直接拿来用 -* https://github.com/cosmoplat-dev - -* 可以考虑把长连接单独做成一个模块,上行下行数据可以直接放到消息队列里面去,上行数据上来后直接放到消息队列里,其他模块接收存数据库,长连接模块监听其他模块放到消息队列里的下发数据 - -> 贡献者:夜殇 - -* 加了规则引擎的物联网项目 -* https://github.com/thingsboard/thingsboard - -* 对上方项目的修改 -* https://github.com/JaryZhen/rulegin - -> 贡献者:[ELLIOT](https://github.com/chanjjaeseo) - -* RabbitMQ 基本操作 -* https://github.com/chanjjaeseo/rabbitMQ-sample - -> 贡献者:[noseparte](https://github.com/noseparte) - -* [netty4通信原理](../netty-study.md) -* MongoDB的基本操作 -* https://github.com/noseparte/mongoTeam diff --git a/doc/design_cn.md b/doc/design_cn.md deleted file mode 100644 index e45ec5c..0000000 --- a/doc/design_cn.md +++ /dev/null @@ -1,39 +0,0 @@ -# 项目设计思路 - -## 设计原则 - -AOP、DI为主,基于Spring Boot快速搭建,尽量减少用户的二次搭配开发 - -## 关于登录 - -关于InChat统一登录的接口设计,设计针对小程序、APP、Web端的登录作用,所以将作为token的形式登录InChat的WebSocket长连接,用户服务器做sso的认证登录后得到token后直接发送login信息到InChat,用户服务器需要重写InChat中的verifyToken方法校验自己的的Token信息是否有效,正常则启动长连接。考虑到token失效问题,WebSocket长连接的登录仅做初次登录,接下来考虑以心跳形式保持链接状态(pingpong),使用token认证是为保护InChat链接的常规化(目前暂时这样设计后面根据使用情况更改设计) - -![Image text](https://raw.githubusercontent.com/UncleCatMySelf/img-myself/master/img/design/%E6%9C%AA%E5%91%BD%E5%90%8D%E6%96%87%E4%BB%B6(12).png) - -* 【2018-11-22】 编码实现和[详细实现文档](detail/Login-cn.md) - -## 离线消息模板 - -一版采用RabbitMQ----移除 - -## 整体设计 - -![Image text](https://raw.githubusercontent.com/UncleCatMySelf/img-myself/master/img/inchat/%E6%9C%AA%E5%91%BD%E5%90%8D%E6%96%87%E4%BB%B6(19).png) - -- 1、移除原本Token概念,用户均以唯一标识登录并存储在线键值对于系统本地Cache。(登录存储、退出移除) -- 2、DefaultWebSocketHandler,是框架默认的处理,数据均已json格式,拆分业务点 -- 3、由InChat内部的服务(WebSocketHandlerService )进行具体的业务实现并回写 -- 4、对于数据的存储与写入,默认是异步写入数据,用户可以重写InChatToDataBaseService,获取实时数据 -- 5、在高并发情况下,我们不推荐异步处理数据,可以通过配置化启动mq(目前支持RabbitMq),框架自动注入对应Bean,并由MQ来执行数据写入 -- 6、关于数据库连接池,我们不会绑定用户使用,而是支持用户自定义。 - -## 集群处理设计 - -![Image](https://raw.githubusercontent.com/UncleCatMySelf/img-myself/master/img/inchat/%E9%9B%86%E7%BE%A4%E8%AE%BE%E8%AE%A1.png) - -目前针对刚刚实现的点对点跨服务器接收发送流程: -- 1、一个服务器承受的用户并发量是有限,所以需要横向扩充服务器,所以会出现多个InChat Server端口,每个服务器都会接收一定用户量的登录并发长连接, -每个用户登录一个服务器后,都会向Redis发送(key=token、value=【IP:端口】+Channel标签)的加密存储值。 -- 2、当60的A用户想发送给70的B用户时,60通过redis知道这个B用户是在线的,可是本地取不到这个链接就会向redis取对应的这个B用户的token的键值对。 -- 3、60的服务器就会先向A用户发送他已经发出的消息,方便前端显示,同时60服务器拿到B用户的【IP:端口】,通过InChat系统内部二次开通的Http客户端,发送给70服务器。 -- 4、70服务器接收到HTTP请求,这时会向B用户发送这个A用户发送的消息,因为Netty是异步的 ,所以过程是流畅的。 \ No newline at end of file diff --git a/doc/detail/Login-cn.md b/doc/detail/Login-cn.md deleted file mode 100644 index 2aa63e7..0000000 --- a/doc/detail/Login-cn.md +++ /dev/null @@ -1,213 +0,0 @@ -## 只给你最值得的信息 - -小弟正在做的一个开源IM项目,目标是实现一个轻量级、高效率的支持聊天与物联网的通讯框架。昨天刚刚出的设计稿并再今天做了实现。 - -项目是基于Netty的二次开发,关于Netty我这里就不再介绍了,懂的人自然都懂。我的预算是做一个所有企业或组织可以引用的Maven项目,并且是基本上开箱即用,简单实现对应的配置与重写方法就可以搭建自己的IM项目(某Q、某信的效果)。 - -本文着重介绍的是登录接口的设计与实现。 - -## 设计信息 - -关于InChat统一登录的接口设计,设计针对小程序、APP、Web端的登录作用,所以将作为token的形式登录InChat的WebSocket长连接,用户服务器做sso的认证登录后得到token后直接发送login信息到InChat,用户服务器需要重写InChat中的verifyToken方法校验自己的的Token信息是否有效,正常则启动长连接。考虑到token失效问题,WebSocket长连接的登录仅做初次登录,接下来考虑以心跳形式保持链接状态(pingpong),使用token认证是为保护InChat链接的常规化(目前暂时这样设计后面根据使用情况更改设计) - -![Image text](https://raw.githubusercontent.com/UncleCatMySelf/img-myself/master/img/inchat/%E6%9C%AA%E5%91%BD%E5%90%8D%E6%96%87%E4%BB%B6(13).png) - -由于目前大部分的Web项目或基于IM的项目登录可能存在多端的单点登录,所以我选用了Token的形式,为什么登录后还需要用token再来websocket这边校验一次呢? - -因为你登录的是web应用程序端的,而websocket而言,只要别人知道你的地址,那么就可以链接上,我们不希望存在过多的死链接(无效链接),所以我们需要将token再次发给InChat登录,由InChat来检验是否是合法登录链接,如果无效则关闭链接。 - -## 代码实现 - -由于是想要做给别人用的,那么我们自己本身就要封装的好一点,对于配置我选了足够多的类型。 - -![Image text](https://raw.githubusercontent.com/UncleCatMySelf/img-myself/master/img/inchat/%E5%BE%AE%E4%BF%A1%E5%9B%BE%E7%89%87_20181122171455.png) - -对于netty监听与初始化,我使用的方式是扫描与AspectJ,你可以在项目的auto包中看到扫描启动,这种启动思路我也是参考了其他的开源项目(具体忘记了地址)。 - -```java -@Bean -@ConditionalOnMissingBean(name = "sacnScheduled") -public ScanRunnable initRunable(@Autowired InitNetty serverBean){ - long time =(serverBean==null || serverBean.getPeriod()<5)?10:serverBean.getPeriod(); - ScanRunnable sacnScheduled = new SacnScheduled(time); - Thread scanRunnable = new Thread(sacnScheduled); - scanRunnable.setDaemon(true); - scanRunnable.start(); - return sacnScheduled; -} - - -@Bean(initMethod = "open", destroyMethod = "close") -@ConditionalOnMissingBean -public InitServer initServer(InitNetty serverBean){ - if(!ObjectUtils.allNotNull(serverBean.getWebport(),serverBean.getServerName())){ - throw new NullPointerException("not set port"); - } - if(serverBean.getBacklog()<1){ - serverBean.setBacklog(_BLACKLOG); - } - if(serverBean.getBossThread()<1){ - serverBean.setBossThread(CPU); - } - if(serverBean.getInitalDelay()<0){ - serverBean.setInitalDelay(SEDU_DAY); - } - if(serverBean.getPeriod()<1){ - serverBean.setPeriod(SEDU_DAY); - } - if(serverBean.getHeart()<1){ - serverBean.setHeart(TIMEOUT); - } - if(serverBean.getRevbuf()<1){ - serverBean.setRevbuf(BUF_SIZE); - } - if(serverBean.getWorkerThread()<1){ - serverBean.setWorkerThread(CPU*2); - } - return new InitServer(serverBean); -} -``` - - -在上图中存在一个DefaultWebSocketHandler,这个是默认的netty启动处理。 - -当然在执行它之前,还需要执行到一个抽象的类WebSocketHandler。 - -它将会为我做一些基本的功能操作。 - -```java -@Slf4j -public abstract class WebSocketHandler extends SimpleChannelInboundHandler { - - WebSocketHandlerApi webSocketHandlerApi; - - public WebSocketHandler(WebSocketHandlerApi webSocketHandlerApi){ - this.webSocketHandlerApi = webSocketHandlerApi; - } - - @Override - protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception { - if (msg instanceof TextWebSocketFrame){ - textdoMessage(ctx,(TextWebSocketFrame)msg); - }else if (msg instanceof WebSocketFrame){ - webdoMessage(ctx,(WebSocketFrame)msg); - } - } - - protected abstract void webdoMessage(ChannelHandlerContext ctx, WebSocketFrame msg); - - protected abstract void textdoMessage(ChannelHandlerContext ctx, TextWebSocketFrame msg); - - @Override - public void channelInactive(ChannelHandlerContext ctx) throws Exception { - log.info("【DefaultWebSocketHandler:channelInactive】"+ctx.channel().localAddress().toString()+"关闭成功"); - webSocketHandlerApi.close(ctx.channel()); - } - - @Override - public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { - if(evt instanceof IdleStateEvent){ - webSocketHandlerApi.doTimeOut(ctx.channel(),(IdleStateEvent)evt); - } - super.userEventTriggered(ctx, evt); - } -} -``` - -对于登录接口,他是基于WebSocket的,且是TextWebSocketFrame类型的,WebSocketFrame是后期的图片聊天功能,所以我们的DefaultWebSocketHandler暂时只需要实现textdoMessage。 - -对于websocket的传输我们推荐使用json形式,这对于前后端都是由好处的。 - -```java - @Override - protected void textdoMessage(ChannelHandlerContext ctx, TextWebSocketFrame msg) { - Channel channel = ctx.channel(); - ServerWebSocketHandlerService serverWebSocketHandlerService; - if (webSocketHandlerApi instanceof ServerWebSocketHandlerService){ - serverWebSocketHandlerService = (ServerWebSocketHandlerService)webSocketHandlerApi; - }else{ - throw new NoFindHandlerException("Server Handler 不匹配"); - } - Map maps = (Map) JSON.parse(msg.text()); - switch (maps.get("type")){ - case "login": - serverWebSocketHandlerService.login(channel,msg); - break; - default: - break; - } - } -``` - -由上面的代码,你也许才想到了前端登录的大致json内容,没错是这样的。 - -``` -{ - type: "login", - token: value -} -``` - -ServerWebSocketHandlerService是一个自己定义的后端WebSocket存在的接口实现服务,我们现在使用到他的登录接口,让我们来看看他的登录实现方法。 - -```java - - @Autowired - InChatVerifyService inChatVerifyService; - - @Override - public boolean login(Channel channel, TextWebSocketFrame textWebSocketFrame) { - //校验规则,自定义校验规则 - Map maps = (Map) JSON.parse(textWebSocketFrame.text()); - System.out.println("login-"+textWebSocketFrame.text()); - String token = maps.get("token"); - Gson gson = new Gson(); - Map backMap = new HashMap<>(); - if (inChatVerifyService.verifyToken(token)){ - backMap.put("type","login"); - backMap.put("success","true"); - channel.writeAndFlush(new TextWebSocketFrame(gson.toJson(backMap))); - return true; - } - backMap.put("type","login"); - backMap.put("success","false"); - channel.writeAndFlush(new TextWebSocketFrame(gson.toJson(backMap))); - close(channel); - return false; - } -``` - -由以上可看出,我们会将token和inChatVerifyService.verifyToken做校验,这是一个接口,我并没有写实现,因为这个是用户的事情了,它需要实现并重写我的verifyToken方法,并返回给我一个值,如下是我测试的时候写的模拟实现。 - -```java -/** - * 不属于项目代码 - * Created by MySelf on 2018/11/22. - */ -@Service -public class InChatVerifyServiceImpl implements InChatVerifyService { - - @Override - public boolean verifyToken(String token) { - //与Redis中的Token做比较,请用户自己实现,查找是否存在该Token值 - System.out.println("verify---"+token); - if ("3333".equals(token)){ - return true; - } - return false; - } -} -``` - -我仅仅做了普通的校验,对于用户可以注入RedisTemplate然后进行校验等工作。到此我们的登录接口就实现好了! - -## 看看效果 - -![Image text](https://raw.githubusercontent.com/UncleCatMySelf/img-myself/master/img/inchat/%E5%BE%AE%E4%BF%A1%E5%9B%BE%E7%89%87_20181122171241.png) - -![Image text](https://raw.githubusercontent.com/UncleCatMySelf/img-myself/master/img/inchat/%E5%BE%AE%E4%BF%A1%E5%9B%BE%E7%89%87_20181122171245.png) - -![Image text](https://raw.githubusercontent.com/UncleCatMySelf/img-myself/master/img/inchat/%E5%BE%AE%E4%BF%A1%E5%9B%BE%E7%89%87_20181122171247.png) - - -> 2017-11-25 end. \ No newline at end of file diff --git a/doc/detail/login_rect.md b/doc/detail/login_rect.md deleted file mode 100644 index 2106932..0000000 --- a/doc/detail/login_rect.md +++ /dev/null @@ -1,34 +0,0 @@ -## 前言 - -本文旨在更新上一节设计中的不合理进行整改,关于登录的不足还有扩展功能的添加。 - -前文:[登录模块详细设计](Login-cn.md) - -对于前文中的登录原核心思路是正确的,不过对于后期的部分业务功能的扩展是比较麻烦的,比如发送给其他人,发送离线消息,判断系统用户是否离线等。 -的确,上文只是设计登录而言,但是我们还要考虑到后续功能接口的封装还有业务流程,所以一开始多磨是有好处的。 - -## 设计整改 - -这次的架构流程我们大致是这样的。 - -![Image text](https://raw.githubusercontent.com/UncleCatMySelf/img-myself/master/img/inchat/login.png) - -我们可能需要中心整理一下: - -* 客户端是小程序、APP、Web端等的统称 -* 客户端向服务器登录请求获取服务器分配的token -* 同时服务器将用户信息与token存入redis -* 客户端登录的同时还要登录InChat,发送json格式向websocket模拟登录 - -``` -{ - type:login - token:**** -} -``` - -* InChat接收根据Type进行登录流程的执行,用户重写verifyToken方法去用户自定义的Redis中判断,返回真假 -* 校验登录成功,InChat本地存储链接与用户信息,这里的用户信息应该是User唯一标识,而不能是Token - -> 在我写到这里的时候,脑子中突然觉得说不定可以使用token,甚至想到更多,导致我没有继续写完本章 -> 2018-11-27 end. \ No newline at end of file diff --git a/doc/goal/goal.md b/doc/goal/goal.md deleted file mode 100644 index e87480e..0000000 --- a/doc/goal/goal.md +++ /dev/null @@ -1,78 +0,0 @@ -# InChat项目里程碑 - -> 项目研发的开放目标,以Maven包为基本的发布(兼对应版本的文档输出)设定为每个里程碑的产出。 - -### 项目于2018年8月14号开始成立,前一个月以Demo为发展路线,后期转为框架研发。 - -## V1.0.0版本 【2018-12-14】 - -> 版本昵称:赤猫 - -版本目标:完成基本的消息通讯(仅支持文本消息),离线消息存储,历史消息查询,一对一聊天、自我聊天、群聊等 - -* [V1.0.0版本使用说明](doc/version/v1.0.0.md) -* [V1.0.0版本使用说明视频教程](https://v.qq.com/x/page/i0813oy0lov.html) - -> 目前项目代码已经推进入了下一版本,如果你想下载这个版本的源码,可以到这里下载[V1.0.0-alpha](https://github.com/UncleCatMySelf/InChat/releases/tag/V1.0.0-alpha) - -``` - - - com.github.UncleCatMySelf - InChat - 1.0-alpha - -``` - -## V1.1.0-alpha版本 【2018-12-21】 - -> 版本昵称:赤猫-1 - -版本目标:移除对SpringBoot的环境依赖,InChat独立生存与使用,结合上一版的功能,并添加服务器发送消息接口 - -* [V1.1.0-alpha版本使用说明](https://unclecatmyself.github.io/2018/12/21/InChatV1.1.0%E7%89%88%E6%9C%AC%E4%BD%BF%E7%94%A8%E8%AF%B4%E6%98%8E/) -* [V1.1.0-alpha版本视频教学](https://v.qq.com/x/page/i08165ym286.html) - -``` - - com.github.UncleCatMySelf - InChat - 1.1.0-alpha - -``` - -## 【2018-12-20】 项目突破 **150** Star,感谢大家的支持 - -## V1.1.2版本 【2019-01-04】 - -> 版本昵称:赤猫-2 - -版本更新:添加HTTP接口调用,捕获已知异常 - -* [V1.1.2版本使用说明](https://unclecatmyself.github.io/2019/01/03/inchatby112/) -* [V1.1.2版本视频教学](https://v.qq.com/x/page/y08228i7znk.html) - -``` - - com.github.UncleCatMySelf - InChat - 1.1.2 - -``` - - -## V1.1.3版本 【待定】 - -> 版本昵称:橙猫 - -版本目标:InChat集群与wss,SSL加密与分布式测试点对点与群聊 - -* [相关文档正在撰写...]() - -``` - - com.github.UncleCatMySelf - InChat - 1.1.3 - -``` diff --git a/doc/netty-study.md b/doc/netty-study.md deleted file mode 100644 index e9a55cb..0000000 --- a/doc/netty-study.md +++ /dev/null @@ -1,40 +0,0 @@ -## netty4通信步骤,原理 - -> 感谢 贡献者:[Noseparte](https://github.com/noseparte) - -### 服务端依次发生的步骤 - -* 1.建立服务端监听套接字ServerSocketChannel,以及对应的管道pipeline; -* 2.启动boss线程,将ServerSocketChannel注册到boss线程持有的selector中,并将注册返回的selectionKey赋值给ServerSocketChannel关联的selectionKey变量; -* 3.在ServerSocketChannel对应的管道中触发channelRegistered事件; -* 4.绑定IP和端口 -* 5.触发channelActive事件,并将ServerSocketChannel关联的selectionKey的OP_ACCEPT位置为1。 -* 6.客户端发起connect请求后,boss线程正在运行的select循环检测到了该ServerSocketChannel的ACCEPT事件就绪,则通过accept系统调用建立一个已连接套接字SocketChannel,并为其创建对应的管道; -* 7.在服务端监听套接字对应的管道中触发channelRead事件; -* 8.channelRead事件由ServerBootstrapAcceptor的channelRead方法响应:为已连接套接字对应的管道加入ChannelInitializer处理器; -启动一个worker线程,并将已连接套接字的注册任务加入到worker线程的任务队列中; -* 9.worker线程执行已连接套接字的注册任务:将已连接套接字注册到worker线程持有的selector中,并将注册返回的selectionKey赋值给已连接套接字关联的selectionKey变量; -在已连接套接字对应的管道中触发channelRegistered事件;channelRegistered事件由ChannelInitializer的channelRegistered方法响应: -将自定义的处理器(譬如EchoServerHandler)加入到已连接套接字对应的管道中;在已连接套接字对应的管道中触发channelActive事件;c -hannelActive事件由已连接套接字对应的管道中的inbound处理器的channelActive方法响应;将已连接套接字关联的selectionKey的OP_READ位置为1;至此,worker线程关联的selector就开始监听已连接套接字的READ事件了。 -* 10.在worker线程运行的同时,Boss线程接着在服务端监听套接字对应的管道中触发channelReadComplete事件。 -* 11.客户端向服务端发送消息后,worker线程正在运行的selector循环会检测到已连接套接字的READ事件就绪。则通过read系统调用将消息从套接字的接受缓冲区中读到AdaptiveRecvByteBufAllocator(可以自适应调整分配的缓存的大小)分配的缓存中; -* 12.在已连接套接字对应的管道中触发channelRead事件; -* 13.channelRead事件由EchoServerHandler处理器的channelRead方法响应:执行write操作将消息存储到ChannelOutboundBuffer中; -* 14.在已连接套接字对应的管道中触发ChannelReadComplete事件; -* 15.ChannelReadComplete事件由EchoServerHandler处理器的channelReadComplete方法响应:执行flush操作将消息从ChannelOutboundBuffer中flush到套接字的发送缓冲区中; - - - -### 客户端依次发生的步骤 - -* 1.建立套接字SocketChannel,以及对应的管道pipeline; -* 2.启动客户端线程,将SocketChannel注册到客户端线程持有的selector中,并将注册返回的selectionKey赋值给SocketChannel关联的selectionKey变量; -* 3.触发channelRegistered事件; -* 4.channelRegistered事件由ChannelInitializer的channelRegistered方法响应:将客户端自定义的处理器(譬如EchoClientHandler)按顺序加入到管道中; -* 5.向服务端发起connect请求,并将SocketChannel关联的selectionKey的OP_CONNECT位置为1; -* 6.开始三次握手,客户端线程正在运行的select循环检测到了该SocketChannel的CONNECT事件就绪,则将关联的selectionKey的OP_CONNECT位置为0,再通过调用finishConnect完成连接的建立; -* 7.触发channelActive事件; -* 8.channelActive事件由EchoClientHandler的channelActive方法响应,通过调用ctx.writeAndFlush方法将消息发往服务端; -* 9.首先将消息存储到ChannelOutboundBuffer中;(如果ChannelOutboundBuffer存储的所有未flush的消息的大小超过高水位线writeBufferHighWaterMark(默认值为64 * 1024),则会触发ChannelWritabilityChanged事件) -* 10.然后将消息从ChannelOutboundBuffer中flush到套接字的发送缓冲区中;(如果ChannelOutboundBuffer存储的所有未flush的消息的大小小于低水位线,则会触发ChannelWritabilityChanged事件) \ No newline at end of file diff --git a/doc/study/1-st.md b/doc/study/1-st.md deleted file mode 100644 index d93848c..0000000 --- a/doc/study/1-st.md +++ /dev/null @@ -1,34 +0,0 @@ -# 第一章 Netty的大致介绍 - -netty被广泛应用于世面上的许多框架,如Dubbo、RocketMQ、Spark、ElasticSearch、Cassandra、Flink、Netty-SocketIO、Spring5、Play、Grpc..... - -以上均是将Netty作为底层网络通讯。 - -## Netty是什么? - -* 异步事件驱动框架,用于快速开发高性能服务端和客户端 -* 封装了JDK底层BIO和NIO模型,提供高度可用的API -* 自带编解码器解决拆包粘包问题,用户只用关心业务逻辑 -* 精心设计的reactor线程模型支持高并发海量连接 -* 自带各种协议栈让你处理任何一种通用协议都几乎不用亲自动手 - -## 学习Netty有必要吗? - -* 各大开源项目选择Netty作为底层通信框架 -* 更好的使用,少走弯路 -* 遇到BUG?单机连接数上不去?性能遇到瓶颈?如何调优? -* 详解reactor线程模型,实践中举一反三 -* 庞大的项目是如何组织的,设计模式,体验优秀的设计 -* 阅读源码其实没有那么困难 - -## 怎么学习Netty? - -* 自己摸索不如前人指路 -* 对应socket编程,逐个切入 -* 填坑路程 - -## 适合人群 - -* 系统掌握Netty底层核心原理 -* 加速掌握基于Netty的各类中间件框架 -* 对技术有追求。对优秀代码由执念的开发者 diff --git a/doc/study/2-st.md b/doc/study/2-st.md deleted file mode 100644 index 4ff3c2b..0000000 --- a/doc/study/2-st.md +++ /dev/null @@ -1,195 +0,0 @@ -# 第二章 Netty基本组件 - -## 一个简单的socket例子 - -![Image text](https://raw.githubusercontent.com/UncleCatMySelf/img-myself/master/img/stduy/100.png) - -### ServerBoot启动类 - -```java -package com.example.demo; - -/** - * @Author:UncleCatMySelf - * @Email:zhupeijie_java@126.com - * @QQ:1341933031 - * @Date:Created in 23:00 2018\12\4 0004 - */ -public class ServerBoot { - - private static final int PORT = 8000; - - public static void main(String[] args){ - Server server = new Server(PORT); - server.start(); - } - -} -``` - -### Server监听端口服务类 - -```java -package com.example.demo; - -import lombok.extern.slf4j.Slf4j; - -import java.io.IOException; -import java.net.ServerSocket; -import java.net.Socket; - -/** - * @Author:UncleCatMySelf - * @Email:zhupeijie_java@126.com - * @QQ:1341933031 - * @Date:Created in 22:46 2018\12\4 0004 - */ -@Slf4j -public class Server { - - private ServerSocket serverSocket; - - public Server(int port){ - try { - this.serverSocket = new ServerSocket(port); - log.info("服务端启动成功,端口:" + port); - }catch (IOException e){ - log.error("服务端启动失败"); - } - } - - public void start(){ - new Thread(new Runnable() { - @Override - public void run() { - doStart(); - } - }).start(); - } - - private void doStart(){ - while (true){ - try { - //阻塞方法 - Socket client = serverSocket.accept(); - new ClientHandler(client).start(); - }catch (IOException e){ - log.error("服务端异常"); - } - } - } -} -``` - -### ClientHandler客户端接入监听类 - -```java -package com.example.demo; - -import lombok.extern.slf4j.Slf4j; - -import java.io.IOException; -import java.io.InputStream; -import java.net.Socket; - -/** - * @Author:UncleCatMySelf - * @Email:zhupeijie_java@126.com - * @QQ:1341933031 - * @Date:Created in 22:50 2018\12\4 0004 - */ -@Slf4j -public class ClientHandler { - - public static final int MAX_DATA_LEN = 1024; - private final Socket socket; - - public ClientHandler(Socket socket){ - this.socket = socket; - } - - public void start(){ - log.info("新客户端接入"); - new Thread(new Runnable() { - @Override - public void run() { - doStart(); - } - }).start(); - } - - private void doStart(){ - try { - InputStream inputStream = socket.getInputStream(); - while (true){ - byte[] data = new byte[MAX_DATA_LEN]; - int len; - while((len = inputStream.read(data)) != -1){ - String message = new String(data,0,len); - log.info("客户端传来消息:" + message); - socket.getOutputStream().write(data); - } - } - }catch (IOException e){ - e.printStackTrace(); - } - } - -} -``` - - -### Client客户端启动类 - -```java -package com.example.demo; - -import lombok.extern.slf4j.Slf4j; - -import java.io.IOException; -import java.net.Socket; - -/** - * @Author:UncleCatMySelf - * @Email:zhupeijie_java@126.com - * @QQ:1341933031 - * @Date:Created in 23:01 2018\12\4 0004 - */ -@Slf4j -public class Client { - - private static final String HOST = "127.0.0.1"; - private static final int PORT = 8000; - private static final int SLEEP_TIME = 5000; - - public static void main(String[] args) throws IOException{ - final Socket socket = new Socket(HOST,PORT); - - new Thread(new Runnable() { - @Override - public void run() { - log.info("客户端启动成功!"); - while (true){ - try { - String message = "hello myself"; - log.info("客户端发送数据:" + message); - socket.getOutputStream().write(message.getBytes()); - }catch (Exception e){ - log.info("写数据出错!"); - } - sleep(); - } - } - }).start(); - } - - private static void sleep(){ - try { - Thread.sleep(SLEEP_TIME); - }catch (InterruptedException e){ - e.printStackTrace(); - } - } - -} -``` \ No newline at end of file diff --git a/doc/study/mulu.md b/doc/study/mulu.md deleted file mode 100644 index ddd649c..0000000 --- a/doc/study/mulu.md +++ /dev/null @@ -1,4 +0,0 @@ -# Netty 入门与源码讲解 - -* [Netty介绍与详情](1-st.md) -* [Netty基本组件](2-st.md) \ No newline at end of file diff --git a/doc/version/v1.0.0.md b/doc/version/v1.0.0.md deleted file mode 100644 index f5fce28..0000000 --- a/doc/version/v1.0.0.md +++ /dev/null @@ -1,295 +0,0 @@ -## v1.0.0版本使用说明 - -### 关于InChat的Maven依赖 - -* fastjson 》 1.2.53 -* gson 》 2.8.5 -* netty 》 4.1.32.Final -* commons-lang 》 3.5 -* aspectj 》 1.9.2 -* lombok 》 1.18.4 -* spring-boot 》 2.0.2.RELEASE -* spring-boot-starter-websocket - -关于一版依旧使用SpringBoot的环境,同时为应用注入了web环境,引入InChat依赖包后,对于SpringBoot相关的web可以无需引入,同时请注意相关版本的兼容性。 -引入InChat默认可以自动运行web环境。 - -### 创建项目 - -创建一个空的Maven项目,并引入**InChat**Maven包,(注意,请不要使用与本项目相同的包目录)。 - -可能你只需要这样的Maven依赖即可 - -``` - - - com.github.UncleCatMySelf - InChat - 1.0-alpha - - - org.springframework.boot - spring-boot-starter-test - test - - -``` - -### 注入InChat的项目到自身项目中 - -你可能需要在你的项目上进行报扫描 - -```java -@SpringBootApplication -@ComponentScan({"com.inchat"}) //你的demo包目录 -@ComponentScan({"com.github.unclecatmyself"}) //InChat的包目录 --请将InChat的放到最下面 -public class DemoApplication { - - public static void main(String[] args) { - SpringApplication.run(DemoApplication.class, args); - } - -} -``` - -### 对接InChat的接口与实现 - -这次你仅需写两个实现接口即可啦!!! - -```java -@Service -public class ToDataBaseServiceImpl implements InChatToDataBaseService{ - - @Override - public Boolean writeMapToDB(Map maps) { - //异步写入数据库 - System.out.println(maps.toString()); - return true; - } -} -``` - -* 这个接口是每个人通讯的信息,InChat自带实现了异步的数据外抛得接口**InChatToDataBaseService**,目前一版只有一个方法, -就是上面得writeMapToDB,你仅需要map的内容转为对应的对象(一版还没提供对应的转换类,下一版对提供),并将数据存入自己喜欢的数据库中。 -如果数据并发大,也可以先放到MQ中,再写入数据库。 - -```java -@Service -public class verifyServiceImpl implements InChatVerifyService { - - - @Override - public boolean verifyToken(String token) { - //登录校验 - return true; - } - - @Override - public JSONArray getArrayByGroupId(String groupId) { - //根据群聊id获取对应的群聊人员ID - JSONArray jsonArray = JSONArray.parseArray("[\"1111\",\"2222\",\"3333\"]"); - return jsonArray; - } -} -``` - -* 这个接口是InChat的校验层实现,对于Token的校验就是,**verifyToken**,websocket链接的时候,你将在初次做登录校验,你可以将从InChat拿到的websocket传过来的 -Token,你可以与自己的用户登录的token做校验,返回true,则用户成功链接InChat。 - -* 关于**getArrayByGroupId**,目前是否应该放在这个接口中还有待确定,不过目前一版暂时这样,你可以去数据库中查询对应的群聊id所对应的人员ID(或Token),并返回对应的 -JSONArray即可啦。 - -### 自定义配置InChat参数 - -这个你可以直接在application中按照自己的意思配置,不过你最好先了解netty - -![Image](https://raw.githubusercontent.com/UncleCatMySelf/img-myself/master/img/inchat/%E5%BE%AE%E4%BF%A1%E5%9B%BE%E7%89%87_20181214104225.png) - -### 启动项目 - -接着启动项目即可啦 - -当你看到这个日志就标志着Inchat搭建成功了!!! - -``` -2018-12-14 10:29:09.269 INFO 4920 --- [ BOSS_1] c.g.u.bootstrap.NettyBootstrapServer : 服务端启动成功【192.168.1.121:8090】 -``` - -### 关于前端 - -这里你可以来到[InChat](https://github.com/UncleCatMySelf/InChat)的Front-End-Testing文档夹中的chat.html。 - -你可以直接使用,你进需要修改对应的对接IP即可。 - -> 关于前端的js暂时还是模板 - -### 关于登录 - -你会看到chat.html中的登录按钮对应的js - -```js -function send(value) { - if (!window.WebSocket) { - return; - } - if (socket.readyState == WebSocket.OPEN) { - var message = { - type: "login", //与InChat对应的 不可修改 - token: "1111" - } - socket.send(JSON.stringify(message)); - } else { - alert("连接没有开启."); - } -} -``` - -本demo,默认登录的Token是“1111”,关于用户校验则直接返回true即可。 - -登录成功,返回以下内容。(不需要显示给用户看) - -``` -{"success":"true","type":"login"} -``` - -InChat不会有登录记录 - -### 发送给自己 - -你会看到chat.html中的登录按钮对应的js - -```js -function sendToMe(value) { - if (!window.WebSocket) { - return; - } - if (socket.readyState == WebSocket.OPEN) { - var message = { - type: "sendMe", //与InChat对应的 不可修改 - value: value, //发送的内容 - token: "1111" //发送用户的token - } - socket.send(JSON.stringify(message)); - } else { - alert("连接没有开启."); - } -} -``` - -发送成功,InChat返回内容.(你仅需将value显示到前端即可) - -``` -{"type":"sendMe","value":"发送给自己的内容"} -``` - -InChat消息记录,你将在异步消息中接受到InChat传递给你的用户通讯消息,你可以进行对应的入库操作 - -``` -{"time":"2018-12-14 10:56:24","type":"sendMe","value":"发送给自己的内容","token":"1111"} -``` - -### 发送给某人 - -你会看到chat.html中的登录按钮对应的js - -```js -function sendToOne(value) { - if (!window.WebSocket) { - return; - } - if (socket.readyState == WebSocket.OPEN) { - var message = { - type : "sendTo", //与InChat对应的 不可修改 - token : "1111", //发送用户Token - value: value, //发送内容 - one: "2222", //接受用户Token(唯一标识) - } - socket.send(JSON.stringify(message)); - } else { - alert("连接没有开启."); - } -} -``` - -发送成功,接受的用户是否登录,你都能接受到返回信息。(value应用于自己界面展示) - -``` -{"one":"2222","type":"sendTo","value":"发送给朋友的内容"} -``` - -但是用户那边就不一样了。 - -登录正常在线。 - -``` -{"from":"1111","type":"sendTo","value":"发送给朋友的内容"} -``` - -离线接受不到信息 - -InChat异步消息推送,你可以看到两种 - -``` -在线: {"one":"2222","time":"2018-12-14 11:01:36","type":"sendTo","value":"发送给朋友的内容","token":"1111"} -``` - -``` -离线: {"one":"2222","time":"2018-12-14 10:59:04","on_online":"2222","type":"sendTo","value":"发送给朋友的内容","token":"1111"} -``` - -如果出现用户发送给用户的状态是离线的,则会在消息多出on_online的字段,该字段的内容就是离线用户的Token,你可以针对性的数据入库,并在用户上线的时候,读写信息的时候,有一个未读消息的状态。 - -### 发送群聊 - -你会看到chat.html中的登录按钮对应的js - -```js -function sendGroup(value) { - if (!window.WebSocket) { - return; - } - if (socket.readyState == WebSocket.OPEN) { - var message = { - type: "sendGroup", //与InChat对应的 不可修改 - groupId: "2", //群聊ID - token: "1111", //发送用户的Token - value: value //发送的消息 - } - socket.send(JSON.stringify(message)); - } else { - alert("连接没有开启."); - } -} -``` - -发送成功,本人将接受到消息 - -``` -{"groupId":"2","from":"1111","type":"sendGroup","value":"大家明天一起去唱K吧"} -``` - -群组中有些人在线接受、离线不接受 - -``` -在线:{"groupId":"2","from":"1111","type":"sendGroup","value":"大家明天一起去唱K吧"} -``` - -InChat异步消息入库,群组只会异步给你一个消息,你可以看到on_online中,3333用户是没有接受到信息的,所以你可以在他上线发送未读消息。 - -``` -{"groupId":"2","time":"2018-12-14 11:09:17","on_online":["3333"],"type":"sendGroup","value":"大家明天一起去唱K吧","token":"1111"} -``` - -### 关于数据库设计 - -> 当前一版不会固定大家的数据库设计,大家可以自己自由设计,同时搭上自己的项目,构建一个附带IM的自项目。 - -### 前端效果 - -发送人 - -![Image](https://raw.githubusercontent.com/UncleCatMySelf/img-myself/master/img/inchat/%E5%BE%AE%E4%BF%A1%E5%9B%BE%E7%89%87_20181214111435.png) - -接收人 - -![Image](https://raw.githubusercontent.com/UncleCatMySelf/img-myself/master/img/inchat/%E5%BE%AE%E4%BF%A1%E5%9B%BE%E7%89%87_20181214111438.png) \ No newline at end of file diff --git a/src/main/java/com/github/unclecatmyself/application.java b/src/main/java/com/github/unclecatmyself/application.java index 1775260..3539ef5 100644 --- a/src/main/java/com/github/unclecatmyself/application.java +++ b/src/main/java/com/github/unclecatmyself/application.java @@ -1,11 +1,5 @@ package com.github.unclecatmyself; -import com.github.unclecatmyself.auto.ConfigFactory; -import com.github.unclecatmyself.auto.InitServer; -import com.github.unclecatmyself.users.DataBaseServiceImpl; -import com.github.unclecatmyself.users.FromServerServiceImpl; -import com.github.unclecatmyself.users.MyInit; -import com.github.unclecatmyself.users.VerifyServiceImpl; /** * Create by UncleCatMySelf in 22:49 2019\1\4 0004 @@ -13,14 +7,7 @@ public class application { public static void main(String[] args) { - ConfigFactory.initNetty = new MyInit(); - ConfigFactory.inChatVerifyService = new VerifyServiceImpl(); - ConfigFactory.inChatToDataBaseService = new DataBaseServiceImpl(); - ConfigFactory.fromServerService = FromServerServiceImpl.TYPE2; -// ConfigFactory.RedisIP = "192.168.0.101"; -// ConfigFactory.RedisIP = "192.168.192.132"; - InitServer.open(); } } diff --git a/src/main/java/com/github/unclecatmyself/auto/AutoConfig.java b/src/main/java/com/github/unclecatmyself/auto/AutoConfig.java deleted file mode 100644 index 4af8a1f..0000000 --- a/src/main/java/com/github/unclecatmyself/auto/AutoConfig.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.github.unclecatmyself.auto; - -/** - * 自动配置厂 - * Create by UncleCatMySelf in 14:33 2019\1\5 0005 - */ -public class AutoConfig { - - //地址配置,默认为空 - public static String address = ""; - -} diff --git a/src/main/java/com/github/unclecatmyself/auto/ConfigFactory.java b/src/main/java/com/github/unclecatmyself/auto/ConfigFactory.java deleted file mode 100644 index d0195eb..0000000 --- a/src/main/java/com/github/unclecatmyself/auto/ConfigFactory.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.github.unclecatmyself.auto; - -import com.github.unclecatmyself.bootstrap.channel.http.FromServerService; -import com.github.unclecatmyself.bootstrap.data.InChatToDataBaseService; -import com.github.unclecatmyself.bootstrap.verify.InChatVerifyService; -import com.github.unclecatmyself.common.bean.InitNetty; - -/** - * 默认配置工厂 - * Created by MySelf on 2018/12/21. - */ -public class ConfigFactory { - - /** Redis的ip地址,这你不会不知道吧? */ - public static String RedisIP; - - /** 用户校验伪接口 */ - public static InChatVerifyService inChatVerifyService; - - /** 用户获取数据伪接口 */ - public static InChatToDataBaseService inChatToDataBaseService; - - /** 系统信息枚举服务接口 */ - public static FromServerService fromServerService; - - /** InChat项目配置 */ - public static InitNetty initNetty; - -} diff --git a/src/main/java/com/github/unclecatmyself/auto/InitServer.java b/src/main/java/com/github/unclecatmyself/auto/InitServer.java deleted file mode 100644 index 5a9348e..0000000 --- a/src/main/java/com/github/unclecatmyself/auto/InitServer.java +++ /dev/null @@ -1,47 +0,0 @@ -package com.github.unclecatmyself.auto; - - -import com.github.unclecatmyself.bootstrap.BootstrapServer; -import com.github.unclecatmyself.bootstrap.NettyBootstrapServer; -import com.github.unclecatmyself.common.bean.InitNetty; - -/** - * InChat项目启动服务 - * Create by UncleCatMySelf in 2018/12/06 - **/ -public abstract class InitServer { - -// private InitNetty serverBean; - - /** 静态化处理,保证唯一,确保用户启动的是他自己指定的,不是框架的 - * 一个数据配置集合 - */ - private static InitNetty serverBean = ConfigFactory.initNetty; - -// public InitServer(InitNetty serverBean) { -// this.serverBean = serverBean; -// } - /** netty服务器启动切面 */ - static BootstrapServer bootstrapServer; - - /** - * 主要还是这个{@link NettyBootstrapServer},实例化想要的netty配置服务 - */ - public static void open(){ - if(serverBean!=null){ - bootstrapServer = new NettyBootstrapServer(); - bootstrapServer.setServerBean(serverBean); - bootstrapServer.start(); - } - } - - /** - * 关闭服务 - */ - public void close(){ - if(bootstrapServer!=null){ - bootstrapServer.shutdown(); - } - } - -} diff --git a/src/main/java/com/github/unclecatmyself/auto/RedisConfig.java b/src/main/java/com/github/unclecatmyself/auto/RedisConfig.java deleted file mode 100644 index e384287..0000000 --- a/src/main/java/com/github/unclecatmyself/auto/RedisConfig.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.github.unclecatmyself.auto; - -import com.github.unclecatmyself.common.constant.LogConstant; -import com.sun.org.apache.regexp.internal.RE; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import redis.clients.jedis.Jedis; - -/** - * 关于redis一些基础东西 - * Create by UncleCatMySelf in 13:56 2019\1\5 0005 - */ -public class RedisConfig { - - private static final Logger log = LoggerFactory.getLogger(RedisConfig.class); - - /** 单例模式 */ - private static RedisConfig instance = new RedisConfig(); - - public static Jedis jedis; - - /** - * 如果配置启动分布式,则自动初始化jedis - * */ - private RedisConfig(){ - if (ConfigFactory.initNetty.getDistributed()){ - this.jedis = new Jedis(ConfigFactory.RedisIP); - log.info(LogConstant.REDIS_START + jedis.ping()); - } - } - - public static RedisConfig getInstance(){ - return instance; - } - -} diff --git a/src/main/java/com/github/unclecatmyself/bootstrap/AbstractBootstrapServer.java b/src/main/java/com/github/unclecatmyself/bootstrap/AbstractBootstrapServer.java deleted file mode 100644 index 4756e2d..0000000 --- a/src/main/java/com/github/unclecatmyself/bootstrap/AbstractBootstrapServer.java +++ /dev/null @@ -1,99 +0,0 @@ -package com.github.unclecatmyself.bootstrap; - - -import com.github.unclecatmyself.auto.ConfigFactory; -import com.github.unclecatmyself.bootstrap.channel.HandlerServiceImpl; -import com.github.unclecatmyself.bootstrap.handler.DefaultHandler; -import com.github.unclecatmyself.common.bean.InitNetty; -import com.github.unclecatmyself.common.constant.BootstrapConstant; -import com.github.unclecatmyself.common.constant.NotInChatConstant; -import com.github.unclecatmyself.common.ssl.SecureSocketSslContextFactory; -import com.github.unclecatmyself.common.utils.SslUtil; -import com.github.unclecatmyself.task.DataAsynchronousTask; -import io.netty.channel.ChannelPipeline; -import io.netty.handler.codec.http.HttpObjectAggregator; -import io.netty.handler.codec.http.HttpRequestDecoder; -import io.netty.handler.codec.http.HttpResponseEncoder; -import io.netty.handler.codec.http.HttpServerCodec; -import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler; -import io.netty.handler.ssl.SslHandler; -import io.netty.handler.stream.ChunkedWriteHandler; -import io.netty.handler.timeout.IdleStateHandler; -import io.netty.util.internal.SystemPropertyUtil; -import org.apache.commons.lang3.ObjectUtils; - -import javax.net.ssl.KeyManagerFactory; -import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLEngine; -import java.security.KeyStore; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; - -/** - * Create by UncleCatMySelf in 2018/12/06 - **/ -public abstract class AbstractBootstrapServer implements BootstrapServer { - - private String PROTOCOL = "TLS"; - - private SSLContext SERVER_CONTEXT; - - /** - * @param channelPipeline channelPipeline - * @param serverBean 服务配置参数 - */ - protected void initHandler(ChannelPipeline channelPipeline, InitNetty serverBean){ - if (serverBean.isSsl()){ - if (!ObjectUtils.allNotNull(serverBean.getJksCertificatePassword(),serverBean.getJksFile(),serverBean.getJksStorePassword())){ - throw new NullPointerException(NotInChatConstant.SSL_NOT_FIND); - } - try { - SSLContext context = SslUtil.createSSLContext("JKS",serverBean.getJksFile(),serverBean.getJksStorePassword()); - SSLEngine engine = context.createSSLEngine(); - engine.setUseClientMode(false); - engine.setNeedClientAuth(false); - channelPipeline.addLast(BootstrapConstant.SSL,new SslHandler(engine)); - System.out.println("open ssl success"); - } catch (Exception e) { - e.printStackTrace(); - } - } - intProtocolHandler(channelPipeline,serverBean); - channelPipeline.addLast(new IdleStateHandler(serverBean.getHeart(),0,0)); - channelPipeline.addLast(new DefaultHandler(new HandlerServiceImpl(new DataAsynchronousTask(ConfigFactory.inChatToDataBaseService),ConfigFactory.inChatVerifyService))); - } - - private void intProtocolHandler(ChannelPipeline channelPipeline,InitNetty serverBean){ - channelPipeline.addLast(BootstrapConstant.HTTPCODE,new HttpServerCodec()); -// channelPipeline.addLast("http-decoder",new HttpRequestDecoder()); - channelPipeline.addLast(BootstrapConstant.AGGREGATOR, new HttpObjectAggregator(serverBean.getMaxContext())); -// channelPipeline.addLast("http-encoder",new HttpResponseEncoder()); - channelPipeline.addLast(BootstrapConstant.CHUNKEDWRITE,new ChunkedWriteHandler()); - channelPipeline.addLast(BootstrapConstant.WEBSOCKETHANDLER,new WebSocketServerProtocolHandler(serverBean.getWebSocketPath())); - } - - private void initSsl(InitNetty serverBean){ - ExecutorService executorService = Executors.newCachedThreadPool(); - executorService.submit(() -> {}); - String algorithm = SystemPropertyUtil.get("ssl.KeyManagerFactory.algorithm"); - if (algorithm == null) { - algorithm = "SunX509"; - } - SSLContext serverContext; - try { - // - KeyStore ks = KeyStore.getInstance("JKS"); - ks.load( SecureSocketSslContextFactory.class.getResourceAsStream(serverBean.getJksFile()), - serverBean.getJksStorePassword().toCharArray()); - KeyManagerFactory kmf = KeyManagerFactory.getInstance(algorithm); - kmf.init(ks,serverBean.getJksCertificatePassword().toCharArray()); - serverContext = SSLContext.getInstance(PROTOCOL); - serverContext.init(kmf.getKeyManagers(), null, null); - } catch (Exception e) { - throw new Error( - "Failed to initialize the server-side SSLContext", e); - } - SERVER_CONTEXT = serverContext; - } - -} diff --git a/src/main/java/com/github/unclecatmyself/bootstrap/BootstrapServer.java b/src/main/java/com/github/unclecatmyself/bootstrap/BootstrapServer.java deleted file mode 100644 index 00c36fa..0000000 --- a/src/main/java/com/github/unclecatmyself/bootstrap/BootstrapServer.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.github.unclecatmyself.bootstrap; - -import com.github.unclecatmyself.common.bean.InitNetty; - -/** - * Create by UncleCatMySelf in 2018/12/06 - **/ -public interface BootstrapServer { - - void shutdown(); - - void setServerBean(InitNetty serverBean); - - void start(); - -} diff --git a/src/main/java/com/github/unclecatmyself/bootstrap/NettyBootstrapServer.java b/src/main/java/com/github/unclecatmyself/bootstrap/NettyBootstrapServer.java deleted file mode 100644 index d4da251..0000000 --- a/src/main/java/com/github/unclecatmyself/bootstrap/NettyBootstrapServer.java +++ /dev/null @@ -1,128 +0,0 @@ -package com.github.unclecatmyself.bootstrap; - -import com.github.unclecatmyself.auto.AutoConfig; -import com.github.unclecatmyself.auto.RedisConfig; -import com.github.unclecatmyself.common.ip.IpUtils; -import com.github.unclecatmyself.common.bean.InitNetty; -import com.github.unclecatmyself.common.utils.RemotingUtil; -import io.netty.bootstrap.ServerBootstrap; -import io.netty.buffer.PooledByteBufAllocator; -import io.netty.channel.ChannelFutureListener; -import io.netty.channel.ChannelInitializer; -import io.netty.channel.ChannelOption; -import io.netty.channel.EventLoopGroup; -import io.netty.channel.epoll.Epoll; -import io.netty.channel.epoll.EpollEventLoopGroup; -import io.netty.channel.epoll.EpollServerSocketChannel; -import io.netty.channel.nio.NioEventLoopGroup; -import io.netty.channel.socket.SocketChannel; -import io.netty.channel.socket.nio.NioServerSocketChannel; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.concurrent.ThreadFactory; -import java.util.concurrent.atomic.AtomicInteger; - -/** - * Create by UncleCatMySelf in 2018/12/06 - **/ -public class NettyBootstrapServer extends AbstractBootstrapServer { - - private final Logger log = LoggerFactory.getLogger(NettyBootstrapServer.class); - - private InitNetty serverBean; - - public void setServerBean(InitNetty serverBean) { - this.serverBean = serverBean; - } - - private EventLoopGroup bossGroup; - - private EventLoopGroup workGroup; - - ServerBootstrap bootstrap=null ;// 启动辅助类 - - /** - * 服务开启 - */ - public void start() { - initEventPool(); - bootstrap.group(bossGroup, workGroup) - .channel(useEpoll()?EpollServerSocketChannel.class:NioServerSocketChannel.class) - .option(ChannelOption.SO_REUSEADDR, serverBean.isReuseaddr()) - .option(ChannelOption.SO_BACKLOG, serverBean.getBacklog()) - .option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT) - .option(ChannelOption.SO_RCVBUF, serverBean.getRevbuf()) - .childHandler(new ChannelInitializer() { - protected void initChannel(SocketChannel ch) throws Exception { - initHandler(ch.pipeline(),serverBean); - } - }) - .childOption(ChannelOption.TCP_NODELAY, serverBean.isNodelay()) - .childOption(ChannelOption.SO_KEEPALIVE, serverBean.isKeepalive()) - .childOption(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT); - bootstrap.bind(IpUtils.getHost(),serverBean.getWebport()).addListener((ChannelFutureListener) channelFuture -> { - if (channelFuture.isSuccess()) { - log.info("服务端启动成功【" + IpUtils.getHost() + ":" + serverBean.getWebport() + "】"); - AutoConfig.address = IpUtils.getHost()+":"+serverBean.getWebport(); - RedisConfig.getInstance(); - }else{ - log.info("服务端启动失败【" + IpUtils.getHost() + ":" + serverBean.getWebport() + "】");} - }); - } - /** - * 初始化EnentPool 参数 - */ - private void initEventPool(){ - bootstrap= new ServerBootstrap(); - if(useEpoll()){ - bossGroup = new EpollEventLoopGroup(serverBean.getBossThread(), new ThreadFactory() { - private AtomicInteger index = new AtomicInteger(0); - public Thread newThread(Runnable r) { - return new Thread(r, "LINUX_BOSS_" + index.incrementAndGet()); - } - }); - workGroup = new EpollEventLoopGroup(serverBean.getWorkerThread(), new ThreadFactory() { - private AtomicInteger index = new AtomicInteger(0); - public Thread newThread(Runnable r) { - return new Thread(r, "LINUX_WORK_" + index.incrementAndGet()); - } - }); - - } - else { - bossGroup = new NioEventLoopGroup(serverBean.getBossThread(), new ThreadFactory() { - private AtomicInteger index = new AtomicInteger(0); - public Thread newThread(Runnable r) { - return new Thread(r, "BOSS_" + index.incrementAndGet()); - } - }); - workGroup = new NioEventLoopGroup(serverBean.getWorkerThread(), new ThreadFactory() { - private AtomicInteger index = new AtomicInteger(0); - public Thread newThread(Runnable r) { - return new Thread(r, "WORK_" + index.incrementAndGet()); - } - }); - } - } - - /** - * 关闭资源 - */ - public void shutdown() { - if(workGroup!=null && bossGroup!=null ){ - try { - bossGroup.shutdownGracefully().sync();// 优雅关闭 - workGroup.shutdownGracefully().sync(); - } catch (InterruptedException e) { - log.error("服务端关闭资源失败【" + IpUtils.getHost() + ":" + serverBean.getWebport() + "】"); - } - } - } - - private boolean useEpoll() { - return RemotingUtil.isLinuxPlatform() - && Epoll.isAvailable(); - } - -} diff --git a/src/main/java/com/github/unclecatmyself/bootstrap/backmsg/InChatBackMapService.java b/src/main/java/com/github/unclecatmyself/bootstrap/backmsg/InChatBackMapService.java deleted file mode 100644 index ffb7a07..0000000 --- a/src/main/java/com/github/unclecatmyself/bootstrap/backmsg/InChatBackMapService.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.github.unclecatmyself.bootstrap.backmsg; - - -import java.util.Map; - -/** - * 消息返回 - * Created by MySelf on 2018/11/23. - */ -public interface InChatBackMapService { - - /** - * 登录成功返回信息 - * @return {@link Map} Json - */ - Map loginSuccess(); - - /** - * 登录失败返回信息 - * @return {@link Map} Json - */ - Map loginError(); - - /** - * 发送给自己 - * @param value {@link String} 通讯消息 - * @return {@link Map} Json - */ - Map sendMe(String value); - - /** - * 发送给某人的信息,返回给自己 - * @param otherOne {@link String} 某人Token - * @param value {@link String} 通讯消息 - * @return {@link Map} Json - */ - Map sendBack(String otherOne, String value); - - /** - * 某人接收到他人发送给他的消息 - * @param me {@link String} 发送人的标签 - * @param value {@link String} 通讯消息 - * @return - */ - Map getMsg(String me, String value); - - /** - * 发送消息到群里 - * @param me {@link String} 发送人的标签 - * @param value {@link String} 通讯消息 - * @param groupId {@link String} 群聊Id - * @return - */ - Map sendGroup(String me,String value,String groupId); -} diff --git a/src/main/java/com/github/unclecatmyself/bootstrap/backmsg/InChatBackMapServiceImpl.java b/src/main/java/com/github/unclecatmyself/bootstrap/backmsg/InChatBackMapServiceImpl.java deleted file mode 100644 index 57a27e9..0000000 --- a/src/main/java/com/github/unclecatmyself/bootstrap/backmsg/InChatBackMapServiceImpl.java +++ /dev/null @@ -1,66 +0,0 @@ -package com.github.unclecatmyself.bootstrap.backmsg; - -import com.github.unclecatmyself.common.constant.Constans; - -import java.util.HashMap; -import java.util.Map; - -/** - * 列入项目中,默认返回实现 - * Created by MySelf on 2018/11/23. - */ -public class InChatBackMapServiceImpl implements InChatBackMapService { - - - public Map loginSuccess() { - Map backMap = new HashMap(); - backMap.put(Constans.TYPE,Constans.LOGIN); - backMap.put(Constans.SUCCESS,Constans.TRUE); - return backMap; - } - - - public Map loginError() { - Map backMap = new HashMap(); - backMap.put(Constans.TYPE,Constans.LOGIN); - backMap.put(Constans.SUCCESS,Constans.FALSE); - return backMap; - } - - - public Map sendMe(String value) { - Map backMap = new HashMap(); - backMap.put(Constans.TYPE,Constans.SENDME); - backMap.put(Constans.VALUE,value); - return backMap; - } - - - public Map sendBack(String otherOne, String value) { - Map backMap = new HashMap(); - backMap.put(Constans.TYPE,Constans.SENDTO); - backMap.put(Constans.VALUE,value); - backMap.put(Constans.ONE,otherOne); - return backMap; - } - - - public Map getMsg(String token, String value) { - Map backMap = new HashMap(); - backMap.put(Constans.TYPE,Constans.SENDTO); - backMap.put(Constans.FROM,token); - backMap.put(Constans.VALUE,value); - return backMap; - } - - - public Map sendGroup(String token, String value, String groupId) { - Map backMap = new HashMap(); - backMap.put(Constans.TYPE,Constans.SENDGROUP); - backMap.put(Constans.FROM,token); - backMap.put(Constans.VALUE,value); - backMap.put(Constans.GROUPID,groupId); - return backMap; - } - -} diff --git a/src/main/java/com/github/unclecatmyself/bootstrap/channel/HandlerServiceImpl.java b/src/main/java/com/github/unclecatmyself/bootstrap/channel/HandlerServiceImpl.java deleted file mode 100644 index d2d259a..0000000 --- a/src/main/java/com/github/unclecatmyself/bootstrap/channel/HandlerServiceImpl.java +++ /dev/null @@ -1,203 +0,0 @@ -package com.github.unclecatmyself.bootstrap.channel; - -import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.JSONArray; -import com.alibaba.fastjson.JSONObject; -import com.github.unclecatmyself.bootstrap.backmsg.InChatBackMapService; -import com.github.unclecatmyself.bootstrap.backmsg.InChatBackMapServiceImpl; -import com.github.unclecatmyself.bootstrap.channel.cache.WsCacheMap; -import com.github.unclecatmyself.bootstrap.channel.http.HttpChannelService; -import com.github.unclecatmyself.bootstrap.channel.http.HttpChannelServiceImpl; -import com.github.unclecatmyself.bootstrap.channel.ws.WebSocketChannelService; -import com.github.unclecatmyself.common.base.HandlerService; -import com.github.unclecatmyself.common.bean.SendInChat; -import com.github.unclecatmyself.common.bean.vo.SendServerVO; -import com.github.unclecatmyself.common.constant.Constans; -import com.google.gson.Gson; -import com.github.unclecatmyself.bootstrap.channel.ws.WsChannelService; -import com.github.unclecatmyself.bootstrap.verify.InChatVerifyService; -import com.github.unclecatmyself.task.DataAsynchronousTask; -import io.netty.channel.Channel; -import io.netty.handler.codec.http.FullHttpMessage; -import io.netty.handler.codec.http.websocketx.TextWebSocketFrame; -import io.netty.util.CharsetUtil; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -/** - * Created by MySelf on 2018/11/21. - */ -public class HandlerServiceImpl extends HandlerService { - - private final InChatVerifyService inChatVerifyService; - - private final InChatBackMapService inChatBackMapService = new InChatBackMapServiceImpl(); - - private final HttpChannelService httpChannelService = new HttpChannelServiceImpl(); - - private final WsChannelService websocketChannelService = new WebSocketChannelService(); - - private final DataAsynchronousTask dataAsynchronousTask; - - public HandlerServiceImpl(DataAsynchronousTask dataAsynchronousTask,InChatVerifyService inChatVerifyService) { - this.dataAsynchronousTask = dataAsynchronousTask; - this.inChatVerifyService = inChatVerifyService; - } - - - @Override - public void getList(Channel channel) { - httpChannelService.getList(channel); - } - - @Override - public void getSize(Channel channel) { - httpChannelService.getSize(channel); - } - - @Override - public void sendFromServer(Channel channel, SendServerVO serverVO) { - httpChannelService.sendFromServer(channel,serverVO); - } - - @Override - public void sendInChat(Channel channel, FullHttpMessage msg) { - System.out.println(msg); - String content = msg.content().toString(CharsetUtil.UTF_8); - Gson gson = new Gson(); - SendInChat sendInChat = gson.fromJson(content,SendInChat.class); - httpChannelService.sendByInChat(channel,sendInChat); - } - - @Override - public void notFindUri(Channel channel) { - httpChannelService.notFindUri(channel); - } - - @Override - public boolean login(Channel channel, Map maps) { - //校验规则,自定义校验规则 - return check(channel, maps); - } - - @Override - public void sendMeText(Channel channel, Map maps) { - Gson gson = new Gson(); - channel.writeAndFlush(new TextWebSocketFrame( - gson.toJson(inChatBackMapService.sendMe((String) maps.get(Constans.VALUE))))); - try { - dataAsynchronousTask.writeData(maps); - } catch (Exception e) { - e.printStackTrace(); - } - } - - @Override - public void sendToText(Channel channel, Map maps) { - Gson gson = new Gson(); - String otherOne = (String) maps.get(Constans.ONE); - String value = (String) maps.get(Constans.VALUE); - String token = (String) maps.get(Constans.TOKEN); - //返回给自己 - channel.writeAndFlush(new TextWebSocketFrame( - gson.toJson(inChatBackMapService.sendBack(otherOne,value)))); - if (websocketChannelService.hasOther(otherOne)){ - //发送给对方--在线 - Channel other = websocketChannelService.getChannel(otherOne); - if (other == null){ - //转http分布式 - httpChannelService.sendInChat(otherOne,inChatBackMapService.getMsg(token,value)); - }else{ - other.writeAndFlush(new TextWebSocketFrame( - gson.toJson(inChatBackMapService.getMsg(token,value)))); - } - }else { - maps.put(Constans.ON_ONLINE,otherOne); - } - try { - dataAsynchronousTask.writeData(maps); - } catch (Exception e) { - return; - } - } - - @Override - public void sendGroupText(Channel channel, Map maps) { - Gson gson = new Gson(); - String groupId = (String) maps.get(Constans.GROUPID); - String token = (String) maps.get(Constans.TOKEN); - String value = (String) maps.get(Constans.VALUE); - List no_online = new ArrayList<>(); - JSONArray array = inChatVerifyService.getArrayByGroupId(groupId); - channel.writeAndFlush(new TextWebSocketFrame( - gson.toJson(inChatBackMapService.sendGroup(token,value,groupId)))); - for (Object item:array) { - if (!token.equals(item)){ - if (websocketChannelService.hasOther((String) item)){ - Channel other = websocketChannelService.getChannel((String) item); - if (other == null){ - //转http分布式 - httpChannelService.sendInChat((String) item,inChatBackMapService.sendGroup(token,value,groupId)); - }else{ - other.writeAndFlush(new TextWebSocketFrame( - gson.toJson(inChatBackMapService.sendGroup(token,value,groupId)))); - } - }else{ - no_online.add((String) item); - } - } - } - maps.put(Constans.ONLINE_GROUP,no_online); - try { - dataAsynchronousTask.writeData(maps); - } catch (Exception e) { - return; - } - } - - @Override - public void verify(Channel channel, Map maps) { - Gson gson = new Gson(); - String token = (String) maps.get(Constans.TOKEN); - System.out.println(token); - if (inChatVerifyService.verifyToken(token)){ - return; - }else{ - channel.writeAndFlush(new TextWebSocketFrame(gson.toJson(inChatBackMapService.loginError()))); - close(channel); - } - } - - @Override - public void sendPhotoToMe(Channel channel, Map maps) { - Gson gson = new Gson(); - System.out.println(maps.get(Constans.VALUE)); - channel.writeAndFlush(new TextWebSocketFrame( - gson.toJson(inChatBackMapService.sendMe((String) maps.get(Constans.VALUE))))); - try { - dataAsynchronousTask.writeData(maps); - } catch (Exception e) { - e.printStackTrace(); - } - } - - private Boolean check(Channel channel, Map maps){ - Gson gson = new Gson(); - String token = (String) maps.get(Constans.TOKEN); - if (inChatVerifyService.verifyToken(token)){ - channel.writeAndFlush(new TextWebSocketFrame(gson.toJson(inChatBackMapService.loginSuccess()))); - websocketChannelService.loginWsSuccess(channel,token); - return true; - } - channel.writeAndFlush(new TextWebSocketFrame(gson.toJson(inChatBackMapService.loginError()))); - close(channel); - return false; - } - - @Override - public void close(Channel channel) { - websocketChannelService.close(channel); - } -} diff --git a/src/main/java/com/github/unclecatmyself/bootstrap/channel/cache/CacheMap.java b/src/main/java/com/github/unclecatmyself/bootstrap/channel/cache/CacheMap.java deleted file mode 100644 index 3ed8d75..0000000 --- a/src/main/java/com/github/unclecatmyself/bootstrap/channel/cache/CacheMap.java +++ /dev/null @@ -1,134 +0,0 @@ -package com.github.unclecatmyself.bootstrap.channel.cache; - -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.CopyOnWriteArrayList; - -/** - * Create by UncleCatMySelf in 2018/12/06 - **/ -public class CacheMap { - - private ConcurrentHashMap> datas = new ConcurrentHashMap<>(); - - public boolean putData(K[] topic, V v){ - if(topic.length==1){ - Node kvNode = buildOne(topic[0], v); - if(kvNode!=null && kvNode.topic.equals(topic[0])){ - return true; - } - } - else{ - Node kvNode = buildOne(topic[0], null); - for(int i=1;i kvNode = datas.get(ks[0]); - for(int i=1;i getData(K[] ks){ - if(ks.length==1){ - return datas.get(ks[0]).get(); - } - else{ - Node node = datas.get(ks[0]); - if(node!=null){ - List all = new ArrayList<>(); - all.addAll(node.get()); - for(int i=1;i buildOne(K k,V v){ - - Node node = this.datas.computeIfAbsent(k, key -> { - Node kObjectNode = new Node(k); - return kObjectNode; - }); - if(v!=null){ - node.put(v); - } - return node; - } - - - - class Node{ - - private final K topic; - - - private volatile ConcurrentHashMap> map =new ConcurrentHashMap<>() ; - - - List vs = new CopyOnWriteArrayList<>(); - - - public K getTopic() {return topic;} - - Node(K topic) { - this.topic = topic; - } - - public boolean delValue(V v){ - return vs.remove(v); - } - - public Node putNextValue(K k,V v){ - Node kvNode = map.computeIfAbsent(k, key -> { - Node node = new Node<>(k); - return node; - }); - if(v!=null){ - kvNode.put(v); - } - return kvNode; - } - - - public Node getNext(K k){ - return map.get(k); - } - - - public boolean put(V v){ - return vs.add(v); - } - - - public List get(){ - return vs; - } - } - -} diff --git a/src/main/java/com/github/unclecatmyself/bootstrap/channel/cache/WsCacheMap.java b/src/main/java/com/github/unclecatmyself/bootstrap/channel/cache/WsCacheMap.java deleted file mode 100644 index a0a9099..0000000 --- a/src/main/java/com/github/unclecatmyself/bootstrap/channel/cache/WsCacheMap.java +++ /dev/null @@ -1,150 +0,0 @@ -package com.github.unclecatmyself.bootstrap.channel.cache; - -import com.github.unclecatmyself.auto.AutoConfig; -import com.github.unclecatmyself.auto.ConfigFactory; -import com.github.unclecatmyself.auto.RedisConfig; -import com.github.unclecatmyself.common.exception.NotFindLoginChannlException; -import com.github.unclecatmyself.common.constant.NotInChatConstant; -import com.github.unclecatmyself.common.utils.RedisUtil; -import io.netty.channel.Channel; -import redis.clients.jedis.Jedis; - -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; - -/** - * WebSocket链接实例本地存储 - * Created by MySelf on 2018/11/26. - */ -public class WsCacheMap { - - /** - * 存储用户标识与链接实例 - */ - private final static Map maps = new ConcurrentHashMap(); - - /** - * 存储链接地址与用户标识 - */ - private final static Map addMaps = new ConcurrentHashMap<>(); - - /** - * Redis连接实例 - */ - private final static Jedis jedis = RedisConfig.jedis; - - /** - * 是否启动分布式 - */ - private final static Boolean isDistributed = ConfigFactory.initNetty.getDistributed(); - - private final static String address = AutoConfig.address; - - /** - * 存储链接 - * @param token {@link String} 用户标签 - * @param channel {@link Channel} 链接实例 - */ - public static void saveWs(String token,Channel channel){ - maps.put(token,channel); - if (isDistributed){ - jedis.set(token, RedisUtil.convertMD5(address,token)); - } - } - - /** - * 存储登录信息 - * @param address 登录地址 - * @param token 用户标签 - */ - public static void saveAd(String address,String token){ - addMaps.put(address, token); - } - - /** - * 获取链接数据 - * @param token {@link String} 用户标识 - * @return {@link Channel} 链接实例 - */ - public static Channel getByToken(String token){ - if (isDistributed){ - if (!maps.containsKey(token)){ - //转分布式发送 - return null; - } - } - return maps.get(token); - } - - /** - * 获取对应token标签 - * @param address {@link String} 链接地址 - * @return {@link String} - */ - public static String getByAddress(String address){ - return addMaps.get(address); - } - - /** - * 删除链接数据 - * @param token {@link String} 用户标识 - */ - public static void deleteWs(String token){ - try { - maps.remove(token); - if (isDistributed){ - jedis.del(token); - } - }catch (NullPointerException e){ - throw new NotFindLoginChannlException(NotInChatConstant.Not_Login); - } - } - - /** - * 删除链接地址 - * @param address - */ - public static void deleteAd(String address){ - addMaps.remove(address); - } - - /** - * 获取链接数 - * @return {@link Integer} 链接数 - */ - public static Integer getSize(){ - if (isDistributed){ - return jedis.keys("*").size(); - } - return maps.size(); - } - - /** - * 判断是否存在链接账号 - * @param token {@link String} 用户标识 - * @return {@link Boolean} 是否存在 - */ - public static boolean hasToken(String token){ - if (isDistributed){ - return jedis.exists(token); - } - return maps.containsKey(token); - } - - /** - * 获取在线用户标签列表 - * @return {@link Set} 标识列表 - */ - public static Set getTokenList(){ - if (isDistributed){ - return jedis.keys("*"); - } - Set keys = maps.keySet(); - return keys; - } - - public static String getByJedis(String token) { - return jedis.get(token); - } -} diff --git a/src/main/java/com/github/unclecatmyself/bootstrap/channel/http/FromServerService.java b/src/main/java/com/github/unclecatmyself/bootstrap/channel/http/FromServerService.java deleted file mode 100644 index c92a28f..0000000 --- a/src/main/java/com/github/unclecatmyself/bootstrap/channel/http/FromServerService.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.github.unclecatmyself.bootstrap.channel.http; - -/** - * public enum FromServerServiceImpl implements FromServerService { - * - * TYPE1(1,"【系统通知】您的账号存在异常,请注意安全保密信息。"), - * TYPE2(2,"【系统通知】恭喜您连续登录超过5天,奖励5积分。"); - * - * private Integer code; - * - * private String message; - * - * FromServerServiceImpl(Integer code, String message){ - * this.code = code; - * this.message = message; - * } - * - * - * public Integer getCode() { - * return code; - * } - * - * - * public String findByCode(Object code) { - * Integer codes = (Integer)code; - * for (FromServerServiceImpl item: FromServerServiceImpl.values()) { - * if (item.code == codes){ - * return item.message; - * } - * } - * return null; - * } - * - * public void setCode(Integer code) { - * this.code = code; - * } - * - * public String getMessage() { - * return message; - * } - * - * public void setMessage(String message) { - * this.message = message; - * } - * - * - * } - * Created by MySelf on 2019/1/2. - */ -public interface FromServerService { - - Integer getCode(); - - String findByCode(Integer code); -} diff --git a/src/main/java/com/github/unclecatmyself/bootstrap/channel/http/HttpChannelService.java b/src/main/java/com/github/unclecatmyself/bootstrap/channel/http/HttpChannelService.java deleted file mode 100644 index 0f730a1..0000000 --- a/src/main/java/com/github/unclecatmyself/bootstrap/channel/http/HttpChannelService.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.github.unclecatmyself.bootstrap.channel.http; - -import com.github.unclecatmyself.common.bean.SendInChat; -import com.github.unclecatmyself.common.bean.vo.SendServerVO; -import io.netty.channel.Channel; -import io.netty.channel.ChannelConfig; -import io.netty.handler.codec.http.websocketx.TextWebSocketFrame; - -import java.util.Map; - -/** - * Create by UncleCatMySelf in 11:41 2018\12\31 0031 - */ -public interface HttpChannelService { - - void getSize(Channel channel); - - void sendFromServer(Channel channel,SendServerVO serverVO); - - void notFindUri(Channel channel); - - void close(Channel channel); - - void getList(Channel channel); - - void sendInChat(String token, Map msg); - - void sendByInChat(Channel channel,SendInChat sendInChat); - -} diff --git a/src/main/java/com/github/unclecatmyself/bootstrap/channel/http/HttpChannelServiceImpl.java b/src/main/java/com/github/unclecatmyself/bootstrap/channel/http/HttpChannelServiceImpl.java deleted file mode 100644 index 1063a44..0000000 --- a/src/main/java/com/github/unclecatmyself/bootstrap/channel/http/HttpChannelServiceImpl.java +++ /dev/null @@ -1,134 +0,0 @@ -package com.github.unclecatmyself.bootstrap.channel.http; - -import com.alibaba.fastjson.JSONObject; -import com.github.unclecatmyself.auto.ConfigFactory; -import com.github.unclecatmyself.bootstrap.channel.cache.WsCacheMap; -import com.github.unclecatmyself.common.bean.SendInChat; -import com.github.unclecatmyself.common.bean.vo.*; -import com.github.unclecatmyself.common.constant.HttpConstant; -import com.github.unclecatmyself.common.constant.LogConstant; -import com.github.unclecatmyself.common.constant.NotInChatConstant; -import com.github.unclecatmyself.common.utils.HttpUtil; -import com.github.unclecatmyself.common.utils.RedisUtil; -import com.google.gson.Gson; -import io.netty.buffer.ByteBuf; -import io.netty.buffer.Unpooled; -import io.netty.channel.Channel; -import io.netty.handler.codec.http.*; -import io.netty.handler.codec.http.websocketx.TextWebSocketFrame; -import io.netty.util.CharsetUtil; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.UnsupportedEncodingException; -import java.util.Date; -import java.util.Map; - -/** - * Create by UncleCatMySelf in 11:41 2018\12\31 0031 - */ -public class HttpChannelServiceImpl implements HttpChannelService { - - private static final Logger log = LoggerFactory.getLogger(HttpChannelServiceImpl.class); - - private static FromServerService fromServerService = ConfigFactory.fromServerService; - - @Override - public void getSize(Channel channel) { - FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK); - response.headers().set(HttpConstant.CONTENT_TYPE,HttpConstant.APPLICATION_JSON); - GetSizeVO getSizeVO = new GetSizeVO(WsCacheMap.getSize(),new Date()); - ResultVO resultVO = new ResultVO<>(HttpResponseStatus.OK.code(),getSizeVO); - Gson gson = new Gson(); - ByteBuf buf = Unpooled.copiedBuffer(gson.toJson(resultVO), CharsetUtil.UTF_8); - response.content().writeBytes(buf); - channel.writeAndFlush(response); - close(channel); - } - - @Override - public void sendFromServer(Channel channel, SendServerVO serverVO) { - if (serverVO.getToken() == ""){ - notFindUri(channel); - } - Channel userChannel = WsCacheMap.getByToken(serverVO.getToken()); - if (userChannel == null){ - log.info(LogConstant.HTTPCHANNELSERVICEIMPL_NOTFINDLOGIN); - notFindToken(channel); - } - String value = fromServerService.findByCode(Integer.parseInt(serverVO.getValue())); - SendServer sendServer = new SendServer(value); - try { - userChannel.writeAndFlush(new TextWebSocketFrame(JSONObject.toJSONString(sendServer))); - sendServer(channel, NotInChatConstant.SEND_SUCCESS); - }catch (Exception e){ - log.info(LogConstant.HTTPCHANNELSERVICEIMPL_SEND_EXCEPTION); - } - } - - private void sendServer(Channel channel,String msg){ - FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.BAD_REQUEST); - response.headers().set(HttpConstant.CONTENT_TYPE,HttpConstant.APPLICATION_JSON); - NotFindUriVO notFindUriVO = new NotFindUriVO(msg); - ResultVO resultVO = new ResultVO<>(HttpResponseStatus.BAD_REQUEST.code(),notFindUriVO); - Gson gson = new Gson(); - ByteBuf buf = Unpooled.copiedBuffer(gson.toJson(resultVO), CharsetUtil.UTF_8); - response.content().writeBytes(buf); - channel.writeAndFlush(response); - close(channel); - } - - private void notFindToken(Channel channel) { - sendServer(channel,NotInChatConstant.NOT_FIND_LOGIN); - } - - @Override - public void notFindUri(Channel channel) { - sendServer(channel,NotInChatConstant.NOT_FIND_URI); - } - - @Override - public void close(Channel channel) { - log.info(LogConstant.HTTPCHANNELSERVICEIMPL_CLOSE); - channel.close(); - } - - @Override - public void getList(Channel channel) { - FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK); - response.headers().set(HttpConstant.CONTENT_TYPE,HttpConstant.APPLICATION_JSON); - GetListVO getListVO = new GetListVO(WsCacheMap.getTokenList()); - ResultVO resultVO = new ResultVO<>(HttpResponseStatus.OK.code(),getListVO); - Gson gson = new Gson(); - ByteBuf buf = Unpooled.copiedBuffer(gson.toJson(resultVO), CharsetUtil.UTF_8); - response.content().writeBytes(buf); - channel.writeAndFlush(response); - close(channel); - } - - @Override - public void sendInChat(String token, Map msg) { - String address = RedisUtil.getAddress(RedisUtil.convertMD5(WsCacheMap.getByJedis(token))); - String[] str = address.split(":"); - try { - HttpClient.getInstance().send(str[0],Integer.parseInt(str[1]),token,msg); - } catch (Exception e) { - e.printStackTrace(); - } - } - - @Override - public void sendByInChat(Channel channel, SendInChat sendInChat) { - Gson gson = new Gson(); - Channel other = WsCacheMap.getByToken(sendInChat.getToken()); - try { - other.writeAndFlush(new TextWebSocketFrame(gson.toJson(sendInChat.getFrame()))); - }catch (NullPointerException e){ - e.printStackTrace(); - } -// FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.BAD_REQUEST); -// response.headers().set(HttpConstant.CONTENT_TYPE,HttpConstant.APPLICATION_JSON); -// channel.writeAndFlush(response); - close(channel); - } -} diff --git a/src/main/java/com/github/unclecatmyself/bootstrap/channel/http/HttpClient.java b/src/main/java/com/github/unclecatmyself/bootstrap/channel/http/HttpClient.java deleted file mode 100644 index cce9f11..0000000 --- a/src/main/java/com/github/unclecatmyself/bootstrap/channel/http/HttpClient.java +++ /dev/null @@ -1,94 +0,0 @@ -package com.github.unclecatmyself.bootstrap.channel.http; - -import com.github.unclecatmyself.common.bean.SendInChat; -import com.github.unclecatmyself.common.constant.HttpConstant; -import com.github.unclecatmyself.common.utils.SslUtil; -import com.google.gson.Gson; -import io.netty.buffer.Unpooled; -import io.netty.channel.*; -import io.netty.channel.nio.NioEventLoopGroup; -import io.netty.channel.socket.nio.NioSocketChannel; -import io.netty.bootstrap.Bootstrap; -import io.netty.channel.socket.SocketChannel; -import io.netty.handler.codec.http.*; -import io.netty.handler.ssl.SslContext; -import io.netty.handler.ssl.SslHandler; -import io.netty.util.CharsetUtil; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLEngine; -import java.net.URI; -import java.util.Map; - -/** - * Create by UncleCatMySelf in 17:47 2019\1\5 0005 - */ -public class HttpClient { - - private static final Logger log = LoggerFactory.getLogger(HttpClient.class); - - private static HttpClient instance = new HttpClient(); - - public static Bootstrap bootstrap; - - private HttpClient(){ - EventLoopGroup workerGroup = new NioEventLoopGroup(); - Bootstrap b = new Bootstrap(); - b.group(workerGroup); - b.channel(NioSocketChannel.class); - b.option(ChannelOption.SO_KEEPALIVE, true); - b.handler(new ChannelInitializer() { - @Override - public void initChannel(SocketChannel ch) throws Exception { - // 客户端接收到的是httpResponse响应,所以要使用HttpResponseDecoder进行解码 - ch.pipeline().addLast(new HttpResponseDecoder()); - // 客户端发送的是httprequest,所以要使用HttpRequestEncoder进行编码 - ch.pipeline().addLast(new HttpRequestEncoder()); - try { - SSLContext context = SslUtil.createSSLContext("JKS","inchat.jks","123456"); - SSLEngine engine = context.createSSLEngine(); - engine.setUseClientMode(true); -// engine.setNeedClientAuth(false); - ch.pipeline().addLast("ssl",new SslHandler(engine)); - }catch (Exception e){ - e.printStackTrace(); - } - } - }); - this.bootstrap = b; - } - - public static HttpClient getInstance(){ - return instance; - } - - public void send(String host, int port,String token,Map value) throws Exception { - // Start the client. - ChannelFuture f = this.bootstrap.connect(host, port).sync(); - - URI uri = new URI(HttpConstant.URI_SENDINCHAT); - - Gson gson = new Gson(); - String content = gson.toJson(new SendInChat(token,value)); - DefaultFullHttpRequest request = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.POST, - uri.toASCIIString(),Unpooled.wrappedBuffer(content.getBytes(CharsetUtil.UTF_8))); - - // 构建http请求 - request.headers().set(HttpHeaderNames.HOST, host); - request.headers().set(HttpHeaderNames.CONNECTION, HttpHeaderValues.KEEP_ALIVE); - request.headers().set(HttpHeaderNames.CONTENT_LENGTH, request.content().readableBytes()); -// request.headers().set(HttpHeaderNames.CONTENT_TYPE,HttpHeaderValues.APPLICATION_X_WWW_FORM_URLENCODED); - - // 发送http请求 - f.channel().write(request); - f.channel().flush(); - f.channel().closeFuture().sync(); - } - -// public static void main(String[] args) throws Exception { -// HttpClient client = new HttpClient(); -// client.connect("192.168.1.121",8090); -// } - -} diff --git a/src/main/java/com/github/unclecatmyself/bootstrap/channel/ws/WebSocketChannelService.java b/src/main/java/com/github/unclecatmyself/bootstrap/channel/ws/WebSocketChannelService.java deleted file mode 100644 index f5ad892..0000000 --- a/src/main/java/com/github/unclecatmyself/bootstrap/channel/ws/WebSocketChannelService.java +++ /dev/null @@ -1,51 +0,0 @@ -package com.github.unclecatmyself.bootstrap.channel.ws; - -import com.google.gson.Gson; -import com.github.unclecatmyself.bootstrap.channel.cache.WsCacheMap; -import io.netty.channel.Channel; -import io.netty.handler.codec.http.websocketx.TextWebSocketFrame; - -import java.util.Map; - -/** - * Created by MySelf on 2018/11/26. - */ -public class WebSocketChannelService implements WsChannelService { - - @Override - public void loginWsSuccess(Channel channel, String token) { - WsCacheMap.saveWs(token,channel); - WsCacheMap.saveAd(channel.remoteAddress().toString(),token); - } - - @Override - public boolean hasOther(String otherOne) { - return WsCacheMap.hasToken(otherOne); - } - - @Override - public Channel getChannel(String otherOne) { - return WsCacheMap.getByToken(otherOne); - } - - @Override - public void close(Channel channel) { - String token = WsCacheMap.getByAddress(channel.remoteAddress().toString()); - WsCacheMap.deleteAd(channel.remoteAddress().toString()); - WsCacheMap.deleteWs(token); - channel.close(); - } - - @Override - public boolean sendFromServer(Channel channel, Map map) { - Gson gson = new Gson(); - try { - channel.writeAndFlush(new TextWebSocketFrame(gson.toJson(map))); - return true; - }catch (Exception e){ - return false; - } - } - - -} diff --git a/src/main/java/com/github/unclecatmyself/bootstrap/channel/ws/WsChannelService.java b/src/main/java/com/github/unclecatmyself/bootstrap/channel/ws/WsChannelService.java deleted file mode 100644 index e3b8113..0000000 --- a/src/main/java/com/github/unclecatmyself/bootstrap/channel/ws/WsChannelService.java +++ /dev/null @@ -1,47 +0,0 @@ -package com.github.unclecatmyself.bootstrap.channel.ws; - -import io.netty.channel.Channel; - -import java.util.Map; - -/** - * WebSocket 聊天业务消息处理 - * Created by MySelf on 2018/11/26. - */ -public interface WsChannelService { - - /** - * 登录成功存储到本地缓存 - * @param channel {@link Channel} 链接实例 - * @param token {@link String} 用户标识 - */ - void loginWsSuccess(Channel channel, String token); - - /** - * 判断是否存在当前在线用户 - * @param otherOne {@link String} 某人的用户标识 - * @return {@link Boolean} 是否存在 - */ - boolean hasOther(String otherOne); - - /** - * 获取某人的链接实例 - * @param otherOne {@link String} 用户唯一标识 - * @return {@link Channel} 链接实例 - */ - Channel getChannel(String otherOne); - - /** - * 删除链接与本地存储信息 - * @param channel {@link Channel} 链接实例 - */ - void close(Channel channel); - - /** - * 以服务端API调用向链接发送信息 - * @param channel {@link } - * @param map - * @return - */ - boolean sendFromServer(Channel channel, Map map); -} diff --git a/src/main/java/com/github/unclecatmyself/bootstrap/data/InChatToDataBaseService.java b/src/main/java/com/github/unclecatmyself/bootstrap/data/InChatToDataBaseService.java deleted file mode 100644 index 623f7ca..0000000 --- a/src/main/java/com/github/unclecatmyself/bootstrap/data/InChatToDataBaseService.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.github.unclecatmyself.bootstrap.data; - -import com.github.unclecatmyself.common.bean.InChatMessage; - -import java.util.Map; - -/** - * Created by MySelf on 2018/12/3. - */ -public interface InChatToDataBaseService { - - Boolean writeMessage(InChatMessage message); - -} diff --git a/src/main/java/com/github/unclecatmyself/bootstrap/handler/DefaultHandler.java b/src/main/java/com/github/unclecatmyself/bootstrap/handler/DefaultHandler.java deleted file mode 100644 index 3c0645f..0000000 --- a/src/main/java/com/github/unclecatmyself/bootstrap/handler/DefaultHandler.java +++ /dev/null @@ -1,154 +0,0 @@ -package com.github.unclecatmyself.bootstrap.handler; - -import com.alibaba.fastjson.JSON; -import com.github.unclecatmyself.common.base.Handler; -import com.github.unclecatmyself.common.base.HandlerApi; -import com.github.unclecatmyself.common.base.HandlerService; -import com.github.unclecatmyself.common.bean.vo.SendServerVO; -import com.github.unclecatmyself.common.constant.Constans; -import com.github.unclecatmyself.common.constant.HttpConstant; -import com.github.unclecatmyself.common.constant.LogConstant; -import com.github.unclecatmyself.common.constant.NotInChatConstant; -import com.github.unclecatmyself.common.exception.NoFindHandlerException; -import com.github.unclecatmyself.common.utils.HttpUtil; -import io.netty.channel.Channel; -import io.netty.channel.ChannelHandler; -import io.netty.channel.ChannelHandlerContext; -import io.netty.handler.codec.http.*; -import io.netty.handler.codec.http.websocketx.BinaryWebSocketFrame; -import io.netty.handler.codec.http.websocketx.TextWebSocketFrame; -import io.netty.handler.codec.http.websocketx.WebSocketFrame; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import java.io.UnsupportedEncodingException; -import java.util.Date; -import java.util.Map; - -/** - * Create by UncleCatMySelf in 2018/12/06 - */ -@ChannelHandler.Sharable -public class DefaultHandler extends Handler { - - private final Logger log = LoggerFactory.getLogger(DefaultHandler.class); - - private final HandlerApi handlerApi; - - public DefaultHandler(HandlerApi handlerApi) { - super(handlerApi); - this.handlerApi = handlerApi; - } - - @Override - protected void webdoMessage(ChannelHandlerContext ctx, WebSocketFrame msg) { - Channel channel = ctx.channel(); - HandlerService httpHandlerService; - if (handlerApi instanceof HandlerService){ - httpHandlerService = (HandlerService)handlerApi; - }else { - throw new NoFindHandlerException(NotInChatConstant.NOT_HANDLER); - } - if (msg instanceof BinaryWebSocketFrame){ - //TODO 实现图片处理 - } - } - - @Override - protected void httpdoMessage(ChannelHandlerContext ctx, FullHttpRequest msg) { - Channel channel = ctx.channel(); - HandlerService httpHandlerService; - if (handlerApi instanceof HandlerService){ - httpHandlerService = (HandlerService)handlerApi; - }else { - throw new NoFindHandlerException(NotInChatConstant.NOT_HANDLER); - } - switch (HttpUtil.checkType(msg)){ - case HttpConstant.GETSIZE: - log.info(LogConstant.DEFAULTWEBSOCKETHANDLER_GETSIZE); - httpHandlerService.getSize(channel); - break; - case HttpConstant.SENDFROMSERVER: - log.info(LogConstant.DEFAULTWEBSOCKETHANDLER_SENDFROMSERVER); - SendServerVO serverVO = null; - try { - serverVO = HttpUtil.getToken(msg); - } catch (UnsupportedEncodingException e) { - log.error(e.getMessage()); - } - httpHandlerService.sendFromServer(channel,serverVO); - break; - case HttpConstant.GETLIST: - log.info(LogConstant.DEFAULTWEBSOCKETHANDLER_GETLIST); - httpHandlerService.getList(channel); - break; - case HttpConstant.SENDINCHAT: - log.info(LogConstant.DEFAULTWEBSOCKETHANDLER_SENDINCHAT); - httpHandlerService.sendInChat(channel,msg); - break; - case HttpConstant.NOTFINDURI: - log.info(LogConstant.DEFAULTWEBSOCKETHANDLER_NOTFINDURI); - httpHandlerService.notFindUri(channel); - break; - default: - System.out.println("为匹配"+msg); - break; - } - } - - @Override - protected void textdoMessage(ChannelHandlerContext ctx, TextWebSocketFrame msg) { - Channel channel = ctx.channel(); - HandlerService handlerService; - if (handlerApi instanceof HandlerService){ - handlerService = (HandlerService)handlerApi; - }else{ - throw new NoFindHandlerException(NotInChatConstant.NOT_HANDLER); - } - Map maps = (Map) JSON.parse(msg.text()); - maps.put(Constans.TIME, new Date()); - switch ((String)maps.get(Constans.TYPE)){ - case Constans.LOGIN: - log.info(LogConstant.DEFAULTWEBSOCKETHANDLER_LOGIN); - handlerService.login(channel,maps); - break; - //针对个人,发送给自己 - case Constans.SENDME: - log.info(LogConstant.DEFAULTWEBSOCKETHANDLER_SENDME); - handlerService.verify(channel,maps); - handlerService.sendMeText(channel,maps); - break; - //针对个人,发送给某人 - case Constans.SENDTO: - log.info(LogConstant.DefaultWebSocketHandler_SENDTO); - handlerService.verify(channel,maps); - handlerService.sendToText(channel,maps); - break; - //发送给群组 - case Constans.SENDGROUP: - log.info(LogConstant.DEFAULTWEBSOCKETHANDLER_SENDGROUP); - handlerService.verify(channel,maps); - handlerService.sendGroupText(channel,maps); - break; - //发送图片,发送给自己 - case Constans.SENDPHOTOTOME: - log.info("图片到个人"); - handlerService.verify(channel,maps); - handlerService.sendPhotoToMe(channel,maps); - break; - default: - break; - } - } - - @Override - public void channelActive(ChannelHandlerContext ctx) throws Exception { - log.info(LogConstant.CHANNELACTIVE+ctx.channel().remoteAddress().toString()+LogConstant.CHANNEL_SUCCESS); - } - - @Override - public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception{ -// log.error("exception",cause); - log.info(LogConstant.EXCEPTIONCAUGHT+ctx.channel().remoteAddress().toString()+LogConstant.DISCONNECT); - ctx.close(); - } -} diff --git a/src/main/java/com/github/unclecatmyself/bootstrap/redisclient/testApplication.java b/src/main/java/com/github/unclecatmyself/bootstrap/redisclient/testApplication.java deleted file mode 100644 index afcbcc0..0000000 --- a/src/main/java/com/github/unclecatmyself/bootstrap/redisclient/testApplication.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.github.unclecatmyself.bootstrap.redisclient; - -import redis.clients.jedis.Jedis; - -/** - * Create by UncleCatMySelf in 23:02 2019\1\4 0004 - */ -public class testApplication { - - public static void main(String[] args) { - //连接redis服务 - Jedis jedis = new Jedis("192.168.12.129"); - System.out.println("连接成功"); - //设置redis字符串数据 - //jedis.set("token","inchat"); - //查看服务是否运行 - System.out.println("服务正在运行:"+jedis.ping()); - //获取存储的数据并输出 - System.out.println("redis存储的字符串为:"+jedis.get("token")); - } - -} diff --git a/src/main/java/com/github/unclecatmyself/bootstrap/verify/InChatVerifyService.java b/src/main/java/com/github/unclecatmyself/bootstrap/verify/InChatVerifyService.java deleted file mode 100644 index 0854bfd..0000000 --- a/src/main/java/com/github/unclecatmyself/bootstrap/verify/InChatVerifyService.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.github.unclecatmyself.bootstrap.verify; - -import com.alibaba.fastjson.JSONArray; - -/** - * 用户校验层 - * Created by MySelf on 2018/11/22. - */ -public interface InChatVerifyService { - - boolean verifyToken(String token); - - JSONArray getArrayByGroupId(String groupId); - -} \ No newline at end of file diff --git a/src/main/java/com/github/unclecatmyself/common/base/Handler.java b/src/main/java/com/github/unclecatmyself/common/base/Handler.java deleted file mode 100644 index cdcec7e..0000000 --- a/src/main/java/com/github/unclecatmyself/common/base/Handler.java +++ /dev/null @@ -1,64 +0,0 @@ -package com.github.unclecatmyself.common.base; - -import com.github.unclecatmyself.common.constant.LogConstant; -import com.github.unclecatmyself.common.exception.NotFindLoginChannlException; -import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.SimpleChannelInboundHandler; -import io.netty.handler.codec.http.FullHttpRequest; -import io.netty.handler.codec.http.websocketx.TextWebSocketFrame; -import io.netty.handler.codec.http.websocketx.WebSocketFrame; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * Netty实现初始层 - * Create by UncleCatMySelf in 2018/12/06 - */ -public abstract class Handler extends SimpleChannelInboundHandler { - - private static final Logger log = LoggerFactory.getLogger(Handler.class); - - HandlerApi handlerApi; - - public Handler(HandlerApi handlerApi){ - this.handlerApi = handlerApi; - } - - @Override - protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception { - if (msg instanceof TextWebSocketFrame){ - System.out.println("TextWebSocketFrame"+msg); - textdoMessage(ctx,(TextWebSocketFrame)msg); - }else if (msg instanceof WebSocketFrame){ - System.out.println("WebSocketFrame"+msg); - webdoMessage(ctx,(WebSocketFrame)msg); - }else if (msg instanceof FullHttpRequest){ - System.out.println("FullHttpRequest"+msg); - httpdoMessage(ctx,(FullHttpRequest)msg); - } - } - - protected abstract void webdoMessage(ChannelHandlerContext ctx, WebSocketFrame msg); - - protected abstract void textdoMessage(ChannelHandlerContext ctx, TextWebSocketFrame msg); - - protected abstract void httpdoMessage(ChannelHandlerContext ctx, FullHttpRequest msg); - - @Override - public void channelInactive(ChannelHandlerContext ctx) throws Exception { - log.info(LogConstant.CHANNELINACTIVE+ctx.channel().localAddress().toString()+LogConstant.CLOSE_SUCCESS); - try { - handlerApi.close(ctx.channel()); - }catch (NotFindLoginChannlException e){ - log.error(LogConstant.NOTFINDLOGINCHANNLEXCEPTION); - } - } - - @Override - public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { -// if(evt instanceof IdleStateEvent){ -// webSocketHandlerApi.doTimeOut(ctx.channel(),(IdleStateEvent)evt); -// } - super.userEventTriggered(ctx, evt); - } -} diff --git a/src/main/java/com/github/unclecatmyself/common/base/HandlerApi.java b/src/main/java/com/github/unclecatmyself/common/base/HandlerApi.java deleted file mode 100644 index 536c0ad..0000000 --- a/src/main/java/com/github/unclecatmyself/common/base/HandlerApi.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.github.unclecatmyself.common.base; - -import io.netty.channel.Channel; - -import java.util.Map; - -/** - * Create by UncleCatMySelf in 2018/12/06 - */ -public interface HandlerApi { - - void close(Channel channel); - -} diff --git a/src/main/java/com/github/unclecatmyself/common/base/HandlerService.java b/src/main/java/com/github/unclecatmyself/common/base/HandlerService.java deleted file mode 100644 index 0463e42..0000000 --- a/src/main/java/com/github/unclecatmyself/common/base/HandlerService.java +++ /dev/null @@ -1,88 +0,0 @@ -package com.github.unclecatmyself.common.base; - -import com.github.unclecatmyself.common.bean.vo.SendServerVO; -import io.netty.channel.Channel; -import io.netty.handler.codec.http.FullHttpMessage; - -import java.util.Map; - -/** - * 业务层伪接口 - * Created by MySelf on 2018/11/21. - */ -public abstract class HandlerService implements HandlerApi { - - /** - * HTTP获取在线用户标签列表 - * @param channel {@link Channel} 链接实例 - */ - public abstract void getList(Channel channel); - - /** - * HTTP获取在线用户数 - * @param channel {@link Channel} 链接实例 - */ - public abstract void getSize(Channel channel); - - /** - * HTTP以服务端向指定用户发送通知 - * @param channel {@link Channel} 链接实例 - * @param sendServerVO {@link SendServerVO} 用户标识 - */ - public abstract void sendFromServer(Channel channel,SendServerVO sendServerVO); - - /** - * HTTP以服务端处理发送 - * @param channel - */ - public abstract void sendInChat(Channel channel, FullHttpMessage msg); - - /** - * 用户未找到匹配Uri - * @param channel {@link Channel} 链接实例 - */ - public abstract void notFindUri(Channel channel); - - /** - * 登录类型 - * @param channel {@link Channel} 链接实例 - * @param map {@link Map} 数据信息 - * @return {@link Boolean} 成功失败 - */ - public abstract boolean login(Channel channel, Map map); - - /** - * 发送给自己 - * @param channel {@link Channel} 链接实例 - * @param maps {@link Map} 数据信息 - */ - public abstract void sendMeText(Channel channel,Map maps); - - /** - * 发送给某人 - * @param channel {@link Channel} 链接实例 - * @param maps {@link Map} 数据信息 - */ - public abstract void sendToText(Channel channel, Map maps); - - /** - * 发送给群聊 - * @param channel {@link Channel} 链接实例 - * @param maps {@link Map} 数据信息 - */ - public abstract void sendGroupText(Channel channel, Map maps); - - /** - * 登录校验 - * @param channel {@link Channel} 链接实例 - * @param maps {@link Map} 数据信息 - */ - public abstract void verify(Channel channel, Map maps); - - /** - * 发送图片给个人 - * @param channel {@link Channel} 链接实例 - * @param maps {@link Map} 数据信息 - */ - public abstract void sendPhotoToMe(Channel channel, Map maps); -} diff --git a/src/main/java/com/github/unclecatmyself/common/bean/InChatMessage.java b/src/main/java/com/github/unclecatmyself/common/bean/InChatMessage.java deleted file mode 100644 index 847e74a..0000000 --- a/src/main/java/com/github/unclecatmyself/common/bean/InChatMessage.java +++ /dev/null @@ -1,113 +0,0 @@ -package com.github.unclecatmyself.common.bean; - -import java.util.ArrayList; -import java.util.Date; - -/** - * 用户层消息Bean封装 - * Created by MySelf on 2018/12/19. - */ -public class InChatMessage { - - /** 消息时间 */ - private Date time; - - /** 消息类型 */ - private String type; - - /** 消息值 */ - private String value; - - /** 用户标识 */ - private String token; - - /** 群聊Id */ - private String groudId; - - /** 是否在线-个人 */ - private String online; - - /** 是否在线-群聊 */ - private ArrayList onlineGroup; - - /** 消息接收人标识 */ - private String one; - - public ArrayList getOnlineGroup() { - return onlineGroup; - } - - public void setOnlineGroup(ArrayList onlineGroup) { - this.onlineGroup = onlineGroup; - } - - public Date getTime() { - return time; - } - - public void setTime(Date time) { - this.time = time; - } - - public String getType() { - return type; - } - - public void setType(String type) { - this.type = type; - } - - public String getValue() { - return value; - } - - public void setValue(String value) { - this.value = value; - } - - public String getToken() { - return token; - } - - public void setToken(String token) { - this.token = token; - } - - public String getGroudId() { - return groudId; - } - - public void setGroudId(String groudId) { - this.groudId = groudId; - } - - public String getOnline() { - return online; - } - - public void setOnline(String online) { - this.online = online; - } - - public String getOne() { - return one; - } - - public void setOne(String one) { - this.one = one; - } - - @Override - public String toString() { - return "InChatMessage{" + - "time=" + time + - ", type='" + type + '\'' + - ", value='" + value + '\'' + - ", token='" + token + '\'' + - ", groudId='" + groudId + '\'' + - ", online='" + online + '\'' + - ", onlineGroup=" + onlineGroup + - ", one='" + one + '\'' + - '}'; - } -} diff --git a/src/main/java/com/github/unclecatmyself/common/bean/InitNetty.java b/src/main/java/com/github/unclecatmyself/common/bean/InitNetty.java deleted file mode 100644 index 7922764..0000000 --- a/src/main/java/com/github/unclecatmyself/common/bean/InitNetty.java +++ /dev/null @@ -1,243 +0,0 @@ -package com.github.unclecatmyself.common.bean; - -import com.github.unclecatmyself.bootstrap.handler.DefaultHandler; - -/** - * 初始化Netty配置 - * Create by UncleCatMySelf in 2018/12/06 - */ -public abstract class InitNetty { - - /** 通信地址 */ - private int webport = 8090; - - private int bossThread = 1; - - private int workerThread = 2; - - private boolean keepalive = true; - - private int backlog = 1024; - - private boolean nodelay = true; - - private boolean reuseaddr = true; - - private int sndbuf = 10485760; - - private int revbuf = 10485760; - - private int heart = 180; - - private int period = 10; - - private String serverName = "iot-netty-chat"; - - private int initalDelay = 10; - - private int maxContext = 65536; - - private String webSocketPath = "/ws"; - - /** 是否启动分布式 */ - private Boolean isDistributed = false; - - /** 是否启动加密 */ - private boolean ssl = false; - - private String jksFile = "inchat.jks"; - - private String jksStorePassword = "123456"; - - private String jksCertificatePassword = "123456"; - - private Class webSocketHandler = DefaultHandler.class; - - public Boolean getDistributed() { - return isDistributed; - } - - public void setDistributed(Boolean distributed) { - isDistributed = distributed; - } - - /** - * 返回WebSocket启动监听端口 - * @return {@link Integer} WebSocket端口 - */ - public int getWebport() { - return webport; - } - - /** - * 返回Netty核心线程个数 - * @return {@link Integer} Netty线程个数 - */ - public int getBossThread() { - return bossThread; - } - - public void setBossThread(int bossThread) { - this.bossThread = bossThread; - } - - /** - * 返回Netty工作线程个数 - * @return {@link Integer} Netty工作线程个数 - */ - public int getWorkerThread() { - return workerThread; - } - - public void setWorkerThread(int workerThread) { - this.workerThread = workerThread; - } - - /** - * 是否保持链接 - * @return {@link Boolean} 是否保持链接 - */ - public boolean isKeepalive() { - return keepalive; - } - - /** - * 服务端接受连接的队列长度,如果队列已满,客户端连接将被拒绝 - * @return {@link Integer} 服务端接受连接的队列长度 - */ - public int getBacklog() { - return backlog; - } - - public void setBacklog(int backlog) { - this.backlog = backlog; - } - - /** - * TCP参数,立即发送数据,默认值为Ture(Netty默认为True而操作系统默认为False)。 - * 该值设置Nagle算法的启用,改算法将小的碎片数据连接成更大的报文来最小化所发送的报文的数量, - * 如果需要发送一些较小的报文,则需要禁用该算法。Netty默认禁用该算法,从而最小化报文传输延时。 - * @return {@link Boolean} Nagle算法是否启用 - */ - public boolean isNodelay() { - return nodelay; - } - - /** - * 地址复用,默认值False。有四种情况可以使用: - * (1).当有一个有相同本地地址和端口的socket1处于TIME_WAIT状态时,而你希望启动的程序的socket2要占用该地址和端口,比如重启服务且保持先前端口。 - * (2).有多块网卡或用IP Alias技术的机器在同一端口启动多个进程,但每个进程绑定的本地IP地址不能相同。 - * (3).单个进程绑定相同的端口到多个socket上,但每个socket绑定的ip地址不同。 - * (4).完全相同的地址和端口的重复绑定。但这只用于UDP的多播,不用于TCP。 - * @return {@link Boolean} 地址复用 - */ - public boolean isReuseaddr() { - return reuseaddr; - } - - - /** - * TCP数据接收缓冲区大小。 - * @return {@link Integer} TCP数据接收缓冲区大小。 - */ - public int getRevbuf() { - return revbuf; - } - - public void setRevbuf(int revbuf) { - this.revbuf = revbuf; - } - - /** - * 读超时时间 - * @return {@link Integer} 读超时时间 - */ - public int getHeart() { - return heart; - } - - public void setHeart(int heart) { - this.heart = heart; - } - - /** - * 消息 重发周期 - * @return {@link Integer} 消息重发周期 - */ - public int getPeriod() { - return period; - } - - public void setPeriod(int period) { - this.period = period; - } - - /** - * 服务名称 - * @return {@link String} 服务名称 - */ - public String getServerName() { - return serverName; - } - - /** - * 消息 重发延迟 - * @return {@link Integer} 消息重发延迟 - */ - public int getInitalDelay() { - return initalDelay; - } - - public void setInitalDelay(int initalDelay) { - this.initalDelay = initalDelay; - } - - public int getMaxContext() { - return maxContext; - } - - /** - * WebSocket URL 后缀地址 - * @return {@link String} WebSocket URL 后缀地址 - */ - public String getWebSocketPath() { - return webSocketPath; - } - - - public Class getWebSocketHandler() { - return webSocketHandler; - } - - public boolean isSsl() { - return ssl; - } - - public void setSsl(boolean ssl) { - this.ssl = ssl; - } - - public String getJksFile() { - return jksFile; - } - - public void setJksFile(String jksFile) { - this.jksFile = jksFile; - } - - public String getJksStorePassword() { - return jksStorePassword; - } - - public void setJksStorePassword(String jksStorePassword) { - this.jksStorePassword = jksStorePassword; - } - - public String getJksCertificatePassword() { - return jksCertificatePassword; - } - - public void setJksCertificatePassword(String jksCertificatePassword) { - this.jksCertificatePassword = jksCertificatePassword; - } -} diff --git a/src/main/java/com/github/unclecatmyself/common/bean/SendInChat.java b/src/main/java/com/github/unclecatmyself/common/bean/SendInChat.java deleted file mode 100644 index 3946077..0000000 --- a/src/main/java/com/github/unclecatmyself/common/bean/SendInChat.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.github.unclecatmyself.common.bean; - -import io.netty.handler.codec.http.websocketx.TextWebSocketFrame; - -import java.util.Map; - -/** - * Create by UncleCatMySelf in 16:06 2019\1\5 0005 - */ -public class SendInChat { - - private String token; - - private Map frame; - - public SendInChat() { - } - - public SendInChat(String token, Map frame) { - this.token = token; - this.frame = frame; - } - - public String getToken() { - return token; - } - - public void setToken(String token) { - this.token = token; - } - - public Map getFrame() { - return frame; - } - - public void setFrame(Map frame) { - this.frame = frame; - } -} diff --git a/src/main/java/com/github/unclecatmyself/common/bean/vo/GetListVO.java b/src/main/java/com/github/unclecatmyself/common/bean/vo/GetListVO.java deleted file mode 100644 index 43abe08..0000000 --- a/src/main/java/com/github/unclecatmyself/common/bean/vo/GetListVO.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.github.unclecatmyself.common.bean.vo; - -import java.util.Set; - -/** - * Create by UncleCatMySelf in 12:26 2018\12\31 0031 - */ -public class GetListVO { - - - - private Set tokens; - - public GetListVO(Set tokens) { - this.tokens = tokens; - } - - public Set getTokens() { - return tokens; - } - - public void setTokens(Set tokens) { - this.tokens = tokens; - } -} diff --git a/src/main/java/com/github/unclecatmyself/common/bean/vo/GetSizeVO.java b/src/main/java/com/github/unclecatmyself/common/bean/vo/GetSizeVO.java deleted file mode 100644 index 691da26..0000000 --- a/src/main/java/com/github/unclecatmyself/common/bean/vo/GetSizeVO.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.github.unclecatmyself.common.bean.vo; - -import java.util.Date; - -/** - * Create by UncleCatMySelf in 11:13 2018\12\31 0031 - */ -public class GetSizeVO { - - private Integer online; - - private Date time; - - public GetSizeVO(Integer online, Date time) { - this.online = online; - this.time = time; - } - - public Integer getOnline() { - return online; - } - - public void setOnline(Integer online) { - this.online = online; - } - - public Date getTime() { - return time; - } - - public void setTime(Date time) { - this.time = time; - } -} diff --git a/src/main/java/com/github/unclecatmyself/common/bean/vo/NotFindUriVO.java b/src/main/java/com/github/unclecatmyself/common/bean/vo/NotFindUriVO.java deleted file mode 100644 index b4fadba..0000000 --- a/src/main/java/com/github/unclecatmyself/common/bean/vo/NotFindUriVO.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.github.unclecatmyself.common.bean.vo; - -/** - * Create by UncleCatMySelf in 11:21 2018\12\31 0031 - */ -public class NotFindUriVO { - - private String message; - - public NotFindUriVO(String message) { - this.message = message; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } -} diff --git a/src/main/java/com/github/unclecatmyself/common/bean/vo/ResultVO.java b/src/main/java/com/github/unclecatmyself/common/bean/vo/ResultVO.java deleted file mode 100644 index db52fa8..0000000 --- a/src/main/java/com/github/unclecatmyself/common/bean/vo/ResultVO.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.github.unclecatmyself.common.bean.vo; - -/** - * Create by UncleCatMySelf in 11:11 2018\12\31 0031 - */ -public class ResultVO { - - private int code; - - private T data; - - public ResultVO(int code, T data) { - this.code = code; - this.data = data; - } - - public int getCode() { - return code; - } - - public void setCode(int code) { - this.code = code; - } - - public T getData() { - return data; - } - - public void setData(T data) { - this.data = data; - } - - @Override - public String toString() { - return "ResultVO{" + - "code=" + code + - ", data=" + data + - '}'; - } -} diff --git a/src/main/java/com/github/unclecatmyself/common/bean/vo/SendServer.java b/src/main/java/com/github/unclecatmyself/common/bean/vo/SendServer.java deleted file mode 100644 index e03a0ef..0000000 --- a/src/main/java/com/github/unclecatmyself/common/bean/vo/SendServer.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.github.unclecatmyself.common.bean.vo; - -import com.github.unclecatmyself.common.constant.Constans; - -/** - * Created by MySelf on 2019/1/3. - */ -public class SendServer { - - private String type = Constans.SERVER; - - private String value; - - public SendServer(String value) { - this.value = value; - } - - public String getType() { - return type; - } - - public void setType(String type) { - this.type = type; - } - - public String getValue() { - return value; - } - - public void setValue(String value) { - this.value = value; - } -} diff --git a/src/main/java/com/github/unclecatmyself/common/bean/vo/SendServerVO.java b/src/main/java/com/github/unclecatmyself/common/bean/vo/SendServerVO.java deleted file mode 100644 index f5c66fb..0000000 --- a/src/main/java/com/github/unclecatmyself/common/bean/vo/SendServerVO.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.github.unclecatmyself.common.bean.vo; - -/** - * Created by MySelf on 2019/1/2. - */ -public class SendServerVO { - - private String token; - - private String value; - - public String getToken() { - return token; - } - - public void setToken(String token) { - this.token = token; - } - - public String getValue() { - return value; - } - - public void setValue(String value) { - this.value = value; - } -} diff --git a/src/main/java/com/github/unclecatmyself/common/constant/BootstrapConstant.java b/src/main/java/com/github/unclecatmyself/common/constant/BootstrapConstant.java deleted file mode 100644 index a8e51ad..0000000 --- a/src/main/java/com/github/unclecatmyself/common/constant/BootstrapConstant.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.github.unclecatmyself.common.constant; - -/** - * Created by MySelf on 2019/1/3. - */ -public class BootstrapConstant { - - public static final String HTTPCODE = "httpCode"; - - public static final String AGGREGATOR = "aggregator"; - - public static final String CHUNKEDWRITE = "chunkedWrite"; - - public static final String WEBSOCKETHANDLER = "webSocketHandler"; - - public static final String SSL = "ssl"; - -} diff --git a/src/main/java/com/github/unclecatmyself/common/constant/Constans.java b/src/main/java/com/github/unclecatmyself/common/constant/Constans.java deleted file mode 100644 index f70c988..0000000 --- a/src/main/java/com/github/unclecatmyself/common/constant/Constans.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.github.unclecatmyself.common.constant; - -/** - * Created by MySelf on 2018/12/5. - */ -public class Constans { - - public static final String TOKEN = "token"; - - public static final String VALUE = "value"; - - public static final String ONE = "one"; - - public static final String ON_ONLINE = "on_online"; - - public static final String ONLINE_GROUP = "online_group"; - - public static final String GROUPID = "groupId"; - - public static final String TYPE = "type"; - - public static final String LOGIN = "login"; - - public static final String SUCCESS = "success"; - - public static final String TRUE = "true"; - - public static final String FALSE = "false"; - - public static final String SENDME = "sendMe"; - - public static final String SENDTO = "sendTo"; - - public static final String FROM = "from"; - - public static final String SENDGROUP = "sendGroup"; - - public static final String SENDPHOTOTOME = "sendPhotoToMe"; - - public static final String TIME = "time"; - - public static final String SERVER = "server"; -} diff --git a/src/main/java/com/github/unclecatmyself/common/constant/HttpConstant.java b/src/main/java/com/github/unclecatmyself/common/constant/HttpConstant.java deleted file mode 100644 index 971d94e..0000000 --- a/src/main/java/com/github/unclecatmyself/common/constant/HttpConstant.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.github.unclecatmyself.common.constant; - -/** - * Create by UncleCatMySelf in 22:49 2018\12\30 0030 - */ -public class HttpConstant { - - public static final String GET = "GET"; - - public static final String POST = "POST"; - - public static final String GETSIZE = "get_size"; - - public static final String GETLIST = "get_list"; - - public static final String SENDINCHAT = "send_inchat"; - - public static final String SENDFROMSERVER = "send_from_server"; - - public static final String NOTFINDURI = "not_find_uri"; - - public static final String URI_GETSIZE = "/get_size"; - - public static final String URI_GETLIST = "/get_list"; - - public static final String URI_SENDINCHAT = "/send_inchat"; - - public static final String URI_SENDFROMSERVER = "/send_from_server"; - - public static final String CONTENT_TYPE = "Content-Type"; - - public static final String APPLICATION_JSON = "application/json;charset=UTF-8"; -} diff --git a/src/main/java/com/github/unclecatmyself/common/constant/LogConstant.java b/src/main/java/com/github/unclecatmyself/common/constant/LogConstant.java deleted file mode 100644 index 87f667e..0000000 --- a/src/main/java/com/github/unclecatmyself/common/constant/LogConstant.java +++ /dev/null @@ -1,53 +0,0 @@ -package com.github.unclecatmyself.common.constant; - -/** - * Created by MySelf on 2019/1/3. - */ -public class LogConstant { - - public static final String HTTPCHANNELSERVICEIMPL_NOTFINDLOGIN = "[HttpChannelServiceImpl.sendFromServer] 未找到用户在线标识"; - - public static final String HTTPCHANNELSERVICEIMPL_CLOSE = "[HttpChannelServiceImpl.close] 关闭HTTP通道连接"; - - public static final String HTTPCHANNELSERVICEIMPL_SEND_EXCEPTION = "[HttpChannelServiceImpl.sendFromServer] 发送通知异常"; - - public static final String DEFAULTWEBSOCKETHANDLER_GETSIZE = "[DefaultWebSocketHandler.httpdoMessage.GETSIZE]"; - - public static final String DEFAULTWEBSOCKETHANDLER_SENDFROMSERVER = "[DefaultWebSocketHandler.httpdoMessage.SENDFROMSERVER]"; - - public static final String DEFAULTWEBSOCKETHANDLER_NOTFINDURI = "[DefaultWebSocketHandler.httpdoMessage.NOTFINDURI]"; - - public static final String DEFAULTWEBSOCKETHANDLER_GETLIST = "[DefaultWebSocketHandler.httpdoMessage.GETLIST]"; - - public static final String DEFAULTWEBSOCKETHANDLER_SENDINCHAT = "[DefaultWebSocketHandler.httpdoMessage.SENDINCHAT]"; - - public static final String DEFAULTWEBSOCKETHANDLER_LOGIN = "[DefaultWebSocketHandler.textdoMessage.LOGIN]"; - - public static final String DEFAULTWEBSOCKETHANDLER_SENDME = "[DefaultWebSocketHandler.textdoMessage.SENDME]"; - - public static final String DefaultWebSocketHandler_SENDTO = "[DefaultWebSocketHandler.textdoMessage.SENDTO]"; - - public static final String DEFAULTWEBSOCKETHANDLER_SENDGROUP = "[DefaultWebSocketHandler.textdoMessage.SENDGROUP]"; - - public static final String CHANNELACTIVE = "[DefaultWebSocketHandler.channelActive]"; - - public static final String CHANNEL_SUCCESS = "链接成功"; - - public static final String DISCONNECT = "异常断开"; - - public static final String EXCEPTIONCAUGHT = "[DefaultWebSocketHandler.exceptionCaught]"; - - public static final String CHANNELINACTIVE = "[Handler:channelInactive]"; - - public static final String CLOSE_SUCCESS = "关闭成功"; - - public static final String NOTFINDLOGINCHANNLEXCEPTION = "[捕获异常:NotFindLoginChannlException]-[Handler:channelInactive] 关闭未正常注册链接!"; - - public static final String DATAASYNCHRONOUSTASK_01 = "[DataAsynchronousTask.writeData]:数据外抛异常"; - - public static final String DATAASYNCHRONOUSTASK_02 = "[DataAsynchronousTask.writeData]:数据外抛异常"; - - public static final String DATAASYNCHRONOUSTASK_03 = "[DataAsynchronousTask.writeData]:线程任务执行异常"; - - public static final String REDIS_START = "[RedisConfig.getJedis]:连接成功,测试连接PING->"; -} diff --git a/src/main/java/com/github/unclecatmyself/common/constant/NotInChatConstant.java b/src/main/java/com/github/unclecatmyself/common/constant/NotInChatConstant.java deleted file mode 100644 index 497deb8..0000000 --- a/src/main/java/com/github/unclecatmyself/common/constant/NotInChatConstant.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.github.unclecatmyself.common.constant; - -/** - * Created by MySelf on 2019/1/3. - */ -public class NotInChatConstant { - - public static final String Not_Login = "未找到正常注册的连接"; - - public static final String SEND_SUCCESS = "通知发送成功"; - - public static final String NOT_FIND_LOGIN = "未找到在线用户标识"; - - public static final String NOT_FIND_URI = "未找到匹配任务URI"; - - public static final String NOT_HANDLER = "Server Handler 不匹配"; - - public static final String SSL_NOT_FIND = "SSL file and password is null"; - -} diff --git a/src/main/java/com/github/unclecatmyself/common/constant/UtilConstant.java b/src/main/java/com/github/unclecatmyself/common/constant/UtilConstant.java deleted file mode 100644 index 86710a5..0000000 --- a/src/main/java/com/github/unclecatmyself/common/constant/UtilConstant.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.github.unclecatmyself.common.constant; - -/** - * Created by MySelf on 2019/1/15. - */ -public class UtilConstant { - - public static final String PATH_PREFIX = "src/main/resources/"; - - public static final String INSTANT = "TLS"; - -} diff --git a/src/main/java/com/github/unclecatmyself/common/exception/NoFindHandlerException.java b/src/main/java/com/github/unclecatmyself/common/exception/NoFindHandlerException.java deleted file mode 100644 index 99cf181..0000000 --- a/src/main/java/com/github/unclecatmyself/common/exception/NoFindHandlerException.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.github.unclecatmyself.common.exception; - -/** - * 找不到对应处理类 - * Create by UncleCatMySelf in 2018/12/06 - **/ -public class NoFindHandlerException extends RuntimeException { - - private static final long serialVersionUID = 6724478022966267728L; - - public NoFindHandlerException(String message) { - super(message); - } - -} diff --git a/src/main/java/com/github/unclecatmyself/common/exception/NotFindLoginChannlException.java b/src/main/java/com/github/unclecatmyself/common/exception/NotFindLoginChannlException.java deleted file mode 100644 index 7670a6c..0000000 --- a/src/main/java/com/github/unclecatmyself/common/exception/NotFindLoginChannlException.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.github.unclecatmyself.common.exception; - -/** - * 未找到正常注册的连接异常 - * Create by UncleCatMySelf in 13:58 2018\12\30 0030 - */ -public class NotFindLoginChannlException extends RuntimeException { - - private static final long serialVersionUID = -2614068393411382075L; - - public NotFindLoginChannlException(String message) { - super(message); - } -} diff --git a/src/main/java/com/github/unclecatmyself/common/ip/IpUtils.java b/src/main/java/com/github/unclecatmyself/common/ip/IpUtils.java deleted file mode 100644 index b06e994..0000000 --- a/src/main/java/com/github/unclecatmyself/common/ip/IpUtils.java +++ /dev/null @@ -1,66 +0,0 @@ -package com.github.unclecatmyself.common.ip; - -import java.net.Inet4Address; -import java.net.InetAddress; -import java.net.NetworkInterface; -import java.util.Enumeration; - -/** - * Create by UncleCatMySelf in 2018/12/06 - **/ -public class IpUtils { - - /*** - * 获取外网IP - * @return - */ - public static String internetIp() { - try { - - Enumeration networks = NetworkInterface.getNetworkInterfaces(); - InetAddress inetAddress = null; - Enumeration inetAddresses = null; - while (networks.hasMoreElements()) { - inetAddresses = networks.nextElement().getInetAddresses(); - while (inetAddresses.hasMoreElements()) { - inetAddress = inetAddresses.nextElement(); - if (inetAddress != null - && inetAddress instanceof Inet4Address - && !inetAddress.isSiteLocalAddress() - && !inetAddress.isLoopbackAddress() - && inetAddress.getHostAddress().indexOf(":") == -1) { - return inetAddress.getHostAddress(); - } - } - } - - return null; - - } catch (Exception e) { - - throw new RuntimeException(e); - } - } - - /** - * 获取内网IP - * - * @return - */ - public static String intranetIp() { - try { - return InetAddress.getLocalHost().getHostAddress(); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - /** - * 获取服务启动host - * @return - */ - public static String getHost(){ - return internetIp()==null?intranetIp():internetIp(); - } - -} diff --git a/src/main/java/com/github/unclecatmyself/common/pool/DefaultThreadFactory.java b/src/main/java/com/github/unclecatmyself/common/pool/DefaultThreadFactory.java deleted file mode 100644 index 014999d..0000000 --- a/src/main/java/com/github/unclecatmyself/common/pool/DefaultThreadFactory.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.github.unclecatmyself.common.pool; - -import java.util.concurrent.ThreadFactory; -import java.util.concurrent.atomic.AtomicInteger; - -/** - * Create by UncleCatMySelf in 2018/12/06 - **/ -public class DefaultThreadFactory implements ThreadFactory { - - private static final AtomicInteger poolNumber = new AtomicInteger(1); - private final ThreadGroup threadGroup; - private final AtomicInteger currentThreadNumber = new AtomicInteger(1); - private final String namePrefix; - private int priority = Thread.NORM_PRIORITY; - private boolean isDaemon = false; - - public DefaultThreadFactory(String prefix) { - this(prefix, false); - } - - public DefaultThreadFactory(String prefix, boolean isDaemon) { - this(prefix, isDaemon, Thread.NORM_PRIORITY); - } - - public DefaultThreadFactory(String prefix, boolean isDaemon, int priority) { - SecurityManager s = System.getSecurityManager(); - this.threadGroup = (s != null) ? s.getThreadGroup() : Thread.currentThread().getThreadGroup(); - this.namePrefix = prefix + "-" + poolNumber.getAndIncrement() + "-thread-"; - this.isDaemon = isDaemon; - this.priority = priority; - } - - @Override - public Thread newThread(Runnable r) { - Thread thread = new Thread(threadGroup, r, namePrefix + currentThreadNumber.getAndIncrement(), 0); - thread.setDaemon(isDaemon); - thread.setPriority(priority); - return thread; - } -} diff --git a/src/main/java/com/github/unclecatmyself/common/pool/ExecutorQueue.java b/src/main/java/com/github/unclecatmyself/common/pool/ExecutorQueue.java deleted file mode 100644 index 89cde71..0000000 --- a/src/main/java/com/github/unclecatmyself/common/pool/ExecutorQueue.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.github.unclecatmyself.common.pool; - -import java.util.concurrent.LinkedTransferQueue; -import java.util.concurrent.RejectedExecutionException; - -/** - * LinkedTransferQueue 能保证更高性能,相比与LinkedBlockingQueue有明显提升 - * 不过LinkedTransferQueue的缺点是没有队列长度控制,需要在外层协助控制 - * Create by UncleCatMySelf in 2018/12/06 - **/ -public class ExecutorQueue extends LinkedTransferQueue { - - private static final long serialVersionUID = -265236426751004839L; - - private StandardThreadExecutor threadPoolExecutor; - - public ExecutorQueue() { - super(); - } - - public void setStandardThreadExecutor(StandardThreadExecutor threadPoolExecutor) { - this.threadPoolExecutor = threadPoolExecutor; - } - - // 注:代码来源于 tomcat - public boolean force(Runnable o) { - if (threadPoolExecutor.isShutdown()) { - throw new RejectedExecutionException("Executor not running, can't force a command into the queue"); - } - // forces the item onto the queue, to be used if the task is rejected - return super.offer(o); - } - - // 注:tomcat的代码进行一些小变更 - public boolean offer(Runnable o) { - int poolSize = threadPoolExecutor.getPoolSize(); - - // we are maxed out on threads, simply queue the object - if (poolSize == threadPoolExecutor.getMaximumPoolSize()) { - return super.offer(o); - } - // we have idle threads, just add it to the queue - // note that we don't use getActiveCount(), see BZ 49730 - if (poolSize >= threadPoolExecutor.getSubmittedTasksCount()) { - return super.offer(o); - } - // if we have less threads than maximum force creation of a new - // thread - if (poolSize < threadPoolExecutor.getMaximumPoolSize()) { - return false; - } - // if we reached here, we need to add it to the queue - return super.offer(o); - } - -} diff --git a/src/main/java/com/github/unclecatmyself/common/pool/StandardThreadExecutor.java b/src/main/java/com/github/unclecatmyself/common/pool/StandardThreadExecutor.java deleted file mode 100644 index 6fdab50..0000000 --- a/src/main/java/com/github/unclecatmyself/common/pool/StandardThreadExecutor.java +++ /dev/null @@ -1,98 +0,0 @@ -package com.github.unclecatmyself.common.pool; - -import java.util.concurrent.*; -import java.util.concurrent.atomic.AtomicInteger; - -/** - * Create by UncleCatMySelf in 2018/12/06 - * tomcat: org.apache.catalina.core.StandardThreadExecutor - * - * java.util.concurrent.threadPoolExecutor execute执行策略: - * 优先offer到queue,queue满后再扩充线程到maxThread,如果已经到了maxThread就reject - * 比较适合于CPU密集型应用(比如runnable内部执行的操作都在JVM内部,memory copy, or compute等等) - * - * StandardThreadExecutor execute执行策略: - * 优先扩充线程到maxThread,再offer到queue,如果满了就reject - * 比较适合于业务处理需要远程资源的场景 - **/ -public class StandardThreadExecutor extends ThreadPoolExecutor { - - public static final int DEFAULT_MIN_THREADS = 20; - public static final int DEFAULT_MAX_THREADS = 200; - public static final int DEFAULT_MAX_IDLE_TIME = 60000; // 1 minutes - - protected AtomicInteger submittedTasksCount; // 正在处理的任务数 - private int maxSubmittedTaskCount; // 最大允许同时处理的任务数 - - public StandardThreadExecutor() { - this(DEFAULT_MIN_THREADS, DEFAULT_MAX_THREADS); - } - - public StandardThreadExecutor(int coreThread, int maxThreads) { - this(coreThread, maxThreads, maxThreads); - } - - public StandardThreadExecutor(int coreThread, int maxThreads, long keepAliveTime, TimeUnit unit) { - this(coreThread, maxThreads, keepAliveTime, unit, maxThreads); - } - - public StandardThreadExecutor(int coreThreads, int maxThreads, int queueCapacity) { - this(coreThreads, maxThreads, queueCapacity, Executors.defaultThreadFactory()); - } - - public StandardThreadExecutor(int coreThreads, int maxThreads, int queueCapacity, ThreadFactory threadFactory) { - this(coreThreads, maxThreads, DEFAULT_MAX_IDLE_TIME, TimeUnit.MILLISECONDS, queueCapacity, threadFactory); - } - - public StandardThreadExecutor(int coreThreads, int maxThreads, long keepAliveTime, TimeUnit unit, int queueCapacity) { - this(coreThreads, maxThreads, keepAliveTime, unit, queueCapacity, Executors.defaultThreadFactory()); - } - - public StandardThreadExecutor(int coreThreads, int maxThreads, long keepAliveTime, TimeUnit unit, - int queueCapacity, ThreadFactory threadFactory) { - this(coreThreads, maxThreads, keepAliveTime, unit, queueCapacity, threadFactory, new AbortPolicy()); - } - - public StandardThreadExecutor(int coreThreads, int maxThreads, long keepAliveTime, TimeUnit unit, - int queueCapacity, ThreadFactory threadFactory, RejectedExecutionHandler handler) { - super(coreThreads, maxThreads, keepAliveTime, unit, new ExecutorQueue(), threadFactory, handler); - ((ExecutorQueue) getQueue()).setStandardThreadExecutor(this); - - submittedTasksCount = new AtomicInteger(0); - - // 最大并发任务限制: 队列buffer数 + 最大线程数 - maxSubmittedTaskCount = queueCapacity + maxThreads; - } - - @Override - public void execute(Runnable command) { - int count = submittedTasksCount.incrementAndGet(); - - // 超过最大的并发任务限制,进行 reject - // 依赖的LinkedTransferQueue没有长度限制,因此这里进行控制 - if (count > maxSubmittedTaskCount) { - submittedTasksCount.decrementAndGet(); - getRejectedExecutionHandler().rejectedExecution(command, this); - } - - try { - super.execute(command); - } catch (RejectedExecutionException rx) { - // there could have been contention around the queue - if (!((ExecutorQueue) getQueue()).force(command)) { - submittedTasksCount.decrementAndGet(); - getRejectedExecutionHandler().rejectedExecution(command, this); - } - rx.printStackTrace(); - } - } - - public int getSubmittedTasksCount() { - return this.submittedTasksCount.get(); - } - - - protected void afterExecute(Runnable r, Throwable t) { - submittedTasksCount.decrementAndGet(); - } -} diff --git a/src/main/java/com/github/unclecatmyself/common/ssl/SecureSocketKeyStore.java b/src/main/java/com/github/unclecatmyself/common/ssl/SecureSocketKeyStore.java deleted file mode 100644 index 322f796..0000000 --- a/src/main/java/com/github/unclecatmyself/common/ssl/SecureSocketKeyStore.java +++ /dev/null @@ -1,456 +0,0 @@ -package com.github.unclecatmyself.common.ssl; - -import java.io.ByteArrayInputStream; -import java.io.InputStream; -import java.security.KeyStore; - -/** - * A bogus key store which provides all the required information to create an - * example SSL connection. - * - * To generate a bogus key store: - * - *
- * keytool -genkey -alias securesocket \ -keysize 2048 -validity 36500 \  -keyalg RSA -dname "CN=securesocket" \   -keypass inc0rrect -storepass mu$tch8ng3 \  -keystore cert.jks
- *
- *
- *
- *
- * 
- */ -public class SecureSocketKeyStore { - - private static final byte[] CERT_BYTES = { (byte) 254, (byte) 237, - (byte) 254, (byte) 237, (byte) 0, (byte) 0, (byte) 0, (byte) 2, - (byte) 0, (byte) 0, (byte) 0, (byte) 1, (byte) 0, (byte) 0, - (byte) 0, (byte) 1, (byte) 0, (byte) 12, (byte) 115, (byte) 101, - (byte) 99, (byte) 117, (byte) 114, (byte) 101, (byte) 115, - (byte) 111, (byte) 99, (byte) 107, (byte) 101, (byte) 116, - (byte) 0, (byte) 0, (byte) 1, (byte) 69, (byte) 231, (byte) 201, - (byte) 156, (byte) 140, (byte) 0, (byte) 0, (byte) 5, (byte) 0, - (byte) 48, (byte) 130, (byte) 4, (byte) 252, (byte) 48, (byte) 14, - (byte) 6, (byte) 10, (byte) 43, (byte) 6, (byte) 1, (byte) 4, - (byte) 1, (byte) 42, (byte) 2, (byte) 17, (byte) 1, (byte) 1, - (byte) 5, (byte) 0, (byte) 4, (byte) 130, (byte) 4, (byte) 232, - (byte) 221, (byte) 18, (byte) 203, (byte) 171, (byte) 175, - (byte) 82, (byte) 132, (byte) 227, (byte) 115, (byte) 143, - (byte) 38, (byte) 191, (byte) 42, (byte) 202, (byte) 130, - (byte) 171, (byte) 75, (byte) 6, (byte) 161, (byte) 120, - (byte) 204, (byte) 61, (byte) 106, (byte) 160, (byte) 81, (byte) 9, - (byte) 204, (byte) 153, (byte) 166, (byte) 38, (byte) 246, - (byte) 13, (byte) 43, (byte) 19, (byte) 100, (byte) 132, (byte) 45, - (byte) 90, (byte) 143, (byte) 1, (byte) 231, (byte) 182, (byte) 89, - (byte) 228, (byte) 183, (byte) 17, (byte) 95, (byte) 129, - (byte) 229, (byte) 42, (byte) 182, (byte) 126, (byte) 114, - (byte) 76, (byte) 124, (byte) 123, (byte) 246, (byte) 152, - (byte) 0, (byte) 141, (byte) 212, (byte) 111, (byte) 52, - (byte) 243, (byte) 112, (byte) 31, (byte) 117, (byte) 124, - (byte) 142, (byte) 24, (byte) 59, (byte) 198, (byte) 164, - (byte) 253, (byte) 21, (byte) 177, (byte) 189, (byte) 74, - (byte) 218, (byte) 110, (byte) 83, (byte) 154, (byte) 49, - (byte) 186, (byte) 159, (byte) 173, (byte) 202, (byte) 94, - (byte) 174, (byte) 183, (byte) 223, (byte) 119, (byte) 109, - (byte) 110, (byte) 72, (byte) 93, (byte) 208, (byte) 195, - (byte) 19, (byte) 89, (byte) 33, (byte) 34, (byte) 186, (byte) 12, - (byte) 86, (byte) 156, (byte) 156, (byte) 210, (byte) 111, - (byte) 110, (byte) 44, (byte) 106, (byte) 36, (byte) 67, - (byte) 168, (byte) 7, (byte) 179, (byte) 244, (byte) 53, - (byte) 134, (byte) 10, (byte) 86, (byte) 179, (byte) 34, (byte) 60, - (byte) 184, (byte) 179, (byte) 162, (byte) 69, (byte) 24, - (byte) 168, (byte) 100, (byte) 183, (byte) 206, (byte) 64, - (byte) 4, (byte) 32, (byte) 66, (byte) 237, (byte) 228, (byte) 92, - (byte) 6, (byte) 213, (byte) 141, (byte) 147, (byte) 198, - (byte) 141, (byte) 216, (byte) 41, (byte) 0, (byte) 101, (byte) 65, - (byte) 41, (byte) 185, (byte) 128, (byte) 229, (byte) 107, - (byte) 25, (byte) 89, (byte) 148, (byte) 16, (byte) 194, - (byte) 101, (byte) 100, (byte) 243, (byte) 147, (byte) 77, - (byte) 230, (byte) 11, (byte) 151, (byte) 99, (byte) 124, - (byte) 55, (byte) 195, (byte) 185, (byte) 30, (byte) 234, - (byte) 83, (byte) 61, (byte) 109, (byte) 131, (byte) 156, - (byte) 244, (byte) 133, (byte) 66, (byte) 39, (byte) 153, (byte) 9, - (byte) 34, (byte) 218, (byte) 201, (byte) 143, (byte) 190, - (byte) 127, (byte) 119, (byte) 102, (byte) 6, (byte) 83, - (byte) 134, (byte) 96, (byte) 170, (byte) 79, (byte) 196, - (byte) 214, (byte) 47, (byte) 215, (byte) 37, (byte) 250, - (byte) 64, (byte) 8, (byte) 165, (byte) 203, (byte) 44, (byte) 53, - (byte) 113, (byte) 147, (byte) 251, (byte) 29, (byte) 26, - (byte) 38, (byte) 193, (byte) 11, (byte) 223, (byte) 212, - (byte) 114, (byte) 96, (byte) 162, (byte) 39, (byte) 48, - (byte) 200, (byte) 172, (byte) 182, (byte) 254, (byte) 180, - (byte) 198, (byte) 11, (byte) 128, (byte) 75, (byte) 74, (byte) 93, - (byte) 226, (byte) 157, (byte) 80, (byte) 14, (byte) 9, (byte) 217, - (byte) 236, (byte) 205, (byte) 153, (byte) 35, (byte) 242, - (byte) 130, (byte) 140, (byte) 25, (byte) 16, (byte) 156, - (byte) 247, (byte) 230, (byte) 5, (byte) 247, (byte) 0, (byte) 34, - (byte) 196, (byte) 15, (byte) 118, (byte) 255, (byte) 185, - (byte) 199, (byte) 59, (byte) 99, (byte) 27, (byte) 187, (byte) 83, - (byte) 81, (byte) 12, (byte) 71, (byte) 69, (byte) 127, (byte) 130, - (byte) 164, (byte) 97, (byte) 195, (byte) 216, (byte) 215, - (byte) 61, (byte) 29, (byte) 196, (byte) 62, (byte) 160, - (byte) 188, (byte) 209, (byte) 173, (byte) 230, (byte) 0, - (byte) 204, (byte) 225, (byte) 1, (byte) 5, (byte) 42, (byte) 223, - (byte) 232, (byte) 187, (byte) 190, (byte) 67, (byte) 126, - (byte) 235, (byte) 178, (byte) 218, (byte) 179, (byte) 46, - (byte) 186, (byte) 156, (byte) 186, (byte) 6, (byte) 191, - (byte) 68, (byte) 239, (byte) 31, (byte) 16, (byte) 204, (byte) 24, - (byte) 68, (byte) 164, (byte) 88, (byte) 10, (byte) 174, (byte) 26, - (byte) 54, (byte) 187, (byte) 149, (byte) 132, (byte) 128, - (byte) 173, (byte) 165, (byte) 8, (byte) 69, (byte) 96, (byte) 49, - (byte) 57, (byte) 223, (byte) 110, (byte) 29, (byte) 215, - (byte) 98, (byte) 42, (byte) 15, (byte) 153, (byte) 228, - (byte) 216, (byte) 61, (byte) 160, (byte) 230, (byte) 34, - (byte) 40, (byte) 232, (byte) 136, (byte) 139, (byte) 140, - (byte) 236, (byte) 251, (byte) 119, (byte) 242, (byte) 199, - (byte) 167, (byte) 61, (byte) 141, (byte) 89, (byte) 29, (byte) 82, - (byte) 114, (byte) 229, (byte) 198, (byte) 27, (byte) 133, - (byte) 87, (byte) 0, (byte) 53, (byte) 69, (byte) 42, (byte) 91, - (byte) 174, (byte) 82, (byte) 244, (byte) 160, (byte) 82, - (byte) 142, (byte) 221, (byte) 106, (byte) 151, (byte) 241, - (byte) 214, (byte) 64, (byte) 14, (byte) 28, (byte) 2, (byte) 3, - (byte) 145, (byte) 143, (byte) 18, (byte) 165, (byte) 247, - (byte) 178, (byte) 211, (byte) 16, (byte) 222, (byte) 76, - (byte) 60, (byte) 119, (byte) 130, (byte) 199, (byte) 230, - (byte) 229, (byte) 3, (byte) 22, (byte) 100, (byte) 135, - (byte) 103, (byte) 60, (byte) 181, (byte) 191, (byte) 56, - (byte) 249, (byte) 181, (byte) 169, (byte) 210, (byte) 25, - (byte) 152, (byte) 201, (byte) 226, (byte) 119, (byte) 71, - (byte) 204, (byte) 70, (byte) 220, (byte) 103, (byte) 46, - (byte) 166, (byte) 125, (byte) 40, (byte) 86, (byte) 208, - (byte) 114, (byte) 138, (byte) 24, (byte) 27, (byte) 219, - (byte) 123, (byte) 161, (byte) 52, (byte) 14, (byte) 38, - (byte) 244, (byte) 112, (byte) 238, (byte) 121, (byte) 90, - (byte) 34, (byte) 157, (byte) 131, (byte) 53, (byte) 245, - (byte) 162, (byte) 89, (byte) 188, (byte) 6, (byte) 202, - (byte) 164, (byte) 130, (byte) 34, (byte) 232, (byte) 74, - (byte) 45, (byte) 137, (byte) 164, (byte) 200, (byte) 197, - (byte) 247, (byte) 64, (byte) 110, (byte) 122, (byte) 49, - (byte) 116, (byte) 137, (byte) 253, (byte) 170, (byte) 232, - (byte) 120, (byte) 26, (byte) 171, (byte) 228, (byte) 229, - (byte) 49, (byte) 56, (byte) 56, (byte) 106, (byte) 110, (byte) 12, - (byte) 109, (byte) 93, (byte) 105, (byte) 241, (byte) 196, - (byte) 11, (byte) 18, (byte) 89, (byte) 108, (byte) 146, - (byte) 224, (byte) 161, (byte) 181, (byte) 236, (byte) 74, - (byte) 128, (byte) 24, (byte) 239, (byte) 22, (byte) 146, (byte) 0, - (byte) 69, (byte) 182, (byte) 246, (byte) 43, (byte) 59, - (byte) 208, (byte) 33, (byte) 48, (byte) 81, (byte) 0, (byte) 70, - (byte) 225, (byte) 222, (byte) 122, (byte) 178, (byte) 138, - (byte) 12, (byte) 207, (byte) 233, (byte) 164, (byte) 13, - (byte) 176, (byte) 123, (byte) 95, (byte) 68, (byte) 238, - (byte) 134, (byte) 66, (byte) 95, (byte) 194, (byte) 192, - (byte) 225, (byte) 244, (byte) 14, (byte) 78, (byte) 53, - (byte) 189, (byte) 217, (byte) 229, (byte) 203, (byte) 192, - (byte) 34, (byte) 38, (byte) 169, (byte) 63, (byte) 239, - (byte) 128, (byte) 172, (byte) 143, (byte) 75, (byte) 7, - (byte) 237, (byte) 125, (byte) 179, (byte) 235, (byte) 229, - (byte) 98, (byte) 8, (byte) 211, (byte) 237, (byte) 116, (byte) 75, - (byte) 27, (byte) 211, (byte) 131, (byte) 245, (byte) 89, - (byte) 150, (byte) 35, (byte) 49, (byte) 207, (byte) 113, - (byte) 237, (byte) 114, (byte) 125, (byte) 134, (byte) 191, - (byte) 110, (byte) 30, (byte) 119, (byte) 131, (byte) 175, - (byte) 166, (byte) 201, (byte) 255, (byte) 200, (byte) 1, - (byte) 126, (byte) 163, (byte) 172, (byte) 52, (byte) 118, - (byte) 184, (byte) 221, (byte) 165, (byte) 167, (byte) 165, - (byte) 20, (byte) 135, (byte) 32, (byte) 222, (byte) 188, - (byte) 250, (byte) 64, (byte) 161, (byte) 67, (byte) 236, - (byte) 212, (byte) 131, (byte) 44, (byte) 32, (byte) 70, (byte) 0, - (byte) 24, (byte) 178, (byte) 83, (byte) 155, (byte) 145, - (byte) 136, (byte) 131, (byte) 120, (byte) 181, (byte) 164, - (byte) 155, (byte) 172, (byte) 41, (byte) 213, (byte) 164, - (byte) 98, (byte) 169, (byte) 152, (byte) 184, (byte) 170, - (byte) 107, (byte) 7, (byte) 21, (byte) 228, (byte) 175, - (byte) 192, (byte) 238, (byte) 68, (byte) 197, (byte) 119, - (byte) 228, (byte) 225, (byte) 156, (byte) 235, (byte) 241, - (byte) 172, (byte) 171, (byte) 236, (byte) 128, (byte) 78, - (byte) 117, (byte) 152, (byte) 123, (byte) 93, (byte) 156, - (byte) 57, (byte) 238, (byte) 211, (byte) 188, (byte) 47, - (byte) 62, (byte) 45, (byte) 127, (byte) 58, (byte) 38, (byte) 29, - (byte) 131, (byte) 95, (byte) 85, (byte) 149, (byte) 112, - (byte) 215, (byte) 207, (byte) 41, (byte) 201, (byte) 30, - (byte) 149, (byte) 73, (byte) 245, (byte) 179, (byte) 176, - (byte) 246, (byte) 203, (byte) 204, (byte) 252, (byte) 13, - (byte) 98, (byte) 151, (byte) 93, (byte) 87, (byte) 241, - (byte) 166, (byte) 46, (byte) 249, (byte) 148, (byte) 49, - (byte) 141, (byte) 136, (byte) 49, (byte) 77, (byte) 250, - (byte) 191, (byte) 157, (byte) 90, (byte) 84, (byte) 51, - (byte) 129, (byte) 133, (byte) 66, (byte) 253, (byte) 99, - (byte) 243, (byte) 34, (byte) 142, (byte) 197, (byte) 4, - (byte) 126, (byte) 7, (byte) 217, (byte) 126, (byte) 205, - (byte) 250, (byte) 141, (byte) 231, (byte) 225, (byte) 203, - (byte) 171, (byte) 246, (byte) 201, (byte) 48, (byte) 96, - (byte) 207, (byte) 74, (byte) 253, (byte) 120, (byte) 114, - (byte) 163, (byte) 192, (byte) 24, (byte) 12, (byte) 10, - (byte) 210, (byte) 94, (byte) 136, (byte) 152, (byte) 185, - (byte) 109, (byte) 87, (byte) 35, (byte) 159, (byte) 238, - (byte) 122, (byte) 200, (byte) 107, (byte) 103, (byte) 243, - (byte) 250, (byte) 152, (byte) 68, (byte) 66, (byte) 170, (byte) 0, - (byte) 134, (byte) 229, (byte) 168, (byte) 182, (byte) 30, - (byte) 89, (byte) 240, (byte) 121, (byte) 106, (byte) 148, - (byte) 142, (byte) 49, (byte) 242, (byte) 215, (byte) 233, - (byte) 57, (byte) 120, (byte) 204, (byte) 180, (byte) 239, - (byte) 199, (byte) 133, (byte) 255, (byte) 71, (byte) 3, - (byte) 132, (byte) 228, (byte) 110, (byte) 66, (byte) 227, - (byte) 122, (byte) 82, (byte) 118, (byte) 173, (byte) 218, - (byte) 54, (byte) 99, (byte) 167, (byte) 154, (byte) 3, (byte) 189, - (byte) 25, (byte) 123, (byte) 169, (byte) 42, (byte) 184, - (byte) 59, (byte) 36, (byte) 131, (byte) 206, (byte) 248, - (byte) 90, (byte) 32, (byte) 183, (byte) 86, (byte) 62, (byte) 149, - (byte) 107, (byte) 243, (byte) 71, (byte) 197, (byte) 124, - (byte) 155, (byte) 214, (byte) 91, (byte) 29, (byte) 81, (byte) 28, - (byte) 115, (byte) 98, (byte) 130, (byte) 184, (byte) 135, - (byte) 13, (byte) 191, (byte) 147, (byte) 43, (byte) 10, - (byte) 178, (byte) 99, (byte) 165, (byte) 210, (byte) 87, - (byte) 87, (byte) 148, (byte) 31, (byte) 198, (byte) 129, - (byte) 32, (byte) 181, (byte) 3, (byte) 144, (byte) 61, (byte) 5, - (byte) 166, (byte) 252, (byte) 73, (byte) 205, (byte) 230, - (byte) 178, (byte) 162, (byte) 46, (byte) 56, (byte) 99, (byte) 77, - (byte) 97, (byte) 236, (byte) 121, (byte) 157, (byte) 139, - (byte) 153, (byte) 217, (byte) 171, (byte) 19, (byte) 68, - (byte) 36, (byte) 14, (byte) 123, (byte) 249, (byte) 101, - (byte) 127, (byte) 184, (byte) 123, (byte) 7, (byte) 124, - (byte) 68, (byte) 98, (byte) 34, (byte) 139, (byte) 224, - (byte) 173, (byte) 246, (byte) 196, (byte) 180, (byte) 70, - (byte) 207, (byte) 168, (byte) 211, (byte) 255, (byte) 84, - (byte) 0, (byte) 174, (byte) 11, (byte) 160, (byte) 155, - (byte) 127, (byte) 228, (byte) 81, (byte) 226, (byte) 115, - (byte) 142, (byte) 200, (byte) 107, (byte) 4, (byte) 204, - (byte) 219, (byte) 192, (byte) 189, (byte) 56, (byte) 127, - (byte) 184, (byte) 187, (byte) 161, (byte) 106, (byte) 62, - (byte) 225, (byte) 211, (byte) 115, (byte) 30, (byte) 172, - (byte) 191, (byte) 66, (byte) 25, (byte) 66, (byte) 235, - (byte) 107, (byte) 41, (byte) 186, (byte) 40, (byte) 239, - (byte) 173, (byte) 11, (byte) 247, (byte) 89, (byte) 79, - (byte) 135, (byte) 86, (byte) 73, (byte) 77, (byte) 164, (byte) 34, - (byte) 109, (byte) 236, (byte) 56, (byte) 198, (byte) 141, - (byte) 87, (byte) 74, (byte) 172, (byte) 56, (byte) 24, (byte) 150, - (byte) 233, (byte) 233, (byte) 165, (byte) 122, (byte) 201, - (byte) 112, (byte) 232, (byte) 23, (byte) 12, (byte) 166, - (byte) 128, (byte) 114, (byte) 139, (byte) 207, (byte) 233, - (byte) 47, (byte) 220, (byte) 172, (byte) 175, (byte) 40, - (byte) 109, (byte) 82, (byte) 142, (byte) 130, (byte) 177, - (byte) 50, (byte) 127, (byte) 196, (byte) 106, (byte) 172, - (byte) 178, (byte) 71, (byte) 178, (byte) 204, (byte) 99, - (byte) 113, (byte) 33, (byte) 189, (byte) 188, (byte) 168, - (byte) 76, (byte) 92, (byte) 230, (byte) 211, (byte) 239, - (byte) 75, (byte) 71, (byte) 64, (byte) 197, (byte) 26, (byte) 222, - (byte) 19, (byte) 213, (byte) 161, (byte) 144, (byte) 20, - (byte) 126, (byte) 192, (byte) 156, (byte) 15, (byte) 113, - (byte) 64, (byte) 73, (byte) 7, (byte) 241, (byte) 217, (byte) 127, - (byte) 171, (byte) 199, (byte) 66, (byte) 32, (byte) 179, (byte) 4, - (byte) 181, (byte) 93, (byte) 121, (byte) 193, (byte) 10, - (byte) 169, (byte) 255, (byte) 152, (byte) 199, (byte) 95, - (byte) 177, (byte) 227, (byte) 135, (byte) 21, (byte) 64, - (byte) 203, (byte) 9, (byte) 79, (byte) 243, (byte) 114, (byte) 2, - (byte) 201, (byte) 157, (byte) 180, (byte) 52, (byte) 193, - (byte) 66, (byte) 34, (byte) 155, (byte) 52, (byte) 35, (byte) 93, - (byte) 31, (byte) 96, (byte) 77, (byte) 12, (byte) 80, (byte) 195, - (byte) 96, (byte) 247, (byte) 251, (byte) 237, (byte) 36, - (byte) 170, (byte) 7, (byte) 3, (byte) 251, (byte) 243, (byte) 47, - (byte) 180, (byte) 98, (byte) 207, (byte) 176, (byte) 106, - (byte) 237, (byte) 114, (byte) 91, (byte) 229, (byte) 56, - (byte) 94, (byte) 154, (byte) 32, (byte) 62, (byte) 240, - (byte) 132, (byte) 4, (byte) 144, (byte) 227, (byte) 140, - (byte) 137, (byte) 76, (byte) 15, (byte) 117, (byte) 82, - (byte) 223, (byte) 168, (byte) 135, (byte) 33, (byte) 91, - (byte) 173, (byte) 4, (byte) 245, (byte) 192, (byte) 95, - (byte) 135, (byte) 22, (byte) 138, (byte) 89, (byte) 1, (byte) 14, - (byte) 230, (byte) 143, (byte) 195, (byte) 93, (byte) 133, - (byte) 194, (byte) 252, (byte) 188, (byte) 31, (byte) 39, - (byte) 162, (byte) 59, (byte) 148, (byte) 219, (byte) 213, - (byte) 179, (byte) 195, (byte) 165, (byte) 67, (byte) 68, - (byte) 39, (byte) 178, (byte) 143, (byte) 192, (byte) 177, - (byte) 221, (byte) 236, (byte) 63, (byte) 40, (byte) 205, - (byte) 26, (byte) 81, (byte) 127, (byte) 5, (byte) 213, (byte) 192, - (byte) 22, (byte) 147, (byte) 98, (byte) 207, (byte) 153, (byte) 8, - (byte) 108, (byte) 75, (byte) 182, (byte) 148, (byte) 0, - (byte) 151, (byte) 15, (byte) 178, (byte) 98, (byte) 145, - (byte) 255, (byte) 213, (byte) 142, (byte) 63, (byte) 247, - (byte) 42, (byte) 161, (byte) 246, (byte) 21, (byte) 128, - (byte) 47, (byte) 248, (byte) 217, (byte) 70, (byte) 195, - (byte) 151, (byte) 236, (byte) 73, (byte) 153, (byte) 230, - (byte) 152, (byte) 217, (byte) 12, (byte) 189, (byte) 65, - (byte) 85, (byte) 189, (byte) 204, (byte) 212, (byte) 161, - (byte) 210, (byte) 217, (byte) 74, (byte) 75, (byte) 186, - (byte) 122, (byte) 167, (byte) 149, (byte) 178, (byte) 202, - (byte) 205, (byte) 246, (byte) 225, (byte) 225, (byte) 190, - (byte) 56, (byte) 42, (byte) 162, (byte) 215, (byte) 107, - (byte) 45, (byte) 121, (byte) 235, (byte) 195, (byte) 219, - (byte) 22, (byte) 0, (byte) 0, (byte) 0, (byte) 1, (byte) 0, - (byte) 5, (byte) 88, (byte) 46, (byte) 53, (byte) 48, (byte) 57, - (byte) 0, (byte) 0, (byte) 2, (byte) 211, (byte) 48, (byte) 130, - (byte) 2, (byte) 207, (byte) 48, (byte) 130, (byte) 1, (byte) 183, - (byte) 160, (byte) 3, (byte) 2, (byte) 1, (byte) 2, (byte) 2, - (byte) 4, (byte) 58, (byte) 247, (byte) 71, (byte) 185, (byte) 48, - (byte) 13, (byte) 6, (byte) 9, (byte) 42, (byte) 134, (byte) 72, - (byte) 134, (byte) 247, (byte) 13, (byte) 1, (byte) 1, (byte) 11, - (byte) 5, (byte) 0, (byte) 48, (byte) 23, (byte) 49, (byte) 21, - (byte) 48, (byte) 19, (byte) 6, (byte) 3, (byte) 85, (byte) 4, - (byte) 3, (byte) 19, (byte) 12, (byte) 115, (byte) 101, (byte) 99, - (byte) 117, (byte) 114, (byte) 101, (byte) 115, (byte) 111, - (byte) 99, (byte) 107, (byte) 101, (byte) 116, (byte) 48, - (byte) 32, (byte) 23, (byte) 13, (byte) 49, (byte) 52, (byte) 48, - (byte) 53, (byte) 49, (byte) 48, (byte) 50, (byte) 48, (byte) 49, - (byte) 56, (byte) 52, (byte) 48, (byte) 90, (byte) 24, (byte) 15, - (byte) 50, (byte) 49, (byte) 49, (byte) 52, (byte) 48, (byte) 52, - (byte) 49, (byte) 54, (byte) 50, (byte) 48, (byte) 49, (byte) 56, - (byte) 52, (byte) 48, (byte) 90, (byte) 48, (byte) 23, (byte) 49, - (byte) 21, (byte) 48, (byte) 19, (byte) 6, (byte) 3, (byte) 85, - (byte) 4, (byte) 3, (byte) 19, (byte) 12, (byte) 115, (byte) 101, - (byte) 99, (byte) 117, (byte) 114, (byte) 101, (byte) 115, - (byte) 111, (byte) 99, (byte) 107, (byte) 101, (byte) 116, - (byte) 48, (byte) 130, (byte) 1, (byte) 34, (byte) 48, (byte) 13, - (byte) 6, (byte) 9, (byte) 42, (byte) 134, (byte) 72, (byte) 134, - (byte) 247, (byte) 13, (byte) 1, (byte) 1, (byte) 1, (byte) 5, - (byte) 0, (byte) 3, (byte) 130, (byte) 1, (byte) 15, (byte) 0, - (byte) 48, (byte) 130, (byte) 1, (byte) 10, (byte) 2, (byte) 130, - (byte) 1, (byte) 1, (byte) 0, (byte) 153, (byte) 113, (byte) 7, - (byte) 44, (byte) 219, (byte) 76, (byte) 101, (byte) 226, - (byte) 138, (byte) 96, (byte) 219, (byte) 60, (byte) 167, - (byte) 138, (byte) 222, (byte) 6, (byte) 78, (byte) 169, (byte) 64, - (byte) 188, (byte) 156, (byte) 190, (byte) 119, (byte) 16, - (byte) 34, (byte) 228, (byte) 250, (byte) 253, (byte) 119, - (byte) 75, (byte) 240, (byte) 60, (byte) 242, (byte) 52, - (byte) 137, (byte) 146, (byte) 20, (byte) 130, (byte) 202, - (byte) 226, (byte) 125, (byte) 19, (byte) 7, (byte) 34, (byte) 8, - (byte) 61, (byte) 243, (byte) 202, (byte) 225, (byte) 206, - (byte) 223, (byte) 53, (byte) 74, (byte) 56, (byte) 222, (byte) 47, - (byte) 99, (byte) 235, (byte) 57, (byte) 73, (byte) 90, (byte) 198, - (byte) 109, (byte) 104, (byte) 36, (byte) 255, (byte) 124, - (byte) 57, (byte) 155, (byte) 248, (byte) 120, (byte) 56, - (byte) 56, (byte) 38, (byte) 41, (byte) 216, (byte) 1, (byte) 216, - (byte) 216, (byte) 100, (byte) 239, (byte) 79, (byte) 222, - (byte) 34, (byte) 21, (byte) 182, (byte) 112, (byte) 136, - (byte) 137, (byte) 16, (byte) 141, (byte) 15, (byte) 83, (byte) 94, - (byte) 245, (byte) 36, (byte) 203, (byte) 178, (byte) 137, - (byte) 159, (byte) 86, (byte) 220, (byte) 253, (byte) 112, - (byte) 200, (byte) 50, (byte) 135, (byte) 215, (byte) 190, - (byte) 21, (byte) 186, (byte) 84, (byte) 21, (byte) 96, (byte) 126, - (byte) 253, (byte) 115, (byte) 209, (byte) 241, (byte) 94, - (byte) 115, (byte) 219, (byte) 0, (byte) 25, (byte) 253, - (byte) 209, (byte) 182, (byte) 118, (byte) 230, (byte) 10, - (byte) 50, (byte) 131, (byte) 39, (byte) 249, (byte) 136, - (byte) 11, (byte) 101, (byte) 192, (byte) 12, (byte) 210, - (byte) 179, (byte) 237, (byte) 213, (byte) 68, (byte) 101, - (byte) 58, (byte) 187, (byte) 255, (byte) 240, (byte) 164, - (byte) 147, (byte) 72, (byte) 148, (byte) 227, (byte) 155, - (byte) 88, (byte) 250, (byte) 101, (byte) 253, (byte) 87, - (byte) 140, (byte) 168, (byte) 39, (byte) 163, (byte) 133, - (byte) 150, (byte) 252, (byte) 226, (byte) 234, (byte) 52, - (byte) 88, (byte) 40, (byte) 56, (byte) 23, (byte) 105, (byte) 236, - (byte) 4, (byte) 113, (byte) 98, (byte) 4, (byte) 0, (byte) 117, - (byte) 59, (byte) 77, (byte) 236, (byte) 135, (byte) 93, (byte) 54, - (byte) 30, (byte) 6, (byte) 126, (byte) 90, (byte) 15, (byte) 105, - (byte) 89, (byte) 216, (byte) 154, (byte) 72, (byte) 134, - (byte) 209, (byte) 74, (byte) 197, (byte) 237, (byte) 51, - (byte) 37, (byte) 33, (byte) 106, (byte) 50, (byte) 71, (byte) 134, - (byte) 169, (byte) 173, (byte) 88, (byte) 111, (byte) 217, - (byte) 117, (byte) 184, (byte) 97, (byte) 1, (byte) 38, (byte) 76, - (byte) 112, (byte) 170, (byte) 190, (byte) 250, (byte) 96, - (byte) 17, (byte) 45, (byte) 117, (byte) 183, (byte) 82, - (byte) 155, (byte) 10, (byte) 53, (byte) 15, (byte) 214, (byte) 36, - (byte) 134, (byte) 249, (byte) 146, (byte) 98, (byte) 99, - (byte) 64, (byte) 158, (byte) 99, (byte) 227, (byte) 21, (byte) 92, - (byte) 98, (byte) 90, (byte) 202, (byte) 214, (byte) 134, - (byte) 233, (byte) 212, (byte) 149, (byte) 2, (byte) 3, (byte) 1, - (byte) 0, (byte) 1, (byte) 163, (byte) 33, (byte) 48, (byte) 31, - (byte) 48, (byte) 29, (byte) 6, (byte) 3, (byte) 85, (byte) 29, - (byte) 14, (byte) 4, (byte) 22, (byte) 4, (byte) 20, (byte) 115, - (byte) 110, (byte) 177, (byte) 165, (byte) 41, (byte) 26, - (byte) 142, (byte) 198, (byte) 221, (byte) 63, (byte) 79, - (byte) 252, (byte) 219, (byte) 159, (byte) 68, (byte) 102, - (byte) 76, (byte) 153, (byte) 128, (byte) 164, (byte) 48, - (byte) 13, (byte) 6, (byte) 9, (byte) 42, (byte) 134, (byte) 72, - (byte) 134, (byte) 247, (byte) 13, (byte) 1, (byte) 1, (byte) 11, - (byte) 5, (byte) 0, (byte) 3, (byte) 130, (byte) 1, (byte) 1, - (byte) 0, (byte) 118, (byte) 55, (byte) 245, (byte) 122, - (byte) 159, (byte) 155, (byte) 98, (byte) 122, (byte) 229, - (byte) 186, (byte) 23, (byte) 207, (byte) 109, (byte) 225, - (byte) 220, (byte) 74, (byte) 51, (byte) 218, (byte) 10, - (byte) 115, (byte) 137, (byte) 103, (byte) 127, (byte) 28, - (byte) 30, (byte) 184, (byte) 149, (byte) 249, (byte) 193, - (byte) 206, (byte) 208, (byte) 181, (byte) 191, (byte) 128, - (byte) 18, (byte) 208, (byte) 24, (byte) 132, (byte) 147, - (byte) 184, (byte) 198, (byte) 82, (byte) 204, (byte) 183, - (byte) 127, (byte) 87, (byte) 234, (byte) 136, (byte) 197, - (byte) 34, (byte) 232, (byte) 124, (byte) 210, (byte) 2, - (byte) 192, (byte) 69, (byte) 246, (byte) 25, (byte) 232, - (byte) 162, (byte) 0, (byte) 157, (byte) 216, (byte) 194, - (byte) 26, (byte) 207, (byte) 225, (byte) 169, (byte) 59, - (byte) 246, (byte) 52, (byte) 51, (byte) 150, (byte) 210, - (byte) 50, (byte) 118, (byte) 58, (byte) 154, (byte) 45, - (byte) 128, (byte) 138, (byte) 47, (byte) 174, (byte) 83, - (byte) 117, (byte) 18, (byte) 224, (byte) 9, (byte) 146, - (byte) 180, (byte) 178, (byte) 22, (byte) 76, (byte) 82, - (byte) 229, (byte) 16, (byte) 150, (byte) 127, (byte) 13, - (byte) 122, (byte) 218, (byte) 159, (byte) 195, (byte) 232, - (byte) 168, (byte) 206, (byte) 105, (byte) 82, (byte) 37, - (byte) 252, (byte) 186, (byte) 223, (byte) 222, (byte) 7, - (byte) 106, (byte) 87, (byte) 218, (byte) 89, (byte) 22, - (byte) 252, (byte) 7, (byte) 177, (byte) 52, (byte) 180, (byte) 9, - (byte) 16, (byte) 29, (byte) 57, (byte) 192, (byte) 209, - (byte) 225, (byte) 155, (byte) 16, (byte) 219, (byte) 38, - (byte) 90, (byte) 174, (byte) 152, (byte) 140, (byte) 252, - (byte) 114, (byte) 133, (byte) 106, (byte) 24, (byte) 107, - (byte) 227, (byte) 80, (byte) 166, (byte) 63, (byte) 47, (byte) 16, - (byte) 15, (byte) 89, (byte) 242, (byte) 19, (byte) 87, (byte) 193, - (byte) 250, (byte) 222, (byte) 223, (byte) 183, (byte) 61, - (byte) 91, (byte) 17, (byte) 92, (byte) 35, (byte) 142, (byte) 44, - (byte) 153, (byte) 135, (byte) 86, (byte) 97, (byte) 70, - (byte) 205, (byte) 38, (byte) 192, (byte) 18, (byte) 244, - (byte) 61, (byte) 46, (byte) 21, (byte) 145, (byte) 99, (byte) 72, - (byte) 142, (byte) 37, (byte) 19, (byte) 219, (byte) 167, - (byte) 62, (byte) 71, (byte) 197, (byte) 86, (byte) 152, - (byte) 139, (byte) 122, (byte) 231, (byte) 122, (byte) 206, - (byte) 42, (byte) 142, (byte) 164, (byte) 237, (byte) 19, - (byte) 60, (byte) 95, (byte) 239, (byte) 191, (byte) 64, - (byte) 188, (byte) 94, (byte) 154, (byte) 199, (byte) 252, - (byte) 62, (byte) 26, (byte) 181, (byte) 194, (byte) 141, - (byte) 13, (byte) 1, (byte) 112, (byte) 161, (byte) 195, - (byte) 149, (byte) 116, (byte) 57, (byte) 118, (byte) 114, - (byte) 248, (byte) 235, (byte) 54, (byte) 229, (byte) 48, - (byte) 53, (byte) 30, (byte) 145, (byte) 199, (byte) 207, - (byte) 49, (byte) 175, (byte) 44, (byte) 172, (byte) 120, - (byte) 254, (byte) 181, (byte) 100, (byte) 113, (byte) 191, - (byte) 64, (byte) 131, (byte) 125, (byte) 80, (byte) 180, - (byte) 229, (byte) 109, (byte) 97, (byte) 8, (byte) 166, - (byte) 155, (byte) 72, (byte) 252, (byte) 84, (byte) 62, (byte) 97, - (byte) 80, (byte) 26, (byte) 17, (byte) 143, (byte) 96, (byte) 16, - (byte) 204, (byte) 86, (byte) 61, (byte) 226, (byte) 149 }; - - - public static KeyStore getKeyStore() - { - KeyStore ks = null; - try{ - ks = KeyStore.getInstance("JKS"); - ks.load(asInputStream(), getKeyStorePassword()); - }catch(Exception ex){ - throw new RuntimeException("Failed to load SSL key store.", ex); - } - return ks; - } - - public static InputStream asInputStream() { - return new ByteArrayInputStream(CERT_BYTES); - } - - public static char[] getCertificatePassword() { - return "inc0rrect".toCharArray(); - } - - public static char[] getKeyStorePassword() { - return "mu$tch8ng3".toCharArray(); - } - - public static String getCertificatePasswordString() { - return "inc0rrect"; - } - - public static String getKeyStorePasswordString() { - return "mu$tch8ng3"; - } - - private SecureSocketKeyStore() { - - } - -} diff --git a/src/main/java/com/github/unclecatmyself/common/ssl/SecureSocketSslContextFactory.java b/src/main/java/com/github/unclecatmyself/common/ssl/SecureSocketSslContextFactory.java deleted file mode 100644 index 8425072..0000000 --- a/src/main/java/com/github/unclecatmyself/common/ssl/SecureSocketSslContextFactory.java +++ /dev/null @@ -1,89 +0,0 @@ -package com.github.unclecatmyself.common.ssl; - -import io.netty.util.internal.SystemPropertyUtil; - -import javax.net.ssl.*; -import java.security.KeyStore; -import java.security.SecureRandom; - -/** - * Creates a bogus {@link SSLContext}. A client-side context created by this - * factory accepts any certificate even if it is invalid. A server-side context - * created by this factory sends a bogus certificate defined in {@link }. - *

- * You will have to create your context differently in a real world application. - * - *

Client Certificate Authentication

- * - * To enable client certificate authentication: - *
    - *
  • Enable client authentication on the server side by calling - * {@link SSLEngine#setNeedClientAuth(boolean)} before creating - * {@link }.
  • - *
  • When initializing an {@link SSLContext} on the client side, - * specify the {@link KeyManager} that contains the client certificate as - * the first argument of {@link SSLContext#init(KeyManager[], TrustManager[], SecureRandom)}.
  • - *
  • When initializing an {@link SSLContext} on the server side, - * specify the proper {@link TrustManager} as the second argument of - * {@link SSLContext#init(KeyManager[], TrustManager[], SecureRandom)} - * to validate the client certificate.
  • - *
- */ -public final class SecureSocketSslContextFactory { - - private static final String PROTOCOL = "TLS"; - private static final SSLContext SERVER_CONTEXT; - private static final SSLContext CLIENT_CONTEXT; - - static { - String algorithm = SystemPropertyUtil.get("ssl.KeyManagerFactory.algorithm"); - if (algorithm == null) { - algorithm = "SunX509"; - } - - SSLContext serverContext; - SSLContext clientContext; - try { - // - //SecureSocketSslContextFactory.class.getResourceAsStream("/securesocket.jks") - KeyStore ks = KeyStore.getInstance("JKS"); - ks.load(SecureSocketKeyStore.asInputStream(), - SecureSocketKeyStore.getKeyStorePassword()); - - // Set up key manager factory to use our key store - KeyManagerFactory kmf = KeyManagerFactory.getInstance(algorithm); - kmf.init(ks, SecureSocketKeyStore.getCertificatePassword()); - - // Initialize the SSLContext to work with our key managers. - serverContext = SSLContext.getInstance(PROTOCOL); - serverContext.init(kmf.getKeyManagers(), null, null); - } catch (Exception e) { - throw new Error( - "Failed to initialize the server-side SSLContext", e); - } - - try { - clientContext = SSLContext.getInstance(PROTOCOL); - clientContext.init(null, SecureSokcetTrustManagerFactory.getTrustManagers(), null); - } catch (Exception e) { - throw new Error( - "Failed to initialize the client-side SSLContext", e); - } - - SERVER_CONTEXT = serverContext; - CLIENT_CONTEXT = clientContext; - } - - public static SSLContext getServerContext() { - return SERVER_CONTEXT; - } - - public static SSLContext getClientContext() { - return CLIENT_CONTEXT; - } - - private SecureSocketSslContextFactory() { - // Unused - } - -} diff --git a/src/main/java/com/github/unclecatmyself/common/ssl/SecureSokcetTrustManagerFactory.java b/src/main/java/com/github/unclecatmyself/common/ssl/SecureSokcetTrustManagerFactory.java deleted file mode 100644 index c4d8975..0000000 --- a/src/main/java/com/github/unclecatmyself/common/ssl/SecureSokcetTrustManagerFactory.java +++ /dev/null @@ -1,63 +0,0 @@ -package com.github.unclecatmyself.common.ssl; - -import javax.net.ssl.ManagerFactoryParameters; -import javax.net.ssl.TrustManager; -import javax.net.ssl.TrustManagerFactorySpi; -import javax.net.ssl.X509TrustManager; -import java.security.InvalidAlgorithmParameterException; -import java.security.KeyStore; -import java.security.KeyStoreException; -import java.security.cert.X509Certificate; - -/** - * Bogus {@link TrustManagerFactorySpi} which accepts any certificate - * even if it is invalid. - */ -public class SecureSokcetTrustManagerFactory extends TrustManagerFactorySpi { - - private static final TrustManager DUMMY_TRUST_MANAGER = new X509TrustManager() { - @Override - public X509Certificate[] getAcceptedIssuers() { - return new X509Certificate[0]; - } - - @Override - public void checkClientTrusted(X509Certificate[] chain, String authType) { - // Always trust - it is an example. - // You should do something in the real world. - // You will reach here only if you enabled client certificate auth, - // as described in SecureChatSslContextFactory. - System.err.println( - "UNKNOWN CLIENT CERTIFICATE: " + chain[0].getSubjectDN()); - } - - @Override - public void checkServerTrusted(X509Certificate[] chain, String authType) { - // Always trust - it is an example. - // You should do something in the real world. - System.err.println( - "UNKNOWN SERVER CERTIFICATE: 222 " + chain[0].getSubjectDN()); - } - }; - - public static TrustManager[] getTrustManagers() { - return new TrustManager[] { DUMMY_TRUST_MANAGER }; - } - - @Override - protected TrustManager[] engineGetTrustManagers() { - return getTrustManagers(); - } - - @Override - protected void engineInit(KeyStore keystore) throws KeyStoreException { - // Unused - } - - @Override - protected void engineInit(ManagerFactoryParameters managerFactoryParameters) - throws InvalidAlgorithmParameterException { - // Unused - } - -} diff --git a/src/main/java/com/github/unclecatmyself/common/ssl/StreamReader.java b/src/main/java/com/github/unclecatmyself/common/ssl/StreamReader.java deleted file mode 100644 index 1f75cb5..0000000 --- a/src/main/java/com/github/unclecatmyself/common/ssl/StreamReader.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.github.unclecatmyself.common.ssl; - -import java.io.InputStream; - -public class StreamReader { - - public String toByteArray(InputStream fin) - { - int i = -1; - StringBuilder buf = new StringBuilder(); - try{ - while((i=fin.read())!=-1){ - if(buf.length()>0) buf.append(","); - buf.append("(byte)"); - buf.append(i); - } - - }catch(Throwable e){ - ; - } - - return buf.toString(); - } - -} diff --git a/src/main/java/com/github/unclecatmyself/common/ssl/X509CertTool.java b/src/main/java/com/github/unclecatmyself/common/ssl/X509CertTool.java deleted file mode 100644 index 304e014..0000000 --- a/src/main/java/com/github/unclecatmyself/common/ssl/X509CertTool.java +++ /dev/null @@ -1,69 +0,0 @@ -package com.github.unclecatmyself.common.ssl; - - - - -import sun.security.x509.*; - -import java.io.IOException; -import java.math.BigInteger; -import java.security.GeneralSecurityException; -import java.security.KeyPair; -import java.security.PrivateKey; -import java.security.SecureRandom; -import java.security.cert.X509Certificate; -import java.util.Date; - - -/** - * This class would require rt.jar in the class path in order to - * generated it alternative is using keytool. - */ -public class X509CertTool { - - /** - * Create a self-signed X.509 Certificate - * @param dn the X.509 Distinguished Name, eg "CN=Test, L=London, C=GB" - * @param pair the KeyPair - * @param days how many days from now the Certificate is valid for - * @param algorithm the signing algorithm, eg "SHA1withRSA" - */ - @SuppressWarnings("restriction") - X509Certificate generateCertificate(String dn, KeyPair pair, int days, - String algorithm) throws GeneralSecurityException, IOException { - PrivateKey privkey = pair.getPrivate(); - X509CertInfo info = new X509CertInfo(); - Date from = new Date(); - Date to = new Date(from.getTime() + days * 86400000l); - CertificateValidity interval = new CertificateValidity(from, to); - BigInteger sn = new BigInteger(64, new SecureRandom()); - X500Name owner = new X500Name(dn); - - info.set(X509CertInfo.VALIDITY, interval); - info.set(X509CertInfo.SERIAL_NUMBER, new CertificateSerialNumber(sn)); - info.set(X509CertInfo.SUBJECT, new CertificateSubjectName(owner)); - info.set(X509CertInfo.ISSUER, new CertificateIssuerName(owner)); - info.set(X509CertInfo.KEY, new CertificateX509Key(pair.getPublic())); - info.set(X509CertInfo.VERSION, new CertificateVersion( - CertificateVersion.V3)); - AlgorithmId algo = new AlgorithmId(AlgorithmId.md5WithRSAEncryption_oid); - info.set(X509CertInfo.ALGORITHM_ID, new CertificateAlgorithmId(algo)); - - // Sign the cert to identify the algorithm that's used. - X509CertImpl cert = new X509CertImpl(info); - cert.sign(privkey, algorithm); - - // Update the algorith, and resign. - algo = (AlgorithmId) cert.get(X509CertImpl.SIG_ALG); - info.set(CertificateAlgorithmId.NAME + "." - + CertificateAlgorithmId.ALGORITHM, algo); - cert = new X509CertImpl(info); - cert.sign(privkey, algorithm); - return cert; - } - - public static void main(String[] args) { - - } - -} diff --git a/src/main/java/com/github/unclecatmyself/common/utils/HttpUtil.java b/src/main/java/com/github/unclecatmyself/common/utils/HttpUtil.java deleted file mode 100644 index f9fd8e9..0000000 --- a/src/main/java/com/github/unclecatmyself/common/utils/HttpUtil.java +++ /dev/null @@ -1,63 +0,0 @@ -package com.github.unclecatmyself.common.utils; - -import com.alibaba.fastjson.JSONObject; -import com.github.unclecatmyself.common.bean.vo.SendServerVO; -import com.github.unclecatmyself.common.constant.Constans; -import com.github.unclecatmyself.common.constant.HttpConstant; -import io.netty.handler.codec.http.FullHttpRequest; -import io.netty.handler.codec.http.HttpMethod; -import io.netty.util.CharsetUtil; - -import java.io.*; -import java.net.HttpURLConnection; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.Map; - -/** - * HTTP接口处理方法 - * Create by UncleCatMySelf in 22:43 2018\12\30 0030 - */ -public class HttpUtil { - - public static String checkType(FullHttpRequest msg){ - msg.retain(); - String url = msg.uri(); - System.out.println(url); - HttpMethod method = msg.method(); - String meName = method.name(); - if (url.equals(HttpConstant.URI_GETSIZE) && meName.equals(HttpConstant.GET)){ - return HttpConstant.GETSIZE; - }else if (url.equals(HttpConstant.URI_SENDFROMSERVER) && meName.equals(HttpConstant.POST)){ - return HttpConstant.SENDFROMSERVER; - }else if (url.equals(HttpConstant.URI_GETLIST) && meName.equals(HttpConstant.GET)){ - return HttpConstant.GETLIST; - }else if (url.equals(HttpConstant.URI_SENDINCHAT) && meName.equals(HttpConstant.POST)){ - return HttpConstant.SENDINCHAT; - }else { - return HttpConstant.NOTFINDURI; - } - } - - public static SendServerVO getToken(FullHttpRequest msg) throws UnsupportedEncodingException { - msg.retain(); - SendServerVO sendServerVO = new SendServerVO(); - String content = msg.content().toString(CharsetUtil.UTF_8); - String[] stars = content.split("&"); - for (int i=0,len=stars.length;i maps){ - InChatMessage message = new InChatMessage(); - if (maps.containsKey(Constans.TOKEN)){ - message.setToken((String) maps.get(Constans.TOKEN)); - } - if (maps.containsKey(Constans.TIME)){ - message.setTime((Date) maps.get(Constans.TIME)); - } - if (maps.containsKey(Constans.VALUE)){ - message.setValue((String)maps.get(Constans.VALUE)); - } - if (maps.containsKey(Constans.TYPE)){ - message.setType((String)maps.get(Constans.TYPE)); - } - if (maps.containsKey(Constans.ONE)){ - message.setOne((String)maps.get(Constans.ONE)); - } - if (maps.containsKey(Constans.GROUPID)){ - message.setGroudId((String)maps.get(Constans.GROUPID)); - } - if (maps.containsKey(Constans.ON_ONLINE)){ - message.setOnline((String)maps.get(Constans.ON_ONLINE)); - } - if (maps.containsKey(Constans.ONLINE_GROUP)){ - message.setOnlineGroup((ArrayList)maps.get(Constans.ONLINE_GROUP)); - } - return message; - } - -} diff --git a/src/main/java/com/github/unclecatmyself/common/utils/RedisUtil.java b/src/main/java/com/github/unclecatmyself/common/utils/RedisUtil.java deleted file mode 100644 index d659d91..0000000 --- a/src/main/java/com/github/unclecatmyself/common/utils/RedisUtil.java +++ /dev/null @@ -1,59 +0,0 @@ -package com.github.unclecatmyself.common.utils; - -import java.security.MessageDigest; - -/** - * Create by UncleCatMySelf in 15:13 2019\1\5 0005 - */ -public class RedisUtil { - - private static final String STAL = "InChat"; - - public static String string2MD5(String inStr) { - MessageDigest md5 = null; - try { - md5 = MessageDigest.getInstance("MD5"); - } catch (Exception e) { - System.out.println(e.toString()); - e.printStackTrace(); - return ""; - } - char[] charArray = inStr.toCharArray(); - byte[] byteArray = new byte[charArray.length]; - for (int i = 0; i < charArray.length; i++) byteArray[i] = (byte) charArray[i]; - byte[] md5Bytes = md5.digest(byteArray); - StringBuffer hexValue = new StringBuffer(); - for (int i = 0; i < md5Bytes.length; i++) { - int val = ((int) md5Bytes[i]) & 0xff; - if (val < 16) - hexValue.append("0"); - hexValue.append(Integer.toHexString(val)); - } - return hexValue.toString(); - } - - public static String convertMD5(String address,String token){ - String inStr = address+"&"+token+"%"+STAL; - char[] a = inStr.toCharArray(); - for (int i = 0; i < a.length; i++){ - a[i] = (char) (a[i] ^ 't'); - } - String s = new String(a); - return s; - } - - public static String convertMD5(String inStr){ - char[] a = inStr.toCharArray(); - for (int i = 0; i < a.length; i++){ - a[i] = (char) (a[i] ^ 't'); - } - String s = new String(a); - return s; - } - - public static String getAddress(String s) { - String[] stars = s.split("&"); - return stars[0]; - } - -} diff --git a/src/main/java/com/github/unclecatmyself/common/utils/RemotingUtil.java b/src/main/java/com/github/unclecatmyself/common/utils/RemotingUtil.java deleted file mode 100644 index c2c72b7..0000000 --- a/src/main/java/com/github/unclecatmyself/common/utils/RemotingUtil.java +++ /dev/null @@ -1,187 +0,0 @@ -package com.github.unclecatmyself.common.utils; - -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.IOException; -import java.lang.reflect.Method; -import java.net.*; -import java.nio.channels.Selector; -import java.nio.channels.SocketChannel; -import java.nio.channels.spi.SelectorProvider; -import java.util.ArrayList; -import java.util.Enumeration; - -public class RemotingUtil { - - public static final String OS_NAME = System.getProperty("os.name"); - - private static final Logger log = LoggerFactory.getLogger(RemotingUtil.class); - private static boolean isLinuxPlatform = false; - private static boolean isWindowsPlatform = false; - - static { - if (OS_NAME != null && OS_NAME.toLowerCase().contains("linux")) { - isLinuxPlatform = true; - } - - if (OS_NAME != null && OS_NAME.toLowerCase().contains("windows")) { - isWindowsPlatform = true; - } - } - - public static boolean isWindowsPlatform() { - return isWindowsPlatform; - } - - public static Selector openSelector() throws IOException { - Selector result = null; - - if (isLinuxPlatform()) { - try { - final Class providerClazz = Class.forName("sun.nio.ch.EPollSelectorProvider"); - if (providerClazz != null) { - try { - final Method method = providerClazz.getMethod("provider"); - if (method != null) { - final SelectorProvider selectorProvider = (SelectorProvider) method.invoke(null); - if (selectorProvider != null) { - result = selectorProvider.openSelector(); - } - } - } catch (final Exception e) { - log.warn("Open ePoll Selector for linux platform exception", e); - } - } - } catch (final Exception e) { - // ignore - } - } - - if (result == null) { - result = Selector.open(); - } - - return result; - } - - public static boolean isLinuxPlatform() { - return isLinuxPlatform; - } - - public static String getLocalAddress() { - try { - // Traversal Network interface to get the first non-loopback and non-private address - Enumeration enumeration = NetworkInterface.getNetworkInterfaces(); - ArrayList ipv4Result = new ArrayList(); - ArrayList ipv6Result = new ArrayList(); - while (enumeration.hasMoreElements()) { - final NetworkInterface networkInterface = enumeration.nextElement(); - final Enumeration en = networkInterface.getInetAddresses(); - while (en.hasMoreElements()) { - final InetAddress address = en.nextElement(); - if (!address.isLoopbackAddress()) { - if (address instanceof Inet6Address) { - ipv6Result.add(normalizeHostAddress(address)); - } else { - ipv4Result.add(normalizeHostAddress(address)); - } - } - } - } - - // prefer ipv4 - if (!ipv4Result.isEmpty()) { - for (String ip : ipv4Result) { - if (ip.startsWith("127.0") || ip.startsWith("192.168")) { - continue; - } - - return ip; - } - - return ipv4Result.get(ipv4Result.size() - 1); - } else if (!ipv6Result.isEmpty()) { - return ipv6Result.get(0); - } - //If failed to find,fall back to localhost - final InetAddress localHost = InetAddress.getLocalHost(); - return normalizeHostAddress(localHost); - } catch (Exception e) { - log.error("Failed to obtain local address", e); - } - - return null; - } - - public static String normalizeHostAddress(final InetAddress localHost) { - if (localHost instanceof Inet6Address) { - return "[" + localHost.getHostAddress() + "]"; - } else { - return localHost.getHostAddress(); - } - } - - public static SocketAddress string2SocketAddress(final String addr) { - String[] s = addr.split(":"); - InetSocketAddress isa = new InetSocketAddress(s[0], Integer.parseInt(s[1])); - return isa; - } - - public static String socketAddress2String(final SocketAddress addr) { - StringBuilder sb = new StringBuilder(); - InetSocketAddress inetSocketAddress = (InetSocketAddress) addr; - sb.append(inetSocketAddress.getAddress().getHostAddress()); - sb.append(":"); - sb.append(inetSocketAddress.getPort()); - return sb.toString(); - } - - public static SocketChannel connect(SocketAddress remote) { - return connect(remote, 1000 * 5); - } - - public static SocketChannel connect(SocketAddress remote, final int timeoutMillis) { - SocketChannel sc = null; - try { - sc = SocketChannel.open(); - sc.configureBlocking(true); - sc.socket().setSoLinger(false, -1); - sc.socket().setTcpNoDelay(true); - sc.socket().setReceiveBufferSize(1024 * 64); - sc.socket().setSendBufferSize(1024 * 64); - sc.socket().connect(remote, timeoutMillis); - sc.configureBlocking(false); - return sc; - } catch (Exception e) { - if (sc != null) { - try { - sc.close(); - } catch (IOException e1) { - e1.printStackTrace(); - } - } - } - - return null; - } - - -} diff --git a/src/main/java/com/github/unclecatmyself/common/utils/SslUtil.java b/src/main/java/com/github/unclecatmyself/common/utils/SslUtil.java deleted file mode 100644 index 5796806..0000000 --- a/src/main/java/com/github/unclecatmyself/common/utils/SslUtil.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.github.unclecatmyself.common.utils; - -import com.github.unclecatmyself.common.constant.UtilConstant; - -import javax.net.ssl.KeyManagerFactory; -import javax.net.ssl.SSLContext; -import java.io.FileInputStream; -import java.io.InputStream; -import java.security.KeyStore; - -/** - * Created by MySelf on 2019/1/8. - */ -public class SslUtil { - - private static volatile SSLContext sslContext = null; - - public static SSLContext createSSLContext(String type ,String path ,String password) throws Exception { - if(null == sslContext){ - synchronized (SslUtil.class) { - if(null == sslContext){ - KeyStore ks = KeyStore.getInstance(type); /// "JKS"         - InputStream ksInputStream = new FileInputStream(UtilConstant.PATH_PREFIX+path); /// 证书存放地址 - ks.load(ksInputStream, password.toCharArray()); - KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); - kmf.init(ks, password.toCharArray()); - sslContext = SSLContext.getInstance(UtilConstant.INSTANT); - sslContext.init(kmf.getKeyManagers(), null, null); - } - } - } - return sslContext; - } - -} diff --git a/src/main/java/com/github/unclecatmyself/demo1/EchoClient.java b/src/main/java/com/github/unclecatmyself/demo1/EchoClient.java new file mode 100644 index 0000000..6465102 --- /dev/null +++ b/src/main/java/com/github/unclecatmyself/demo1/EchoClient.java @@ -0,0 +1,60 @@ +package com.github.unclecatmyself.demo1; + +import io.netty.bootstrap.Bootstrap; +import io.netty.channel.*; +import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.channel.socket.SocketChannel; +import io.netty.channel.socket.nio.NioSocketChannel; +import io.netty.handler.ssl.SslContext; +import io.netty.handler.ssl.SslContextBuilder; +import io.netty.handler.ssl.util.InsecureTrustManagerFactory; + +/** + * @ClassName EchoClient + * @Description TODO + * @Author MySelf + * @Date 2019/8/17 17:56 + * @Version 1.0 + **/ +public final class EchoClient { + + static final boolean SSL = System.getProperty("ssl") != null; + static final String HOST = System.getProperty("host", "127.0.0.1"); + static final int PORT = Integer.parseInt(System.getProperty("port", "8007")); + static final int SIZE = Integer.parseInt(System.getProperty("size", "256")); + + public static void main(String[] args) throws Exception { + final SslContext sslCtx; + if (SSL){ + sslCtx = SslContextBuilder.forClient() + .trustManager(InsecureTrustManagerFactory.INSTANCE).build(); + }else { + sslCtx = null; + } + + EventLoopGroup group = new NioEventLoopGroup(); + try { + Bootstrap b = new Bootstrap(); + b.group(group) + .channel(NioSocketChannel.class) + .option(ChannelOption.TCP_NODELAY,true) + .handler(new ChannelInitializer() { + @Override + protected void initChannel(SocketChannel sc) throws Exception { + ChannelPipeline p = sc.pipeline(); + if (sslCtx != null){ + p.addLast(sslCtx.newHandler(sc.alloc(),HOST,PORT)); + } + p.addLast(new EchoClientHandler()); + } + }); + + ChannelFuture f = b.connect(HOST,PORT).sync(); + + f.channel().closeFuture().sync(); + }finally { + group.shutdownGracefully(); + } + } + +} diff --git a/src/main/java/com/github/unclecatmyself/demo1/EchoClientHandler.java b/src/main/java/com/github/unclecatmyself/demo1/EchoClientHandler.java new file mode 100644 index 0000000..db3e6fa --- /dev/null +++ b/src/main/java/com/github/unclecatmyself/demo1/EchoClientHandler.java @@ -0,0 +1,46 @@ +package com.github.unclecatmyself.demo1; + +import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelInboundHandlerAdapter; + +/** + * @ClassName EchoClientHandler + * @Description TODO + * @Author MySelf + * @Date 2019/8/17 18:06 + * @Version 1.0 + **/ +public class EchoClientHandler extends ChannelInboundHandlerAdapter { + + private final ByteBuf firstMessage; + + public EchoClientHandler(){ + firstMessage = Unpooled.buffer(EchoClient.SIZE); + for (int i = 0; i < firstMessage.capacity(); i++){ + firstMessage.writeByte((byte)i); + } + } + + @Override + public void channelActive(ChannelHandlerContext ctx) throws Exception { + ctx.writeAndFlush(firstMessage); + } + + @Override + public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { + ctx.write(msg); + } + + @Override + public void channelReadComplete(ChannelHandlerContext ctx) throws Exception { + ctx.flush(); + } + + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { + cause.printStackTrace(); + ctx.close(); + } +} diff --git a/src/main/java/com/github/unclecatmyself/demo1/EchoServer.java b/src/main/java/com/github/unclecatmyself/demo1/EchoServer.java new file mode 100644 index 0000000..e1cfce4 --- /dev/null +++ b/src/main/java/com/github/unclecatmyself/demo1/EchoServer.java @@ -0,0 +1,68 @@ +package com.github.unclecatmyself.demo1; + +import io.netty.bootstrap.ServerBootstrap; +import io.netty.channel.*; +import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.channel.socket.SocketChannel; +import io.netty.channel.socket.nio.NioServerSocketChannel; +import io.netty.channel.socket.nio.NioSocketChannel; +import io.netty.handler.logging.LogLevel; +import io.netty.handler.logging.LoggingHandler; +import io.netty.handler.ssl.SslContext; +import io.netty.handler.ssl.SslContextBuilder; +import io.netty.handler.ssl.util.SelfSignedCertificate; + +/** + * @ClassName EchoServer + * @Description TODO + * @Author MySelf + * @Date 2019/8/17 18:15 + * @Version 1.0 + **/ +public final class EchoServer { + + static final boolean SSL = System.getProperty("ssl") != null; + static final int PORT = Integer.parseInt(System.getProperty("port", "8007")); + + public static void main(String[] args) throws Exception { + final SslContext sslCtx; + if (SSL){ + SelfSignedCertificate ssc = new SelfSignedCertificate(); + sslCtx = SslContextBuilder.forServer(ssc.certificate(), ssc.privateKey()).build(); + }else{ + sslCtx = null; + } + + EventLoopGroup bossGroup = new NioEventLoopGroup(1); + EventLoopGroup workerGroup = new NioEventLoopGroup(); + final EchoServerHandler serverHandler = new EchoServerHandler(); + try { + ServerBootstrap b = new ServerBootstrap(); + b.group(bossGroup,workerGroup) + .channel(NioServerSocketChannel.class) + .option(ChannelOption.SO_BACKLOG,100) + .handler(new LoggingHandler(LogLevel.INFO)) + .childHandler(new ChannelInitializer() { + @Override + protected void initChannel(SocketChannel ch) throws Exception { + ChannelPipeline p = ch.pipeline(); + if (sslCtx != null){ + p.addLast(sslCtx.newHandler(ch.alloc())); + } + p.addLast(serverHandler); + } + }) + ; + + ChannelFuture f = b.bind(PORT).sync(); + + f.channel().closeFuture().sync(); + + }finally { + bossGroup.shutdownGracefully(); + workerGroup.shutdownGracefully(); + } + + } + +} diff --git a/src/main/java/com/github/unclecatmyself/demo1/EchoServerHandler.java b/src/main/java/com/github/unclecatmyself/demo1/EchoServerHandler.java new file mode 100644 index 0000000..96d3bb6 --- /dev/null +++ b/src/main/java/com/github/unclecatmyself/demo1/EchoServerHandler.java @@ -0,0 +1,31 @@ +package com.github.unclecatmyself.demo1; + +import io.netty.channel.ChannelHandler; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelInboundHandlerAdapter; + +/** + * @ClassName EchoServerHandler + * @Description TODO + * @Author MySelf + * @Date 2019/8/17 18:14 + * @Version 1.0 + **/ +@ChannelHandler.Sharable +public class EchoServerHandler extends ChannelInboundHandlerAdapter { + @Override + public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { + ctx.write(msg); + } + + @Override + public void channelReadComplete(ChannelHandlerContext ctx) throws Exception { + ctx.flush(); + } + + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { + cause.printStackTrace(); + ctx.close(); + } +} diff --git a/src/main/java/com/github/unclecatmyself/task/DataAsynchronousTask.java b/src/main/java/com/github/unclecatmyself/task/DataAsynchronousTask.java deleted file mode 100644 index 7714d5e..0000000 --- a/src/main/java/com/github/unclecatmyself/task/DataAsynchronousTask.java +++ /dev/null @@ -1,52 +0,0 @@ -package com.github.unclecatmyself.task; - -import com.github.unclecatmyself.bootstrap.data.InChatToDataBaseService; -import com.github.unclecatmyself.common.constant.LogConstant; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.Map; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.FutureTask; - -/** - * 数据异步转移方法 - * Created by MySelf on 2018/12/3. - */ -public class DataAsynchronousTask { - - private final Logger log = LoggerFactory.getLogger(DataAsynchronousTask.class); - - /** 用户读数据接口伪实现 */ - private final InChatToDataBaseService inChatToDataBaseService; - - - public DataAsynchronousTask(InChatToDataBaseService inChatToDataBaseService){ - this.inChatToDataBaseService = inChatToDataBaseService; - } - - /** - * 将Netty数据消息借助这个方法已新线程发送给用户实现读方法 - * @param maps {@link Map} 传递消息 - */ - public void writeData(Map maps){ - Boolean result = false; - ExecutorService service = Executors.newCachedThreadPool(); - final FutureTask future = new FutureTask(new DataCallable(inChatToDataBaseService,maps)); - service.execute(future); - try { - result = future.get(); - } catch (InterruptedException e) { - e.printStackTrace(); - log.error(LogConstant.DATAASYNCHRONOUSTASK_01); - } catch (ExecutionException e) { - log.error(LogConstant.DATAASYNCHRONOUSTASK_02); - } - if (!result){ - log.error(LogConstant.DATAASYNCHRONOUSTASK_03); - } - } - -} diff --git a/src/main/java/com/github/unclecatmyself/task/DataCallable.java b/src/main/java/com/github/unclecatmyself/task/DataCallable.java deleted file mode 100644 index 902b71b..0000000 --- a/src/main/java/com/github/unclecatmyself/task/DataCallable.java +++ /dev/null @@ -1,30 +0,0 @@ -package com.github.unclecatmyself.task; - -import com.github.unclecatmyself.bootstrap.data.InChatToDataBaseService; -import com.github.unclecatmyself.common.utils.MessageChangeUtil; - -import java.util.Map; -import java.util.concurrent.Callable; - -/** - * 获取结果的异步线程任务 - * Create by UncleCatMySelf in 11:25 2018\12\30 0030 - */ -public class DataCallable implements Callable{ - - /** 用户读数据接口伪实现 */ - private final InChatToDataBaseService inChatToDataBaseService; - /** 消息数据 */ - private final Map maps; - - DataCallable(InChatToDataBaseService inChatToDataBaseService,Map maps) { - this.inChatToDataBaseService = inChatToDataBaseService; - this.maps = maps; - } - - @Override - public Boolean call() throws Exception { - inChatToDataBaseService.writeMessage(MessageChangeUtil.Change(maps)); - return true; - } -} diff --git a/src/main/java/com/github/unclecatmyself/users/DataBaseServiceImpl.java b/src/main/java/com/github/unclecatmyself/users/DataBaseServiceImpl.java deleted file mode 100644 index 331c91b..0000000 --- a/src/main/java/com/github/unclecatmyself/users/DataBaseServiceImpl.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.github.unclecatmyself.users; - -import com.github.unclecatmyself.bootstrap.data.InChatToDataBaseService; -import com.github.unclecatmyself.common.bean.InChatMessage; - -/** - * Created by MySelf on 2019/1/3. - */ -public class DataBaseServiceImpl implements InChatToDataBaseService { - //获取消息 - public Boolean writeMessage(InChatMessage inChatMessage) { - System.out.println(inChatMessage.toString()); - return true; - } -} diff --git a/src/main/java/com/github/unclecatmyself/users/FromServerServiceImpl.java b/src/main/java/com/github/unclecatmyself/users/FromServerServiceImpl.java deleted file mode 100644 index d86ae40..0000000 --- a/src/main/java/com/github/unclecatmyself/users/FromServerServiceImpl.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.github.unclecatmyself.users; - -import com.github.unclecatmyself.bootstrap.channel.http.FromServerService; - -/** - * Created by MySelf on 2019/1/3. - */ -public enum FromServerServiceImpl implements FromServerService { - - TYPE1(1,"【系统通知】您的账号存在异常,请注意安全保密信息。"), - TYPE2(2,"【系统通知】恭喜您连续登录超过5天,奖励5积分。"); - - private Integer code; - - private String message; - - FromServerServiceImpl(Integer code, String message){ - this.code = code; - this.message = message; - } - - public Integer getCode() { - return code; - } - - public String findByCode(Object code) { - Integer codes = (Integer)code; - for (FromServerServiceImpl item: FromServerServiceImpl.values()) { - if (item.code == codes){ - return item.message; - } - } - return null; - } - - public void setCode(Integer code) { - this.code = code; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - -} diff --git a/src/main/java/com/github/unclecatmyself/users/MyInit.java b/src/main/java/com/github/unclecatmyself/users/MyInit.java deleted file mode 100644 index 5e47fac..0000000 --- a/src/main/java/com/github/unclecatmyself/users/MyInit.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.github.unclecatmyself.users; - -import com.github.unclecatmyself.common.bean.InitNetty; - -/** - * Created by MySelf on 2019/1/3. - */ -public class MyInit extends InitNetty { - - @Override - public int getWebport() { - return 8090; - } - - @Override - public Boolean getDistributed() { - return false; - } - - @Override - public boolean isSsl() { - return false; - } - -} diff --git a/src/main/java/com/github/unclecatmyself/users/VerifyServiceImpl.java b/src/main/java/com/github/unclecatmyself/users/VerifyServiceImpl.java deleted file mode 100644 index 8bcbb5d..0000000 --- a/src/main/java/com/github/unclecatmyself/users/VerifyServiceImpl.java +++ /dev/null @@ -1,21 +0,0 @@ -package com.github.unclecatmyself.users; - -import com.alibaba.fastjson.JSONArray; -import com.github.unclecatmyself.bootstrap.verify.InChatVerifyService; - -/** - * Created by MySelf on 2019/1/3. - */ -public class VerifyServiceImpl implements InChatVerifyService { - - - public boolean verifyToken(String token) { - return true; - } - - - public JSONArray getArrayByGroupId(String groupId) { - JSONArray jsonArray = JSONArray.parseArray("[\"1111\",\"2222\",\"3333\"]"); - return jsonArray; - } -} diff --git a/src/main/resources/log4j.properties b/src/main/resources/log4j.properties deleted file mode 100644 index 30185a7..0000000 --- a/src/main/resources/log4j.properties +++ /dev/null @@ -1,17 +0,0 @@ -log4j.rootLogger=debug, stdout - -log4j.appender.stdout=org.apache.log4j.ConsoleAppender -log4j.appender.stdout.layout=org.apache.log4j.PatternLayout - -log4j.appender.stdout.layout.ConversionPattern=%5p - %m%n - -#log4j.appender.R=org.apache.log4j.RollingFileAppender -#log4j.appender.R.File=firestorm.log - -log4j.appender.R.MaxFileSize=100KB -log4j.appender.R.MaxBackupIndex=1 - -log4j.appender.R.layout=org.apache.log4j.PatternLayout -log4j.appender.R.layout.ConversionPattern=%p %t %c - %m%n - -log4j.logger.com.codefutures=DEBUG \ No newline at end of file diff --git a/src/test/java/com/github/unclecatmyself/common/utils/RedisUtilTests.java b/src/test/java/com/github/unclecatmyself/common/utils/RedisUtilTests.java deleted file mode 100644 index 21cf2db..0000000 --- a/src/test/java/com/github/unclecatmyself/common/utils/RedisUtilTests.java +++ /dev/null @@ -1,51 +0,0 @@ -package com.github.unclecatmyself.common.utils; - -import org.junit.Assert; -import org.junit.Test; - -public class RedisUtilTests { - - @Test - public void testString2MD5() { - Assert.assertEquals("d41d8cd98f00b204e9800998ecf8427e", - RedisUtil.string2MD5("")); - Assert.assertEquals("202cb962ac59075b964b07152d234b70", - RedisUtil.string2MD5("123")); - Assert.assertEquals("acbd18db4cc2f85cedef654fccc4a4d8", - RedisUtil.string2MD5("foo")); - Assert.assertEquals("8a6551f0a3e52a89dbf095f3ea1fe59f", - RedisUtil.string2MD5("£$%^&*")); - } - - @Test - public void testConvertMD5() { - Assert.assertEquals("", RedisUtil.convertMD5("")); - Assert.assertEquals("EFG", RedisUtil.convertMD5("123")); - Assert.assertEquals("\u0012\u001B\u001B", RedisUtil.convertMD5("foo")); - Assert.assertEquals("PQ*R^", RedisUtil.convertMD5("$%^&*")); - } - - @Test - public void testConvertMD52() { - Assert.assertEquals("\u001A\u0001\u0018\u0018R\u001A\u0001\u0018" + - "\u0018Q=\u001A7\u001C\u0015\u0000", - RedisUtil.convertMD5(null, null)); - Assert.assertEquals("\u0012\u001B\u001BR\u001A\u0001\u0018\u0018Q=" + - "\u001A7\u001C\u0015\u0000", RedisUtil.convertMD5("foo", null)); - Assert.assertEquals("\u001A\u0001\u0018\u0018R\u0012\u001B\u001BQ=" + - "\u001A7\u001C\u0015\u0000", RedisUtil.convertMD5(null, "foo")); - Assert.assertEquals("RQ=\u001A7\u001C\u0015\u0000", - RedisUtil.convertMD5("", "")); - Assert.assertEquals("\u0012\u001B\u001BR\u0012\u001B\u001BQ=\u001A7" + - "\u001C\u0015\u0000", RedisUtil.convertMD5("foo", "foo")); - Assert.assertEquals("EF×PQGR\u0012\u001B\u001BQ=\u001A7\u001C\u0015" + - "\u0000", RedisUtil.convertMD5("12£$%3", "foo")); - } - - @Test - public void testGetAddress() { - Assert.assertEquals("", RedisUtil.getAddress("")); - Assert.assertEquals("foobarbaz", RedisUtil.getAddress("foobarbaz")); - Assert.assertEquals("foo", RedisUtil.getAddress("foo&bar&baz")); - } -} From bada63212a93613572f9d0a331fc1097dee94afd Mon Sep 17 00:00:00 2001 From: MySelf <1341933031@qq.com> Date: Sun, 18 Aug 2019 11:42:00 +0800 Subject: [PATCH 2/7] =?UTF-8?q?=E5=A4=A9=C3=A4=C3=A6=C2=BB=E5=8A=A0?= =?UTF-8?q?=E6=B3=A8=E8=A7=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + doc/echo.md | 12 ++++++++++++ .../unclecatmyself/demo1/EchoClient.java | 19 ++++++++++++++++--- .../demo1/EchoClientHandler.java | 2 ++ .../unclecatmyself/demo1/EchoServer.java | 4 ++-- 5 files changed, 33 insertions(+), 5 deletions(-) create mode 100644 doc/echo.md diff --git a/README.md b/README.md index f1c27d2..6baeebb 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,7 @@ ## 官方教程 +- [1、Echo简单通讯](doc/echo.md) [地址](https://github.com/AwakenCN/InChat/tree/official-demo/src/main/java/com/github/unclecatmyself/demo1) ## 公众号:Java猫说 diff --git a/doc/echo.md b/doc/echo.md new file mode 100644 index 0000000..7a4ad78 --- /dev/null +++ b/doc/echo.md @@ -0,0 +1,12 @@ +## Echo简易通讯案例 + +> 版本:netty 4.1.* +> +> 申明:本文旨在重新分享讨论Netty官方相关案例,添加部分个人理解与要点解析。 + +这个是InChat的案例[地址](https://github.com/AwakenCN/InChat/tree/official-demo/src/main/java/com/github/unclecatmyself/demo1),里面补充了详细的注释,比起官方会容易看一点。 + +官方案例地址:https://netty.io/4.1/xref/io/netty/example/echo/package-summary.html + + + diff --git a/src/main/java/com/github/unclecatmyself/demo1/EchoClient.java b/src/main/java/com/github/unclecatmyself/demo1/EchoClient.java index 6465102..52c9f39 100644 --- a/src/main/java/com/github/unclecatmyself/demo1/EchoClient.java +++ b/src/main/java/com/github/unclecatmyself/demo1/EchoClient.java @@ -11,27 +11,36 @@ /** * @ClassName EchoClient - * @Description TODO + * @Description 一个简单的应答通讯的实例 * @Author MySelf * @Date 2019/8/17 17:56 * @Version 1.0 **/ public final class EchoClient { + //判断是否加密 static final boolean SSL = System.getProperty("ssl") != null; + //监听本地服务 static final String HOST = System.getProperty("host", "127.0.0.1"); + //监听端口 static final int PORT = Integer.parseInt(System.getProperty("port", "8007")); + //发送消息的大小,用于EchoClientHandler static final int SIZE = Integer.parseInt(System.getProperty("size", "256")); public static void main(String[] args) throws Exception { + //公共抽象类,安全套接字协议实现充当工厂SSLEngine和SslHandler。在内部,它通过JDK SSLContext或OpenSSL 实现SSL_CTX final SslContext sslCtx; if (SSL){ + //用于配置新SslContext以进行创建的构建器 sslCtx = SslContextBuilder.forClient() + //用于验证远程端点证书的可信管理器 + //InsecureTrustManagerFactory:在TrustManagerFactory没有任何验证的情况下信任所有X.509证书的不安全因素 + //注:切勿TrustManagerFactory在生产中使用它。它纯粹是出于测试目的,因此非常不安全。 .trustManager(InsecureTrustManagerFactory.INSTANCE).build(); }else { sslCtx = null; } - + //事件循环 EventLoopGroup group = new NioEventLoopGroup(); try { Bootstrap b = new Bootstrap(); @@ -42,16 +51,20 @@ public static void main(String[] args) throws Exception { @Override protected void initChannel(SocketChannel sc) throws Exception { ChannelPipeline p = sc.pipeline(); + //了解SslContext的用法 if (sslCtx != null){ p.addLast(sslCtx.newHandler(sc.alloc(),HOST,PORT)); } p.addLast(new EchoClientHandler()); } }); - + //这个sync后的代码均会执行 ChannelFuture f = b.connect(HOST,PORT).sync(); + System.out.println("before-----"); + //这个sync后的代码不会执行 f.channel().closeFuture().sync(); + System.out.println("after-----"); }finally { group.shutdownGracefully(); } diff --git a/src/main/java/com/github/unclecatmyself/demo1/EchoClientHandler.java b/src/main/java/com/github/unclecatmyself/demo1/EchoClientHandler.java index db3e6fa..6ecd414 100644 --- a/src/main/java/com/github/unclecatmyself/demo1/EchoClientHandler.java +++ b/src/main/java/com/github/unclecatmyself/demo1/EchoClientHandler.java @@ -17,6 +17,8 @@ public class EchoClientHandler extends ChannelInboundHandlerAdapter { private final ByteBuf firstMessage; public EchoClientHandler(){ + //获取EchoClient的SIZE + //Unpooled:ByteBuf通过分配新空间或通过包装或复制现有字节数组,字节缓冲区和字符串来创建新的 firstMessage = Unpooled.buffer(EchoClient.SIZE); for (int i = 0; i < firstMessage.capacity(); i++){ firstMessage.writeByte((byte)i); diff --git a/src/main/java/com/github/unclecatmyself/demo1/EchoServer.java b/src/main/java/com/github/unclecatmyself/demo1/EchoServer.java index e1cfce4..b9bbf8c 100644 --- a/src/main/java/com/github/unclecatmyself/demo1/EchoServer.java +++ b/src/main/java/com/github/unclecatmyself/demo1/EchoServer.java @@ -27,6 +27,7 @@ public final class EchoServer { public static void main(String[] args) throws Exception { final SslContext sslCtx; if (SSL){ + //SelfSignedCertificate:生成临时自签名证书以进行测试 SelfSignedCertificate ssc = new SelfSignedCertificate(); sslCtx = SslContextBuilder.forServer(ssc.certificate(), ssc.privateKey()).build(); }else{ @@ -51,8 +52,7 @@ protected void initChannel(SocketChannel ch) throws Exception { } p.addLast(serverHandler); } - }) - ; + }); ChannelFuture f = b.bind(PORT).sync(); From 251cc441b9ddbac229faf343922847d5423bc1d5 Mon Sep 17 00:00:00 2001 From: MySelf <1341933031@qq.com> Date: Sun, 18 Aug 2019 11:56:55 +0800 Subject: [PATCH 3/7] update --- doc/echo.md | 238 ++++++++++++++++++ .../unclecatmyself/demo1/EchoServer.java | 2 +- 2 files changed, 239 insertions(+), 1 deletion(-) diff --git a/doc/echo.md b/doc/echo.md index 7a4ad78..47c1861 100644 --- a/doc/echo.md +++ b/doc/echo.md @@ -8,5 +8,243 @@ 官方案例地址:https://netty.io/4.1/xref/io/netty/example/echo/package-summary.html +### 正文 +- EchoClient(客户端) +- EchoClientHandler +- EchoServer(服务端) +- EchoServerHandler +### 要点介绍 + +- SslContext + +官方介绍:https://netty.io/4.1/api/io/netty/handler/ssl/SslContext.html + +公共抽象类,安全套接字协议实现充当工厂SSLEngine和SslHandler。在内部,它通过JDK SSLContext或OpenSSL 实现SSL_CTX,还有关于它的使用方式,如果你需要ssl加密的话 + +- SslContextBuilder + +官方介绍:https://netty.io/4.1/api/io/netty/handler/ssl/SslContextBuilder.html + +用于配置新SslContext以进行创建的构建器,其中包含多个方法这里就不多补充,大家可以去看看 + +- InsecureTrustManagerFactory + +官方介绍:https://netty.io/4.1/api/io/netty/handler/ssl/util/InsecureTrustManagerFactory.html + +在TrustManagerFactory没有任何验证的情况下信任所有X.509证书的不安全因素 + +> 注意:切勿TrustManagerFactory在生产中使用它。它纯粹是出于测试目的,因此非常不安全。 + +- SelfSignedCertificate + +官方介绍:https://netty.io/4.1/api/io/netty/handler/ssl/util/SelfSignedCertificate.html + +生成临时自签名证书以进行测试 + +> 注意:切勿在生产中使用此类生成的证书和私钥。它纯粹是出于测试目的,因此非常不安全。它甚至使用不安全的伪随机生成器在内部更快地生成 + +### 项目源码 + +- EchoClient + +```java +/** + * @ClassName EchoClient + * @Description 一个简单的应答通讯的实例 + * @Author MySelf + * @Date 2019/8/17 17:56 + * @Version 1.0 + **/ +public final class EchoClient { + + //判断是否加密 + static final boolean SSL = System.getProperty("ssl") != null; + //监听本地服务 + static final String HOST = System.getProperty("host", "127.0.0.1"); + //监听端口 + static final int PORT = Integer.parseInt(System.getProperty("port", "8007")); + //发送消息的大小,用于EchoClientHandler + static final int SIZE = Integer.parseInt(System.getProperty("size", "256")); + + public static void main(String[] args) throws Exception { + //公共抽象类,安全套接字协议实现充当工厂SSLEngine和SslHandler。在内部,它通过JDK SSLContext或OpenSSL 实现SSL_CTX + final SslContext sslCtx; + if (SSL){ + //用于配置新SslContext以进行创建的构建器 + sslCtx = SslContextBuilder.forClient() + //用于验证远程端点证书的可信管理器 + //InsecureTrustManagerFactory:在TrustManagerFactory没有任何验证的情况下信任所有X.509证书的不安全因素 + //注:切勿TrustManagerFactory在生产中使用它。它纯粹是出于测试目的,因此非常不安全。 + .trustManager(InsecureTrustManagerFactory.INSTANCE).build(); + }else { + sslCtx = null; + } + //事件循环 + EventLoopGroup group = new NioEventLoopGroup(); + try { + Bootstrap b = new Bootstrap(); + b.group(group) + .channel(NioSocketChannel.class) + .option(ChannelOption.TCP_NODELAY,true) + .handler(new ChannelInitializer() { + @Override + protected void initChannel(SocketChannel sc) throws Exception { + ChannelPipeline p = sc.pipeline(); + //了解SslContext的用法 + if (sslCtx != null){ + p.addLast(sslCtx.newHandler(sc.alloc(),HOST,PORT)); + } + p.addLast(new EchoClientHandler()); + } + }); + //这个sync后的代码均会执行 + ChannelFuture f = b.connect(HOST,PORT).sync(); + System.out.println("before-----"); + + //这个sync后的代码不会执行 + f.channel().closeFuture().sync(); + System.out.println("after-----"); + }finally { + group.shutdownGracefully(); + } + } + +} +``` + +- EchoClientHandler + +```java +/** + * @ClassName EchoClientHandler + * @Description TODO + * @Author MySelf + * @Date 2019/8/17 18:06 + * @Version 1.0 + **/ +public class EchoClientHandler extends ChannelInboundHandlerAdapter { + + private final ByteBuf firstMessage; + + public EchoClientHandler(){ + //获取EchoClient的SIZE + //Unpooled:ByteBuf通过分配新空间或通过包装或复制现有字节数组,字节缓冲区和字符串来创建新的 + firstMessage = Unpooled.buffer(EchoClient.SIZE); + for (int i = 0; i < firstMessage.capacity(); i++){ + firstMessage.writeByte((byte)i); + } + } + + @Override + public void channelActive(ChannelHandlerContext ctx) throws Exception { + ctx.writeAndFlush(firstMessage); + } + + @Override + public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { + ctx.write(msg); + } + + @Override + public void channelReadComplete(ChannelHandlerContext ctx) throws Exception { + ctx.flush(); + } + + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { + cause.printStackTrace(); + ctx.close(); + } +} +``` + +- EchoServer + +```java +/** + * @ClassName EchoServer + * @Description 服务端 + * @Author MySelf + * @Date 2019/8/17 18:15 + * @Version 1.0 + **/ +public final class EchoServer { + + static final boolean SSL = System.getProperty("ssl") != null; + static final int PORT = Integer.parseInt(System.getProperty("port", "8007")); + + public static void main(String[] args) throws Exception { + final SslContext sslCtx; + if (SSL){ + //SelfSignedCertificate:生成临时自签名证书以进行测试 + SelfSignedCertificate ssc = new SelfSignedCertificate(); + sslCtx = SslContextBuilder.forServer(ssc.certificate(), ssc.privateKey()).build(); + }else{ + sslCtx = null; + } + + EventLoopGroup bossGroup = new NioEventLoopGroup(1); + EventLoopGroup workerGroup = new NioEventLoopGroup(); + final EchoServerHandler serverHandler = new EchoServerHandler(); + try { + ServerBootstrap b = new ServerBootstrap(); + b.group(bossGroup,workerGroup) + .channel(NioServerSocketChannel.class) + .option(ChannelOption.SO_BACKLOG,100) + .handler(new LoggingHandler(LogLevel.INFO)) + .childHandler(new ChannelInitializer() { + @Override + protected void initChannel(SocketChannel ch) throws Exception { + ChannelPipeline p = ch.pipeline(); + if (sslCtx != null){ + p.addLast(sslCtx.newHandler(ch.alloc())); + } + p.addLast(serverHandler); + } + }); + + ChannelFuture f = b.bind(PORT).sync(); + + f.channel().closeFuture().sync(); + + }finally { + bossGroup.shutdownGracefully(); + workerGroup.shutdownGracefully(); + } + + } + +} +``` + +- EchoServerHandler + +```java +/** + * @ClassName EchoServerHandler + * @Description TODO + * @Author MySelf + * @Date 2019/8/17 18:14 + * @Version 1.0 + **/ +@ChannelHandler.Sharable +public class EchoServerHandler extends ChannelInboundHandlerAdapter { + @Override + public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { + ctx.write(msg); + } + + @Override + public void channelReadComplete(ChannelHandlerContext ctx) throws Exception { + ctx.flush(); + } + + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { + cause.printStackTrace(); + ctx.close(); + } +} +``` \ No newline at end of file diff --git a/src/main/java/com/github/unclecatmyself/demo1/EchoServer.java b/src/main/java/com/github/unclecatmyself/demo1/EchoServer.java index b9bbf8c..02d4320 100644 --- a/src/main/java/com/github/unclecatmyself/demo1/EchoServer.java +++ b/src/main/java/com/github/unclecatmyself/demo1/EchoServer.java @@ -14,7 +14,7 @@ /** * @ClassName EchoServer - * @Description TODO + * @Description 服务端 * @Author MySelf * @Date 2019/8/17 18:15 * @Version 1.0 From 7de355aa641f9cb5dd9871cecbe35cbd2ebd2d06 Mon Sep 17 00:00:00 2001 From: MySelf <1341933031@qq.com> Date: Mon, 19 Aug 2019 21:06:04 +0800 Subject: [PATCH 4/7] =?UTF-8?q?=E6=B7=BB=E5=8A=A0discard?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doc/discard.md | 8 +++ .../unclecatmyself/demo2/DiscardClient.java | 71 +++++++++++++++++++ .../demo2/DiscardClientHandler.java | 71 +++++++++++++++++++ .../unclecatmyself/demo2/DiscardServer.java | 71 +++++++++++++++++++ .../demo2/DiscardServerHandler.java | 26 +++++++ 5 files changed, 247 insertions(+) create mode 100644 doc/discard.md create mode 100644 src/main/java/com/github/unclecatmyself/demo2/DiscardClient.java create mode 100644 src/main/java/com/github/unclecatmyself/demo2/DiscardClientHandler.java create mode 100644 src/main/java/com/github/unclecatmyself/demo2/DiscardServer.java create mode 100644 src/main/java/com/github/unclecatmyself/demo2/DiscardServerHandler.java diff --git a/doc/discard.md b/doc/discard.md new file mode 100644 index 0000000..2d694bb --- /dev/null +++ b/doc/discard.md @@ -0,0 +1,8 @@ +## 无限异步发送数据流 + +> 版本:netty 4.1.* +> +> 申明:本文旨在重新分享讨论Netty官方相关案例,添加部分个人理解与要点解析。 + + + diff --git a/src/main/java/com/github/unclecatmyself/demo2/DiscardClient.java b/src/main/java/com/github/unclecatmyself/demo2/DiscardClient.java new file mode 100644 index 0000000..309f6dd --- /dev/null +++ b/src/main/java/com/github/unclecatmyself/demo2/DiscardClient.java @@ -0,0 +1,71 @@ +package com.github.unclecatmyself.demo2; + +import com.github.unclecatmyself.demo1.EchoClientHandler; +import io.netty.bootstrap.Bootstrap; +import io.netty.channel.*; +import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.channel.socket.SocketChannel; +import io.netty.channel.socket.nio.NioSocketChannel; +import io.netty.handler.ssl.SslContext; +import io.netty.handler.ssl.SslContextBuilder; +import io.netty.handler.ssl.util.InsecureTrustManagerFactory; + +/** + * @ClassName DiscardClient + * @Description TODO + * @Author MySelf + * @Date 2019/8/19 20:38 + * @Version 1.0 + **/ +public final class DiscardClient { + + //判断是否加密 + static final boolean SSL = System.getProperty("ssl") != null; + //监听本地服务 + static final String HOST = System.getProperty("host", "127.0.0.1"); + //监听端口 + static final int PORT = Integer.parseInt(System.getProperty("port", "8007")); + //发送消息的大小,用于EchoClientHandler + static final int SIZE = Integer.parseInt(System.getProperty("size", "256")); + + public static void main(String[] args) throws Exception { + //公共抽象类,安全套接字协议实现充当工厂SSLEngine和SslHandler。在内部,它通过JDK SSLContext或OpenSSL 实现SSL_CTX + final SslContext sslCtx; + if (SSL){ + //用于配置新SslContext以进行创建的构建器 + sslCtx = SslContextBuilder.forClient() + //用于验证远程端点证书的可信管理器 + //InsecureTrustManagerFactory:在TrustManagerFactory没有任何验证的情况下信任所有X.509证书的不安全因素 + //注:切勿TrustManagerFactory在生产中使用它。它纯粹是出于测试目的,因此非常不安全。 + .trustManager(InsecureTrustManagerFactory.INSTANCE).build(); + }else { + sslCtx = null; + } + //事件循环 + EventLoopGroup group = new NioEventLoopGroup(); + try { + Bootstrap b = new Bootstrap(); + b.group(group) + .channel(NioSocketChannel.class) + .option(ChannelOption.TCP_NODELAY,true) + .handler(new ChannelInitializer() { + @Override + protected void initChannel(SocketChannel sc) throws Exception { + ChannelPipeline p = sc.pipeline(); + //了解SslContext的用法 + if (sslCtx != null){ + p.addLast(sslCtx.newHandler(sc.alloc(),HOST,PORT)); + } + p.addLast(new DiscardClientHandler()); + } + }); + + ChannelFuture f = b.connect(HOST,PORT).sync(); + + f.channel().closeFuture().sync(); + }finally { + group.shutdownGracefully(); + } + } + +} diff --git a/src/main/java/com/github/unclecatmyself/demo2/DiscardClientHandler.java b/src/main/java/com/github/unclecatmyself/demo2/DiscardClientHandler.java new file mode 100644 index 0000000..24f67a0 --- /dev/null +++ b/src/main/java/com/github/unclecatmyself/demo2/DiscardClientHandler.java @@ -0,0 +1,71 @@ +package com.github.unclecatmyself.demo2; + +import io.netty.buffer.ByteBuf; +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelFutureListener; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.SimpleChannelInboundHandler; + +/** + * @ClassName DiscardClientHandler + * @Description TODO + * @Author MySelf + * @Date 2019/8/19 20:38 + * @Version 1.0 + **/ +public class DiscardClientHandler extends SimpleChannelInboundHandler { + + private ByteBuf content; + private ChannelHandlerContext ctx; + + @Override + public void channelActive(ChannelHandlerContext ctx) throws Exception { + this.ctx = ctx; + + // 初始化消息 + content = ctx.alloc().directBuffer(DiscardClient.SIZE).writeZero(DiscardClient.SIZE); + + // 发送初始信息 + generateTraffic(); + } + + @Override + public void channelInactive(ChannelHandlerContext ctx) throws Exception { + content.release(); + } + + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { + // 引发异常时关闭连接 + cause.printStackTrace(); + ctx.close(); + } + + @Override + protected void channelRead0(ChannelHandlerContext channelHandlerContext, Object o) throws Exception { + // 服务器应该不发送任何内容,但如果它发送什么,丢弃它。 + } + + long counter; + + // 生成数据 + private void generateTraffic(){ + // 将出站缓冲区刷新到套接字 + // 刷新后,再次生成相同数量的流量 + ctx.writeAndFlush(content.retainedDuplicate()).addListener(trafficGenerator); + } + + // 数据触发 + private final ChannelFutureListener trafficGenerator = new ChannelFutureListener() { + @Override + public void operationComplete(ChannelFuture channelFuture) throws Exception { + if (channelFuture.isSuccess()){ + generateTraffic(); + }else { + channelFuture.cause().printStackTrace(); + channelFuture.channel().close(); + } + } + }; + +} diff --git a/src/main/java/com/github/unclecatmyself/demo2/DiscardServer.java b/src/main/java/com/github/unclecatmyself/demo2/DiscardServer.java new file mode 100644 index 0000000..77aa095 --- /dev/null +++ b/src/main/java/com/github/unclecatmyself/demo2/DiscardServer.java @@ -0,0 +1,71 @@ +package com.github.unclecatmyself.demo2; + +import com.github.unclecatmyself.demo1.EchoServerHandler; +import io.netty.bootstrap.ServerBootstrap; +import io.netty.channel.*; +import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.channel.socket.SocketChannel; +import io.netty.channel.socket.nio.NioServerSocketChannel; +import io.netty.handler.logging.LogLevel; +import io.netty.handler.logging.LoggingHandler; +import io.netty.handler.ssl.SslContext; +import io.netty.handler.ssl.SslContextBuilder; +import io.netty.handler.ssl.util.SelfSignedCertificate; + +/** + * @ClassName DiscardServer + * @Description TODO + * @Author MySelf + * @Date 2019/8/19 20:38 + * @Version 1.0 + **/ +public class DiscardServer { + + static final boolean SSL = System.getProperty("ssl") != null; + static final int PORT = Integer.parseInt(System.getProperty("port", "8007")); + + public static void main(String[] args) throws Exception { + final SslContext sslCtx; + if (SSL){ + //SelfSignedCertificate:生成临时自签名证书以进行测试 + SelfSignedCertificate ssc = new SelfSignedCertificate(); + sslCtx = SslContextBuilder.forServer(ssc.certificate(), ssc.privateKey()).build(); + }else{ + sslCtx = null; + } + + EventLoopGroup bossGroup = new NioEventLoopGroup(1); + EventLoopGroup workerGroup = new NioEventLoopGroup(); + + try { + ServerBootstrap b = new ServerBootstrap(); + b.group(bossGroup,workerGroup) + .channel(NioServerSocketChannel.class) + .option(ChannelOption.SO_BACKLOG,100) + .handler(new LoggingHandler(LogLevel.INFO)) + .childHandler(new ChannelInitializer() { + @Override + protected void initChannel(SocketChannel ch) throws Exception { + ChannelPipeline p = ch.pipeline(); + if (sslCtx != null){ + p.addLast(sslCtx.newHandler(ch.alloc())); + } + p.addLast(new DiscardServerHandler()); + } + }); + + // 绑定并开始接受传入连接 + ChannelFuture f = b.bind(PORT).sync(); + + // 等待服务器套接字关闭 + // 这个例子,这不会发生,但你可以这样优雅的做 + f.channel().closeFuture().sync(); + + }finally { + bossGroup.shutdownGracefully(); + workerGroup.shutdownGracefully(); + } + + } + +} diff --git a/src/main/java/com/github/unclecatmyself/demo2/DiscardServerHandler.java b/src/main/java/com/github/unclecatmyself/demo2/DiscardServerHandler.java new file mode 100644 index 0000000..3b54da1 --- /dev/null +++ b/src/main/java/com/github/unclecatmyself/demo2/DiscardServerHandler.java @@ -0,0 +1,26 @@ +package com.github.unclecatmyself.demo2; + +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.SimpleChannelInboundHandler; + +/** + * @ClassName DiscardServerHandler + * @Description TODO + * @Author MySelf + * @Date 2019/8/19 20:39 + * @Version 1.0 + **/ +public class DiscardServerHandler extends SimpleChannelInboundHandler { + + @Override + protected void channelRead0(ChannelHandlerContext channelHandlerContext, Object o) throws Exception { + // discard + } + + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { + // 引发异常时关闭连接 + cause.printStackTrace(); + ctx.close(); + } +} From 625046648bf1f12fa475fb572619f47317e4ca8b Mon Sep 17 00:00:00 2001 From: MySelf <1341933031@qq.com> Date: Mon, 19 Aug 2019 21:40:07 +0800 Subject: [PATCH 5/7] =?UTF-8?q?=E6=9B=B4=E6=96=B0md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doc/discard.md | 263 ++++++++++++++++++ .../demo2/DiscardClientHandler.java | 4 +- 2 files changed, 265 insertions(+), 2 deletions(-) diff --git a/doc/discard.md b/doc/discard.md index 2d694bb..83fbfda 100644 --- a/doc/discard.md +++ b/doc/discard.md @@ -4,5 +4,268 @@ > > 申明:本文旨在重新分享讨论Netty官方相关案例,添加部分个人理解与要点解析。 +这个是[InChat](https://github.com/AwakenCN/InChat)的案例[地址](https://github.com/AwakenCN/InChat/tree/official-demo/src/main/java/com/github/unclecatmyself/demo2),里面补充了详细的注释,比起官方会容易看一点。 +官方案例地址:https://netty.io/4.1/xref/io/netty/example/echo/package-summary.html +### 正文 + +- DiscardClient(客户端) +- DiscardClientHandler +- DiscardServer(服务端) +- DiscardServerHandler + +### 要点介绍 + +- ChannelInboundHandlerAdapter [官方介绍](https://netty.io/4.1/api/io/netty/channel/ChannelInboundHandlerAdapter.html) + +实现了抽象基类ChannelInboundHandler,因此也提供其所有方法的实现,子类可以重写方法实现来改变它。 + +> 注意:channelRead(ChannelHandlerContext, Object) 方法自动返回后不会释放消息。如果您正在寻找ChannelInboundHandler自动发布收到的消息的实现,请参阅SimpleChannelInboundHandler + +- SimpleChannelInboundHandler [官方介绍](https://netty.io/4.1/api/io/netty/channel/SimpleChannelInboundHandler.html) + +允许显式只处理特定类型的消息 + +- writeZero(int length) [官方介绍](https://netty.io/4.1/api/io/netty/buffer/ByteBuf.html#writeZero-int-) + +从当前开始 用(0x00)填充此缓冲区writerIndex并按writerIndex指定值增加length。如果this.writableBytes小于length,ensureWritable(int) 将调用以尝试扩展容量以适应。 + +- directBuffer(int initialCapacity) [官方介绍](https://netty.io/4.1/api/io/netty/buffer/ByteBufAllocator.html#directBuffer-int-) + +使用给定的初始值给ByteBuf分配直接值 + +- release() [官方介绍](https://netty.io/4.1/api/io/netty/util/ReferenceCounted.html#release--) + +每一个新分配的ByteBuf的引用计数值为1,每对这个ByteBuf对象增加一个引用,需要调用ByteBuf.retain()方法,而每减少一个引用,需要调用ByteBuf.release()方法。当这个ByteBuf对象的引用计数值为0时,表示此对象可回收 + +- retainedDuplicate() [官方介绍](https://netty.io/4.1/api/io/netty/buffer/ByteBuf.html#retainedDuplicate--) + +返回保留的缓冲区,该缓冲区共享此缓冲区的整个区域。修改返回的缓冲区或此缓冲区的内容会影响彼此的内容,同时它们会维护单独的索引和标记。此方法的行为类似于此方法,duplicate().retain()但此方法可能返回产生较少垃圾的缓冲区实现。 + +- ChannelFutureListener [官方介绍](https://netty.io/4.1/api/io/netty/channel/ChannelFutureListener.html) + +监听一个ChannelFuture的结果。Channel一旦通过调用添加此侦听器,将以ChannelFuture.addListener(GenericFutureListener)异步I / O的操作通知结果。 + +### 项目源码 + + +- DiscardClient(客户端) + +```java +/** + * @ClassName DiscardClient + * @Description TODO + * @Author MySelf + * @Date 2019/8/19 20:38 + * @Version 1.0 + **/ +public final class DiscardClient { + + //判断是否加密 + static final boolean SSL = System.getProperty("ssl") != null; + //监听本地服务 + static final String HOST = System.getProperty("host", "127.0.0.1"); + //监听端口 + static final int PORT = Integer.parseInt(System.getProperty("port", "8007")); + //发送消息的大小,用于EchoClientHandler + static final int SIZE = Integer.parseInt(System.getProperty("size", "256")); + + public static void main(String[] args) throws Exception { + //公共抽象类,安全套接字协议实现充当工厂SSLEngine和SslHandler。在内部,它通过JDK SSLContext或OpenSSL 实现SSL_CTX + final SslContext sslCtx; + if (SSL){ + //用于配置新SslContext以进行创建的构建器 + sslCtx = SslContextBuilder.forClient() + //用于验证远程端点证书的可信管理器 + //InsecureTrustManagerFactory:在TrustManagerFactory没有任何验证的情况下信任所有X.509证书的不安全因素 + //注:切勿TrustManagerFactory在生产中使用它。它纯粹是出于测试目的,因此非常不安全。 + .trustManager(InsecureTrustManagerFactory.INSTANCE).build(); + }else { + sslCtx = null; + } + //事件循环 + EventLoopGroup group = new NioEventLoopGroup(); + try { + Bootstrap b = new Bootstrap(); + b.group(group) + .channel(NioSocketChannel.class) + .option(ChannelOption.TCP_NODELAY,true) + .handler(new ChannelInitializer() { + @Override + protected void initChannel(SocketChannel sc) throws Exception { + ChannelPipeline p = sc.pipeline(); + //了解SslContext的用法 + if (sslCtx != null){ + p.addLast(sslCtx.newHandler(sc.alloc(),HOST,PORT)); + } + p.addLast(new DiscardClientHandler()); + } + }); + + ChannelFuture f = b.connect(HOST,PORT).sync(); + + f.channel().closeFuture().sync(); + }finally { + group.shutdownGracefully(); + } + } + +} +``` + +- DiscardClientHandler + +```java +/** + * @ClassName DiscardClientHandler + * @Description TODO + * @Author MySelf + * @Date 2019/8/19 20:38 + * @Version 1.0 + **/ +public class DiscardClientHandler extends SimpleChannelInboundHandler { + + private ByteBuf content; + private ChannelHandlerContext ctx; + + @Override + public void channelActive(ChannelHandlerContext ctx) throws Exception { + this.ctx = ctx; + + // 初始化消息 + content = ctx.alloc().directBuffer(DiscardClient.SIZE).writeZero(DiscardClient.SIZE); + + // 发送初始信息 + generateTraffic(); + } + + @Override + public void channelInactive(ChannelHandlerContext ctx) throws Exception { + //引用计数为0,释放 + content.release(); + } + + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { + // 引发异常时关闭连接 + cause.printStackTrace(); + ctx.close(); + } + + @Override + protected void channelRead0(ChannelHandlerContext channelHandlerContext, Object o) throws Exception { + // 服务器应该不发送任何内容,但如果它发送什么,丢弃它。 + } + + // 生成数据 + private void generateTraffic(){ + // 将出站缓冲区刷新到套接字 + // 刷新后,再次生成相同数量的流量 + ctx.writeAndFlush(content.retainedDuplicate()).addListener(trafficGenerator); + } + + // 数据触发 + private final ChannelFutureListener trafficGenerator = new ChannelFutureListener() { + //完成操作后的方法调用,即只要成功无限调用generateTraffic() + @Override + public void operationComplete(ChannelFuture channelFuture) throws Exception { + if (channelFuture.isSuccess()){ + generateTraffic(); + }else { + channelFuture.cause().printStackTrace(); + channelFuture.channel().close(); + } + } + }; + +} +``` + +- DiscardServer(服务端) + +```java +/** + * @ClassName DiscardServer + * @Description TODO + * @Author MySelf + * @Date 2019/8/19 20:38 + * @Version 1.0 + **/ +public class DiscardServer { + + static final boolean SSL = System.getProperty("ssl") != null; + static final int PORT = Integer.parseInt(System.getProperty("port", "8007")); + + public static void main(String[] args) throws Exception { + final SslContext sslCtx; + if (SSL){ + //SelfSignedCertificate:生成临时自签名证书以进行测试 + SelfSignedCertificate ssc = new SelfSignedCertificate(); + sslCtx = SslContextBuilder.forServer(ssc.certificate(), ssc.privateKey()).build(); + }else{ + sslCtx = null; + } + + EventLoopGroup bossGroup = new NioEventLoopGroup(1); + EventLoopGroup workerGroup = new NioEventLoopGroup(); + + try { + ServerBootstrap b = new ServerBootstrap(); + b.group(bossGroup,workerGroup) + .channel(NioServerSocketChannel.class) + .option(ChannelOption.SO_BACKLOG,100) + .handler(new LoggingHandler(LogLevel.INFO)) + .childHandler(new ChannelInitializer() { + @Override + protected void initChannel(SocketChannel ch) throws Exception { + ChannelPipeline p = ch.pipeline(); + if (sslCtx != null){ + p.addLast(sslCtx.newHandler(ch.alloc())); + } + p.addLast(new DiscardServerHandler()); + } + }); + + // 绑定并开始接受传入连接 + ChannelFuture f = b.bind(PORT).sync(); + + // 等待服务器套接字关闭 + // 这个例子,这不会发生,但你可以这样优雅的做 + f.channel().closeFuture().sync(); + + }finally { + bossGroup.shutdownGracefully(); + workerGroup.shutdownGracefully(); + } + + } + +} +``` + +- DiscardServerHandler + +```java +/** + * @ClassName DiscardServerHandler + * @Description TODO + * @Author MySelf + * @Date 2019/8/19 20:39 + * @Version 1.0 + **/ +public class DiscardServerHandler extends SimpleChannelInboundHandler { + + @Override + protected void channelRead0(ChannelHandlerContext channelHandlerContext, Object o) throws Exception { + // discard + } + + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { + // 引发异常时关闭连接 + cause.printStackTrace(); + ctx.close(); + } +} +``` \ No newline at end of file diff --git a/src/main/java/com/github/unclecatmyself/demo2/DiscardClientHandler.java b/src/main/java/com/github/unclecatmyself/demo2/DiscardClientHandler.java index 24f67a0..06ff16d 100644 --- a/src/main/java/com/github/unclecatmyself/demo2/DiscardClientHandler.java +++ b/src/main/java/com/github/unclecatmyself/demo2/DiscardClientHandler.java @@ -31,6 +31,7 @@ public void channelActive(ChannelHandlerContext ctx) throws Exception { @Override public void channelInactive(ChannelHandlerContext ctx) throws Exception { + //引用计数为0,释放 content.release(); } @@ -46,8 +47,6 @@ protected void channelRead0(ChannelHandlerContext channelHandlerContext, Object // 服务器应该不发送任何内容,但如果它发送什么,丢弃它。 } - long counter; - // 生成数据 private void generateTraffic(){ // 将出站缓冲区刷新到套接字 @@ -57,6 +56,7 @@ private void generateTraffic(){ // 数据触发 private final ChannelFutureListener trafficGenerator = new ChannelFutureListener() { + //完成操作后的方法调用,即只要成功无限调用generateTraffic() @Override public void operationComplete(ChannelFuture channelFuture) throws Exception { if (channelFuture.isSuccess()){ From c5f5cf43b9ffbc5a088b284be3216ac5c697490c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=B1=E5=9F=B9=E6=9D=B0?= <1341933031@qq.com> Date: Tue, 20 Aug 2019 14:10:20 +0800 Subject: [PATCH 6/7] update --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6baeebb..54790e5 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ ## 官方教程 - [1、Echo简单通讯](doc/echo.md) [地址](https://github.com/AwakenCN/InChat/tree/official-demo/src/main/java/com/github/unclecatmyself/demo1) - +- [2、异步无限发送](doc/discard.md) [地址](https://github.com/AwakenCN/InChat/tree/official-demo/src/main/java/com/github/unclecatmyself/demo2) ## 公众号:Java猫说 From a599d09dd7a9f1f09ff406e746969a20579683a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=B1=E5=9F=B9=E6=9D=B0?= <1341933031@qq.com> Date: Tue, 27 Aug 2019 10:51:52 +0800 Subject: [PATCH 7/7] =?UTF-8?q?=E8=87=AA=E5=8A=A8=E9=87=8D=E8=BF=9E?= =?UTF-8?q?=E6=9C=BA=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + doc/time.md | 242 ++++++++++++++++++ .../unclecatmyself/demo3/UptimeClient.java | 55 ++++ .../demo3/UptimeClientHandler.java | 77 ++++++ .../unclecatmyself/demo3/UptimeServer.java | 51 ++++ .../demo3/UptimeServerHandler.java | 24 ++ 6 files changed, 450 insertions(+) create mode 100644 doc/time.md create mode 100644 src/main/java/com/github/unclecatmyself/demo3/UptimeClient.java create mode 100644 src/main/java/com/github/unclecatmyself/demo3/UptimeClientHandler.java create mode 100644 src/main/java/com/github/unclecatmyself/demo3/UptimeServer.java create mode 100644 src/main/java/com/github/unclecatmyself/demo3/UptimeServerHandler.java diff --git a/README.md b/README.md index 54790e5..cc185d4 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,7 @@ - [1、Echo简单通讯](doc/echo.md) [地址](https://github.com/AwakenCN/InChat/tree/official-demo/src/main/java/com/github/unclecatmyself/demo1) - [2、异步无限发送](doc/discard.md) [地址](https://github.com/AwakenCN/InChat/tree/official-demo/src/main/java/com/github/unclecatmyself/demo2) +- [3、自动重连机制](doc/time.md) [地址](https://github.com/AwakenCN/InChat/tree/official-demo/src/main/java/com/github/unclecatmyself/demo3) ## 公众号:Java猫说 diff --git a/doc/time.md b/doc/time.md new file mode 100644 index 0000000..10296bf --- /dev/null +++ b/doc/time.md @@ -0,0 +1,242 @@ +## Netty自动重连机制 + +> 版本:netty 4.1.* +> +> 申明:本文旨在重新分享讨论Netty官方相关案例,添加部分个人理解与要点解析。 + +这个是InChat的案例[地址](https://github.com/AwakenCN/InChat/tree/official-demo/src/main/java/com/github/unclecatmyself/demo1),里面补充了详细的注释,比起官方会容易看一点。 + +官方案例地址:https://netty.io/4.1/xref/io/netty/example/uptime/package-summary.html + +### 正文 + +- UptimeClient(客户端) +- UptimeClientHandler +- UptimeServer(服务端) +- UptimeServerHandler + +### 要点介绍 + +- IdleStateHandler https://netty.io/4.1/api/io/netty/handler/timeout/IdleStateHandler.html + +一个对Channel尚未执行读、写或两次操作的触发器 + +属性|含义 +---|--- +readerIdleTime | 在IdleStateEvent其状态IdleState.READER_IDLE 时的指定时间段没有执行读操作将被触发。指定0禁用。 +writerIdleTime | 在IdleStateEvent其状态IdleState.WRITER_IDLE 时的指定时间段没有执行写操作将被触发。指定0禁用。 +allIdleTime | 一个IdleStateEvent其状态IdleState.ALL_IDLE 时的时间在规定的时间进行读取和写入都将被触发。指定0禁用。 + +如下一个在没有信息时发送ping消息,且30秒没有入站信息则关闭连接 + +```java +public class MyChannelInitializer extends ChannelInitializer { + @Override + public void initChannel(Channel channel) { + channel.pipeline().addLast("idleStateHandler", new IdleStateHandler(60, 30, 0)); + channel.pipeline().addLast("myHandler", new MyHandler()); + } + } + + // Handler should handle the IdleStateEvent triggered by IdleStateHandler. + public class MyHandler extends ChannelDuplexHandler { + @Override + public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { + if (evt instanceof IdleStateEvent) { + IdleStateEvent e = (IdleStateEvent) evt; + if (e.state() == IdleState.READER_IDLE) { + ctx.close(); + } else if (e.state() == IdleState.WRITER_IDLE) { + ctx.writeAndFlush(new PingMessage()); + } + } + } + } +``` + +### 项目源码 + +- UptimeClient + +```java +/** + * Created by MySelf on 2019/8/27. + */ +public final class UptimeClient { + + static final String HOST = System.getProperty("host", "127.0.0.1"); + static final int PORT = Integer.parseInt(System.getProperty("port", "8080")); + // 重新连接前睡眠5秒 + static final int RECONNECT_DELAY = Integer.parseInt(System.getProperty("reconnectDelay", "5")); + // 当服务器在 10 秒内不发送任何内容时重新连接。 + private static final int READ_TIMEOUT = Integer.parseInt(System.getProperty("readTimeout", "10")); + + private static final UptimeClientHandler handler = new UptimeClientHandler(); + private static final Bootstrap bs = new Bootstrap(); + + public static void main(String[] args) throws Exception { + EventLoopGroup group = new NioEventLoopGroup(); + bs.group(group) + .channel(NioSocketChannel.class) + .remoteAddress(HOST,PORT) + .handler(new ChannelInitializer() { + @Override + protected void initChannel(SocketChannel ch) throws Exception { + ch.pipeline().addLast(new IdleStateHandler(READ_TIMEOUT,0,0),handler); + } + }); + bs.connect(); + } + + static void connect(){ + bs.connect().addListener(new ChannelFutureListener() { + @Override + public void operationComplete(ChannelFuture future) throws Exception { + if (future.cause() != null){ + handler.startTime = -1; + handler.println("Failed to connect:" + future.cause()); + } + } + }); + } + +} +``` + +- UptimeClientHandler + +```java +/** + * Created by MySelf on 2019/8/27. + */ +@ChannelHandler.Sharable +public class UptimeClientHandler extends SimpleChannelInboundHandler { + + long startTime = -1; + + @Override + protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception { + //Discard received data + } + + @Override + public void channelActive(ChannelHandlerContext ctx) throws Exception { + if (startTime < 0){ + startTime = System.currentTimeMillis(); + } + println("Connected to:" + ctx.channel().remoteAddress()); + } + + @Override + public void channelInactive(ChannelHandlerContext ctx) throws Exception { + println("Disconnected from: " + ctx.channel().remoteAddress()); + } + + @Override + public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { + if (!(evt instanceof IdleStateEvent)){ + return; + } + IdleStateEvent e = (IdleStateEvent)evt; + if (e.state() == IdleState.READER_IDLE){ + // 连接正常,但是没有读信息,关闭连接 + println("Disconnecting due to no inbound traffic"); + ctx.close(); + } + } + + @Override + public void channelUnregistered(ChannelHandlerContext ctx) throws Exception { + // 睡眠5秒 + println("Sleeping for:" + UptimeClient.RECONNECT_DELAY + 's'); + // 启动线程重新连接 + ctx.channel().eventLoop().schedule(new Runnable() { + @Override + public void run() { + println("Reconnecting to:" + UptimeClient.HOST + ":" + UptimeClient.PORT); + UptimeClient.connect(); + } + },UptimeClient.RECONNECT_DELAY, TimeUnit.SECONDS); + } + + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { + cause.printStackTrace(); + ctx.close(); + } + + void println(String msg){ + if (startTime < 0){ + System.err.format("[SERVER IS DOWN] %s%n",msg); + } else { + System.err.format("[UPTIME: %5ds] %s%n",(System.currentTimeMillis() - startTime)/1000,msg); + } + } +} +``` + +- UptimeServer + +```java +/** + * Created by MySelf on 2019/8/27. + */ +public final class UptimeServer { + + private static final int PORT = Integer.parseInt(System.getProperty("port", "8080")); + private static final UptimeServerHandler handler = new UptimeServerHandler(); + + private UptimeServer(){} + + public static void main(String[] args) throws Exception { + EventLoopGroup bossGroup = new NioEventLoopGroup(); + EventLoopGroup workerGroup = new NioEventLoopGroup(); + + try { + ServerBootstrap b = new ServerBootstrap(); + b.group(bossGroup,workerGroup) + .channel(NioServerSocketChannel.class) + .handler(new LoggingHandler(LogLevel.INFO)) + .childHandler(new ChannelInitializer() { + @Override + protected void initChannel(SocketChannel ch) throws Exception { + ch.pipeline().addLast(handler); + } + }); + // Bind and start to accept incoming connections. + ChannelFuture f = b.bind(PORT).sync(); + + // Wait until the server socket is closed. + // In this example, this does not happen, but you can do that to gracefully + // shut down your server. + f.channel().closeFuture().sync(); + }finally { + workerGroup.shutdownGracefully(); + bossGroup.shutdownGracefully(); + } + } +} +``` + +- UptimeServerHandler + +```java +/** + * Created by MySelf on 2019/8/27. + */ +@ChannelHandler.Sharable +public class UptimeServerHandler extends SimpleChannelInboundHandler { + + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { + // Close the connection when an exception is raised. + cause.printStackTrace(); + ctx.close(); + } + + @Override + protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception { + // discard + } +} +``` \ No newline at end of file diff --git a/src/main/java/com/github/unclecatmyself/demo3/UptimeClient.java b/src/main/java/com/github/unclecatmyself/demo3/UptimeClient.java new file mode 100644 index 0000000..06cd843 --- /dev/null +++ b/src/main/java/com/github/unclecatmyself/demo3/UptimeClient.java @@ -0,0 +1,55 @@ +package com.github.unclecatmyself.demo3; + + +import io.netty.bootstrap.Bootstrap; +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelFutureListener; +import io.netty.channel.ChannelInitializer; +import io.netty.channel.EventLoopGroup; +import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.channel.socket.SocketChannel; +import io.netty.channel.socket.nio.NioSocketChannel; +import io.netty.handler.timeout.IdleStateHandler; + +/** + * Created by MySelf on 2019/8/27. + */ +public final class UptimeClient { + + static final String HOST = System.getProperty("host", "127.0.0.1"); + static final int PORT = Integer.parseInt(System.getProperty("port", "8080")); + // 重新连接前睡眠5秒 + static final int RECONNECT_DELAY = Integer.parseInt(System.getProperty("reconnectDelay", "5")); + // 当服务器在 10 秒内不发送任何内容时重新连接。 + private static final int READ_TIMEOUT = Integer.parseInt(System.getProperty("readTimeout", "10")); + + private static final UptimeClientHandler handler = new UptimeClientHandler(); + private static final Bootstrap bs = new Bootstrap(); + + public static void main(String[] args) throws Exception { + EventLoopGroup group = new NioEventLoopGroup(); + bs.group(group) + .channel(NioSocketChannel.class) + .remoteAddress(HOST,PORT) + .handler(new ChannelInitializer() { + @Override + protected void initChannel(SocketChannel ch) throws Exception { + ch.pipeline().addLast(new IdleStateHandler(READ_TIMEOUT,0,0),handler); + } + }); + bs.connect(); + } + + static void connect(){ + bs.connect().addListener(new ChannelFutureListener() { + @Override + public void operationComplete(ChannelFuture future) throws Exception { + if (future.cause() != null){ + handler.startTime = -1; + handler.println("Failed to connect:" + future.cause()); + } + } + }); + } + +} diff --git a/src/main/java/com/github/unclecatmyself/demo3/UptimeClientHandler.java b/src/main/java/com/github/unclecatmyself/demo3/UptimeClientHandler.java new file mode 100644 index 0000000..388e7e4 --- /dev/null +++ b/src/main/java/com/github/unclecatmyself/demo3/UptimeClientHandler.java @@ -0,0 +1,77 @@ +package com.github.unclecatmyself.demo3; + +import io.netty.channel.ChannelHandler; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.SimpleChannelInboundHandler; +import io.netty.handler.timeout.IdleState; +import io.netty.handler.timeout.IdleStateEvent; + +import java.util.concurrent.TimeUnit; + +/** + * Created by MySelf on 2019/8/27. + */ +@ChannelHandler.Sharable +public class UptimeClientHandler extends SimpleChannelInboundHandler { + + long startTime = -1; + + @Override + protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception { + //Discard received data + } + + @Override + public void channelActive(ChannelHandlerContext ctx) throws Exception { + if (startTime < 0){ + startTime = System.currentTimeMillis(); + } + println("Connected to:" + ctx.channel().remoteAddress()); + } + + @Override + public void channelInactive(ChannelHandlerContext ctx) throws Exception { + println("Disconnected from: " + ctx.channel().remoteAddress()); + } + + @Override + public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { + if (!(evt instanceof IdleStateEvent)){ + return; + } + IdleStateEvent e = (IdleStateEvent)evt; + if (e.state() == IdleState.READER_IDLE){ + // 连接正常,但是没有读信息,关闭连接 + println("Disconnecting due to no inbound traffic"); + ctx.close(); + } + } + + @Override + public void channelUnregistered(ChannelHandlerContext ctx) throws Exception { + // 睡眠5秒 + println("Sleeping for:" + UptimeClient.RECONNECT_DELAY + 's'); + // 启动线程重新连接 + ctx.channel().eventLoop().schedule(new Runnable() { + @Override + public void run() { + println("Reconnecting to:" + UptimeClient.HOST + ":" + UptimeClient.PORT); + UptimeClient.connect(); + } + },UptimeClient.RECONNECT_DELAY, TimeUnit.SECONDS); + } + + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { + cause.printStackTrace(); + ctx.close(); + } + + void println(String msg){ + if (startTime < 0){ + System.err.format("[SERVER IS DOWN] %s%n",msg); + } else { + System.err.format("[UPTIME: %5ds] %s%n",(System.currentTimeMillis() - startTime)/1000,msg); + } + } +} diff --git a/src/main/java/com/github/unclecatmyself/demo3/UptimeServer.java b/src/main/java/com/github/unclecatmyself/demo3/UptimeServer.java new file mode 100644 index 0000000..cb08ac3 --- /dev/null +++ b/src/main/java/com/github/unclecatmyself/demo3/UptimeServer.java @@ -0,0 +1,51 @@ +package com.github.unclecatmyself.demo3; + +import io.netty.bootstrap.ServerBootstrap; +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelInitializer; +import io.netty.channel.EventLoopGroup; +import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.channel.socket.SocketChannel; +import io.netty.channel.socket.nio.NioServerSocketChannel; +import io.netty.channel.socket.nio.NioSocketChannel; +import io.netty.handler.logging.LogLevel; +import io.netty.handler.logging.LoggingHandler; + +/** + * Created by MySelf on 2019/8/27. + */ +public final class UptimeServer { + + private static final int PORT = Integer.parseInt(System.getProperty("port", "8080")); + private static final UptimeServerHandler handler = new UptimeServerHandler(); + + private UptimeServer(){} + + public static void main(String[] args) throws Exception { + EventLoopGroup bossGroup = new NioEventLoopGroup(); + EventLoopGroup workerGroup = new NioEventLoopGroup(); + + try { + ServerBootstrap b = new ServerBootstrap(); + b.group(bossGroup,workerGroup) + .channel(NioServerSocketChannel.class) + .handler(new LoggingHandler(LogLevel.INFO)) + .childHandler(new ChannelInitializer() { + @Override + protected void initChannel(SocketChannel ch) throws Exception { + ch.pipeline().addLast(handler); + } + }); + // Bind and start to accept incoming connections. + ChannelFuture f = b.bind(PORT).sync(); + + // Wait until the server socket is closed. + // In this example, this does not happen, but you can do that to gracefully + // shut down your server. + f.channel().closeFuture().sync(); + }finally { + workerGroup.shutdownGracefully(); + bossGroup.shutdownGracefully(); + } + } +} diff --git a/src/main/java/com/github/unclecatmyself/demo3/UptimeServerHandler.java b/src/main/java/com/github/unclecatmyself/demo3/UptimeServerHandler.java new file mode 100644 index 0000000..92a59b2 --- /dev/null +++ b/src/main/java/com/github/unclecatmyself/demo3/UptimeServerHandler.java @@ -0,0 +1,24 @@ +package com.github.unclecatmyself.demo3; + +import io.netty.channel.ChannelHandler; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.SimpleChannelInboundHandler; + +/** + * Created by MySelf on 2019/8/27. + */ +@ChannelHandler.Sharable +public class UptimeServerHandler extends SimpleChannelInboundHandler { + + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { + // Close the connection when an exception is raised. + cause.printStackTrace(); + ctx.close(); + } + + @Override + protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception { + // discard + } +}