├── readme-update.md ├── doc ├── qos0_seq.png ├── qos1_seq.png └── qos2_seq.png ├── ext.opensource.netty-client-example ├── src │ └── main │ │ ├── resources │ │ ├── META-INF │ │ │ └── spring-devtools.properties │ │ ├── cert │ │ │ ├── ssl_client.cer │ │ │ └── ssl_client.jks │ │ ├── application.properties │ │ └── banner.txt │ │ └── java │ │ └── ext │ │ └── opensource │ │ └── netty │ │ └── client │ │ └── example │ │ ├── mqtt │ │ ├── CustomMqttClient.java │ │ ├── MqttClientCustomInit.java │ │ ├── CustomMqttClientIgnite.java │ │ └── CustomMqttClientRedis.java │ │ ├── ignite │ │ ├── IgniteConditionConfig.java │ │ ├── IgniteConditionalCache.java │ │ ├── CacheListIgnite.java │ │ └── IgniteProperties.java │ │ ├── redis │ │ ├── RedisConditionalCache.java │ │ ├── RedisConditionConfig.java │ │ └── CacheListRedis.java │ │ ├── listen │ │ ├── ContextClosedListener.java │ │ └── SpringBeanUtil.java │ │ ├── WebSocketClientApplication.java │ │ ├── SimpleClientApplication.java │ │ └── MqttClientApplication.java └── pom.xml ├── ext.opensource.netty-server-example └── src │ └── main │ ├── resources │ ├── META-INF │ │ └── spring-devtools.properties │ ├── cert │ │ ├── ssl_server.cer │ │ ├── ssl_server.jks │ │ └── ssl_server_both.jks │ ├── static │ │ └── websocket │ │ │ └── favicon.ico │ ├── banner.txt │ └── application.properties │ └── java │ └── ext │ └── opensource │ └── netty │ └── server │ └── example │ ├── mqtt │ ├── MqttServerRecvice.java │ ├── MqttCustomCache.java │ ├── MqttCustomInit.java │ ├── BaseMqttCustom.java │ ├── redis │ │ ├── config │ │ │ ├── RedisConditionalCache.java │ │ │ ├── RedisConditionalCommunicate.java │ │ │ ├── RedisConditionConfig.java │ │ │ ├── RedisSubribleLister.java │ │ │ └── RedisSubListenerConfig.java │ │ ├── CustomRedisCommunicate.java │ │ └── CacheListRedis.java │ ├── ignite │ │ ├── config │ │ │ ├── IgniteConditionalCache.java │ │ │ └── IgniteConditionalCommunicate.java │ │ └── InternalCommunicationIgnite.java │ ├── kafka │ │ ├── config │ │ │ ├── KafkaConditionalCommunicate.java │ │ │ ├── KafkaConditionConfig.java │ │ │ └── KafkaProducerConfig.java │ │ ├── CustomKafkaCommunicate.java │ │ └── KafkaSubribleLister.java │ ├── MqttCustom.java │ └── MqttCustomCommunicate.java │ ├── simple │ ├── SocketCmd.java │ ├── SocketCmdService.java │ └── BizDispatchCollect.java │ ├── listen │ ├── ContextStopListener.java │ ├── ContextStartedListener.java │ ├── ContextClosedListener.java │ ├── SpringBeanUtil.java │ └── ContextRefreshedListener.java │ ├── scanner │ ├── InvokerHoler.java │ ├── Invoker.java │ └── HandlerScaner.java │ ├── websocket │ └── WebSocketEventChat.java │ ├── http │ ├── HttpResourceThymeleaf.java │ └── ThymeleafTest.java │ └── WebSocketApplication.java ├── standard ├── ext.opensource.importorder └── ext-opensoure codetemplates.xml ├── ext.opensource.netty-server ├── src │ └── main │ │ ├── java │ │ └── ext │ │ │ └── opensource │ │ │ └── netty │ │ │ └── server │ │ │ ├── httpsocket │ │ │ ├── BaseWebSocketEvent.java │ │ │ ├── HttpResourceProcess.java │ │ │ ├── HttpResourceFile.java │ │ │ ├── WebSocketServer.java │ │ │ ├── WebSocketEvent.java │ │ │ ├── HttpServer.java │ │ │ ├── MapUrlParamsUtil.java │ │ │ ├── WebSocketUtil.java │ │ │ ├── BaseHttpResource.java │ │ │ ├── WebSocketSession.java │ │ │ └── HttpResourceHander.java │ │ │ ├── mqtt │ │ │ ├── protocol │ │ │ │ ├── data │ │ │ │ │ ├── ClientTopic.java │ │ │ │ │ ├── ConsumerClientData.java │ │ │ │ │ ├── ProcedureClientData.java │ │ │ │ │ ├── TopicData.java │ │ │ │ │ └── BaseDataInMap.java │ │ │ │ ├── ProtocolUtil.java │ │ │ │ └── process │ │ │ │ │ └── ProcedureProcess.java │ │ │ ├── api │ │ │ │ ├── InternalSend.java │ │ │ │ ├── MqttAuth.java │ │ │ │ ├── PubishMessageLister.java │ │ │ │ ├── InternalRecvice.java │ │ │ │ ├── impl │ │ │ │ │ ├── AuthServiceImpl.java │ │ │ │ │ ├── ConsumerDataServiceImpl.java │ │ │ │ │ ├── SessionServiceImpl.java │ │ │ │ │ └── ProcedureDataServiceImpl.java │ │ │ │ ├── ConsumerDataService.java │ │ │ │ ├── ProcedureDataService.java │ │ │ │ ├── MqttSessionService.java │ │ │ │ ├── TopicService.java │ │ │ │ └── CustomConfig.java │ │ │ ├── common │ │ │ │ ├── SubscribeTopicInfo.java │ │ │ │ ├── InternalMessage.java │ │ │ │ ├── ConsumerMessage.java │ │ │ │ ├── ProcedureMessage.java │ │ │ │ ├── RetainMessage.java │ │ │ │ └── BorkerMessage.java │ │ │ ├── MqttWebSocketCodec.java │ │ │ ├── MqttWebSocketServer.java │ │ │ ├── MqttSession.java │ │ │ └── MqttServer.java │ │ │ ├── simple │ │ │ ├── SocketCmdEvent.java │ │ │ ├── SimpleServer.java │ │ │ └── SimpleServerHandler.java │ │ │ ├── TestServerApplication.java │ │ │ └── SimpleServerApplication.java │ │ └── resources │ │ ├── application.properties │ │ └── banner.txt └── pom.xml ├── ext.opensource.netty-client ├── src │ └── main │ │ └── java │ │ └── ext │ │ └── opensource │ │ └── netty │ │ └── client │ │ ├── mqtt │ │ ├── common │ │ │ ├── ClientEvent.java │ │ │ ├── SubscribeMessage.java │ │ │ ├── MessageStatus.java │ │ │ ├── DefautMqttConsumerListener.java │ │ │ ├── MessageData.java │ │ │ └── MqttConnectOptions.java │ │ ├── api │ │ │ ├── MqttConsumerListener.java │ │ │ ├── MqttProducer.java │ │ │ ├── MqttConsumer.java │ │ │ ├── MqttProducerProcess.java │ │ │ ├── MqttConsumerProcess.java │ │ │ └── ClientProcess.java │ │ └── MqttClientHandler.java │ │ ├── core │ │ ├── ClientProcess.java │ │ ├── ConnectCheckClient.java │ │ └── LoginCheckThread.java │ │ ├── httpsocket │ │ └── WebSocketClient.java │ │ └── simple │ │ └── SimpleClient.java └── pom.xml ├── ext.opensource.netty-common ├── src │ └── main │ │ └── java │ │ └── ext │ │ └── opensource │ │ └── netty │ │ └── common │ │ ├── SocketModel.java │ │ ├── api │ │ ├── SocketApplication.java │ │ ├── GlobalUniqueId.java │ │ ├── GlobalUniqueIdSet.java │ │ └── GlobalUniqueIdImpl.java │ │ ├── exception │ │ ├── LoginException.java │ │ ├── SocketRuntimeException.java │ │ └── MethodNotSupportException.java │ │ ├── utils │ │ ├── ByteBufUtil.java │ │ ├── MessageId.java │ │ ├── IpUtil.java │ │ └── StringsUtil.java │ │ ├── core │ │ ├── BaseCacheList.java │ │ ├── UniqueIdInteger.java │ │ ├── CacheListLocalMemory.java │ │ └── CacheList.java │ │ ├── TranDataProto.java │ │ ├── NettyConstant.java │ │ ├── NettyUtil.java │ │ ├── HeartbeatServerHandler.java │ │ ├── LogDispatchHandler.java │ │ ├── ChannelManagerHandler.java │ │ ├── HeartbeatClientHandler.java │ │ ├── TranDataProtoUtil.java │ │ ├── ChannelManager.java │ │ └── NettyLog.java └── pom.xml ├── .gitignore ├── ext.opensource.redis ├── pom.xml └── src │ └── main │ └── java │ └── org │ └── infrastructure │ └── redis │ ├── core │ ├── GsonRedisSerializer.java │ ├── JosnRedisUtil.java │ └── FastJsonRedisSerializer.java │ ├── IRedisHashService.java │ └── config │ └── RedisProperties.java └── readme.md /readme-update.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /doc/qos0_seq.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xjc-opensource/ext-opensource-netty/HEAD/doc/qos0_seq.png -------------------------------------------------------------------------------- /doc/qos1_seq.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xjc-opensource/ext-opensource-netty/HEAD/doc/qos1_seq.png -------------------------------------------------------------------------------- /doc/qos2_seq.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xjc-opensource/ext-opensource-netty/HEAD/doc/qos2_seq.png -------------------------------------------------------------------------------- /ext.opensource.netty-client-example/src/main/resources/META-INF/spring-devtools.properties: -------------------------------------------------------------------------------- 1 | restart.include.ignite=/ignite-[\\w-\\.]+jar 2 | -------------------------------------------------------------------------------- /ext.opensource.netty-server-example/src/main/resources/META-INF/spring-devtools.properties: -------------------------------------------------------------------------------- 1 | restart.include.ignite=/ignite-[\\w-\\.]+jar 2 | -------------------------------------------------------------------------------- /standard/ext.opensource.importorder: -------------------------------------------------------------------------------- 1 | #Organize Import Order 2 | #Wed Aug 21 12:21:41 CST 2019 3 | 5=org.infrastructure 4 | 4=ext.opensource 5 | 3=com 6 | 2=org 7 | 1=javax 8 | 0=java 9 | -------------------------------------------------------------------------------- /ext.opensource.netty-client-example/src/main/resources/cert/ssl_client.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xjc-opensource/ext-opensource-netty/HEAD/ext.opensource.netty-client-example/src/main/resources/cert/ssl_client.cer -------------------------------------------------------------------------------- /ext.opensource.netty-client-example/src/main/resources/cert/ssl_client.jks: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xjc-opensource/ext-opensource-netty/HEAD/ext.opensource.netty-client-example/src/main/resources/cert/ssl_client.jks -------------------------------------------------------------------------------- /ext.opensource.netty-server-example/src/main/resources/cert/ssl_server.cer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xjc-opensource/ext-opensource-netty/HEAD/ext.opensource.netty-server-example/src/main/resources/cert/ssl_server.cer -------------------------------------------------------------------------------- /ext.opensource.netty-server-example/src/main/resources/cert/ssl_server.jks: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xjc-opensource/ext-opensource-netty/HEAD/ext.opensource.netty-server-example/src/main/resources/cert/ssl_server.jks -------------------------------------------------------------------------------- /ext.opensource.netty-server-example/src/main/resources/cert/ssl_server_both.jks: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xjc-opensource/ext-opensource-netty/HEAD/ext.opensource.netty-server-example/src/main/resources/cert/ssl_server_both.jks -------------------------------------------------------------------------------- /ext.opensource.netty-server-example/src/main/resources/static/websocket/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xjc-opensource/ext-opensource-netty/HEAD/ext.opensource.netty-server-example/src/main/resources/static/websocket/favicon.ico -------------------------------------------------------------------------------- /ext.opensource.netty-server/src/main/java/ext/opensource/netty/server/httpsocket/BaseWebSocketEvent.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.server.httpsocket; 2 | 3 | /** 4 | * @author ben 5 | * @Title: basic 6 | * @Description: 7 | **/ 8 | 9 | public abstract class BaseWebSocketEvent implements WebSocketEvent { 10 | } 11 | -------------------------------------------------------------------------------- /ext.opensource.netty-client/src/main/java/ext/opensource/netty/client/mqtt/common/ClientEvent.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.client.mqtt.common; 2 | 3 | /** 4 | * @author ben 5 | * @Title: basic 6 | * @Description: 7 | **/ 8 | public interface ClientEvent { 9 | /** 10 | * 事件处理 11 | */ 12 | public void process(); 13 | } 14 | -------------------------------------------------------------------------------- /ext.opensource.netty-server/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.profiles.active=dev 2 | spring.output.ansi.enabled=DETECT 3 | 4 | info.app.name=@project.name@ 5 | info.app.description=@project.description@ 6 | info.app.version=@project.version@ 7 | info.app.spring-boot-version=@project.parent.version@ 8 | info.app.build.ver=@build.ver@ -------------------------------------------------------------------------------- /ext.opensource.netty-common/src/main/java/ext/opensource/netty/common/SocketModel.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.common; 2 | 3 | /** 4 | * @author ben 5 | * @Title: basic 6 | * @Description: 7 | **/ 8 | 9 | public enum SocketModel { 10 | /** 11 | * 阻塞 12 | */ 13 | BLOCK, 14 | 15 | /** 16 | * 非阻塞 17 | */ 18 | UNBOLOCK 19 | } 20 | -------------------------------------------------------------------------------- /ext.opensource.netty-common/src/main/java/ext/opensource/netty/common/api/SocketApplication.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.common.api; 2 | 3 | /** 4 | * @author ben 5 | * @Title: basic 6 | * @Description: 7 | **/ 8 | public interface SocketApplication { 9 | 10 | /** 11 | * close socket server 12 | */ 13 | public void shutdown(); 14 | } 15 | -------------------------------------------------------------------------------- /ext.opensource.netty-common/src/main/java/ext/opensource/netty/common/exception/LoginException.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.common.exception; 2 | 3 | /** 4 | * @author ben 5 | * @Title: basic 6 | * @Description: 7 | **/ 8 | 9 | public class LoginException extends RuntimeException { 10 | private static final long serialVersionUID = 1L; 11 | 12 | public LoginException(String message) { 13 | super(message); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /ext.opensource.netty-server-example/src/main/java/ext/opensource/netty/server/example/mqtt/MqttServerRecvice.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.server.example.mqtt; 2 | 3 | 4 | /** 5 | * @author ben 6 | * @Title: basic 7 | * @Description: 8 | **/ 9 | 10 | public interface MqttServerRecvice { 11 | /** 12 | * 处理订阅到的信息 13 | * @param message 14 | * @return 15 | */ 16 | public boolean processServerRecviceMesage(String message); 17 | } 18 | -------------------------------------------------------------------------------- /ext.opensource.netty-server/src/main/java/ext/opensource/netty/server/mqtt/protocol/data/ClientTopic.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.server.mqtt.protocol.data; 2 | 3 | /** 4 | * @author ben 5 | * @Title: basic 6 | * @Description: 7 | **/ 8 | 9 | public class ClientTopic extends BaseDataInMap { 10 | private static final long serialVersionUID = 1L; 11 | 12 | public ClientTopic() { 13 | super(""); 14 | } 15 | 16 | 17 | } 18 | -------------------------------------------------------------------------------- /ext.opensource.netty-server/src/main/java/ext/opensource/netty/server/mqtt/api/InternalSend.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.server.mqtt.api; 2 | 3 | import ext.opensource.netty.server.mqtt.common.InternalMessage; 4 | 5 | /** 6 | * @author ben 7 | * @Title: basic 8 | * @Description: 9 | **/ 10 | 11 | public interface InternalSend { 12 | /** 13 | * 发送内部信息 14 | * @param msg 15 | */ 16 | public void internalSend(InternalMessage msg); 17 | } 18 | -------------------------------------------------------------------------------- /ext.opensource.netty-client-example/src/main/java/ext/opensource/netty/client/example/mqtt/CustomMqttClient.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.client.example.mqtt; 2 | 3 | import ext.opensource.netty.client.mqtt.MqttClient; 4 | 5 | /** 6 | * @author ben 7 | * @Title: basic 8 | * @Description: 9 | **/ 10 | 11 | public class CustomMqttClient implements MqttClientCustomInit { 12 | 13 | @Override 14 | public void init(MqttClient nettyClient) { 15 | 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /ext.opensource.netty-server/src/main/java/ext/opensource/netty/server/mqtt/api/MqttAuth.java: -------------------------------------------------------------------------------- 1 | 2 | package ext.opensource.netty.server.mqtt.api; 3 | 4 | /** 5 | * @author ben 6 | * @Title: basic 7 | * @Description: 8 | **/ 9 | 10 | public interface MqttAuth { 11 | /** 12 | * 验证接入终端信息 13 | * @param clientId 14 | * @param username 15 | * @param password 16 | * @return 17 | */ 18 | boolean checkValid(String clientId, String username, String password); 19 | } 20 | -------------------------------------------------------------------------------- /ext.opensource.netty-server-example/src/main/java/ext/opensource/netty/server/example/mqtt/MqttCustomCache.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.server.example.mqtt; 2 | 3 | import ext.opensource.netty.server.mqtt.MqttServer; 4 | 5 | 6 | /** 7 | * @author ben 8 | * @Title: basic 9 | * @Description: 10 | **/ 11 | public class MqttCustomCache extends BaseMqttCustom { 12 | @Override 13 | public void init(MqttServer mqttServer) { 14 | super.init(mqttServer); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /ext.opensource.netty-server-example/src/main/java/ext/opensource/netty/server/example/mqtt/MqttCustomInit.java: -------------------------------------------------------------------------------- 1 | 2 | package ext.opensource.netty.server.example.mqtt; 3 | 4 | import ext.opensource.netty.server.mqtt.MqttServer; 5 | 6 | /** 7 | * @author ben 8 | * @Title: CustomInit.java 9 | * @Description: 10 | **/ 11 | 12 | public interface MqttCustomInit { 13 | /** 14 | * init 15 | * @param mqttServer 16 | */ 17 | public void init(MqttServer mqttServer); 18 | } 19 | -------------------------------------------------------------------------------- /ext.opensource.netty-server/src/main/java/ext/opensource/netty/server/mqtt/api/PubishMessageLister.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.server.mqtt.api; 2 | 3 | import ext.opensource.netty.server.mqtt.common.BorkerMessage; 4 | 5 | /** 6 | * @author ben 7 | * @Title: basic 8 | * @Description: 9 | **/ 10 | 11 | 12 | public interface PubishMessageLister { 13 | /** 14 | * custom define process 15 | * @param msg 16 | */ 17 | void processMessage(BorkerMessage msg); 18 | } 19 | -------------------------------------------------------------------------------- /standard/ext-opensoure codetemplates.xml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ext.opensource.netty-server/src/main/java/ext/opensource/netty/server/mqtt/api/InternalRecvice.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.server.mqtt.api; 2 | 3 | import ext.opensource.netty.server.mqtt.common.InternalMessage; 4 | 5 | /** 6 | * @author ben 7 | * @Title: basic 8 | * @Description: 9 | **/ 10 | 11 | public interface InternalRecvice { 12 | /** 13 | * 接收内部信息处理 14 | * @param msg 15 | * @return 16 | */ 17 | public boolean processInternalRecvice(InternalMessage msg); 18 | } -------------------------------------------------------------------------------- /ext.opensource.netty-client-example/src/main/java/ext/opensource/netty/client/example/mqtt/MqttClientCustomInit.java: -------------------------------------------------------------------------------- 1 | 2 | package ext.opensource.netty.client.example.mqtt; 3 | 4 | import ext.opensource.netty.client.mqtt.MqttClient; 5 | 6 | /** 7 | * @author ben 8 | * @Title: CustomInit.java 9 | * @Description: 10 | **/ 11 | 12 | public interface MqttClientCustomInit { 13 | /** 14 | * init 15 | * @param nettyClient 16 | */ 17 | public void init(MqttClient nettyClient); 18 | } 19 | -------------------------------------------------------------------------------- /ext.opensource.netty-server/src/main/java/ext/opensource/netty/server/simple/SocketCmdEvent.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.server.simple; 2 | 3 | import ext.opensource.netty.common.TranDataProto; 4 | 5 | /** 6 | * @author ben 7 | * @Title: basic 8 | * @Description: 9 | **/ 10 | 11 | public interface SocketCmdEvent { 12 | /** 13 | * doCmd 14 | * @param code 15 | * @param message 16 | * @return 17 | */ 18 | public TranDataProto doCmd(String code, String message); 19 | } 20 | -------------------------------------------------------------------------------- /ext.opensource.netty-common/src/main/java/ext/opensource/netty/common/utils/ByteBufUtil.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.common.utils; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | 5 | /** 6 | * @author ben 7 | * @Title: basic 8 | * @Description: 9 | **/ 10 | 11 | public class ByteBufUtil { 12 | 13 | public static byte[] copyByteBuf(ByteBuf byteBuf){ 14 | byte[] bytes = new byte[byteBuf.readableBytes()]; 15 | byteBuf.readBytes(bytes); 16 | return bytes; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /ext.opensource.netty-server-example/src/main/java/ext/opensource/netty/server/example/mqtt/BaseMqttCustom.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.server.example.mqtt; 2 | 3 | import ext.opensource.netty.server.mqtt.MqttServer; 4 | 5 | 6 | /** 7 | * @author ben 8 | * @Title: basic 9 | * @Description: 10 | **/ 11 | 12 | public class BaseMqttCustom implements MqttCustomInit{ 13 | protected MqttServer mqttServer; 14 | 15 | @Override 16 | public void init(MqttServer mqttServer) { 17 | this.mqttServer = mqttServer; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /ext.opensource.netty-client/src/main/java/ext/opensource/netty/client/mqtt/common/SubscribeMessage.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.client.mqtt.common; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | /** 9 | * @author ben 10 | * @Title: basic 11 | * @Description: 12 | **/ 13 | 14 | @Builder 15 | @Data 16 | @NoArgsConstructor 17 | @AllArgsConstructor 18 | public class SubscribeMessage { 19 | private String topic; 20 | private int qos; 21 | } -------------------------------------------------------------------------------- /ext.opensource.netty-client/src/main/java/ext/opensource/netty/client/mqtt/common/MessageStatus.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.client.mqtt.common; 2 | 3 | /** 4 | * @author ben 5 | * @Title: basic 6 | * @Description: 7 | **/ 8 | 9 | public enum MessageStatus { 10 | /** 11 | * none 12 | */ 13 | None, 14 | /** 15 | * Qos1 16 | */ 17 | PUB, 18 | /** 19 | * Qos2 20 | */ 21 | PUBREC, 22 | /** 23 | * Qos2 24 | */ 25 | PUBREL, 26 | /** 27 | * finish 28 | */ 29 | COMPLETE, 30 | } 31 | -------------------------------------------------------------------------------- /ext.opensource.netty-client/src/main/java/ext/opensource/netty/client/core/ClientProcess.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.client.core; 2 | 3 | import ext.opensource.netty.common.exception.LoginException; 4 | 5 | /** 6 | * @author ben 7 | * @Title: basic 8 | * @Description: 9 | **/ 10 | 11 | public interface ClientProcess { 12 | /** 13 | * 登录完成 14 | * @param bResult 15 | * @param exception 16 | */ 17 | void loginFinish(boolean bResult, LoginException exception); 18 | 19 | /** 20 | * 发送指令关闭 21 | */ 22 | void disConnect(); 23 | } 24 | -------------------------------------------------------------------------------- /ext.opensource.netty-common/src/main/java/ext/opensource/netty/common/api/GlobalUniqueId.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.common.api; 2 | 3 | import ext.opensource.netty.common.core.CacheList; 4 | import ext.opensource.netty.common.core.UniqueIdInteger; 5 | 6 | /** 7 | * @author ben 8 | * @Title: basic 9 | * @Description: 10 | **/ 11 | 12 | public interface GlobalUniqueId { 13 | 14 | void setCacheList(CacheList cacheList); 15 | /** 16 | * get uniuqe id 17 | * @return 18 | */ 19 | int getNextMessageId(String clientId); 20 | } 21 | -------------------------------------------------------------------------------- /ext.opensource.netty-server/src/main/java/ext/opensource/netty/server/mqtt/protocol/ProtocolUtil.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.server.mqtt.protocol; 2 | 3 | import ext.opensource.netty.common.MqttProtocolUtil; 4 | import io.netty.handler.codec.mqtt.MqttPublishMessage; 5 | 6 | /** 7 | * @author ben 8 | * @Title: basic 9 | * @Description: 10 | **/ 11 | 12 | public class ProtocolUtil extends MqttProtocolUtil { 13 | public static MqttPublishMessage publishMessage(String topic, byte[] payload) { 14 | return publishMessage(topic, payload, 0, 10, false); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /ext.opensource.netty-server/src/main/java/ext/opensource/netty/server/mqtt/api/impl/AuthServiceImpl.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.server.mqtt.api.impl; 2 | 3 | import ext.opensource.netty.common.NettyLog; 4 | import ext.opensource.netty.server.mqtt.api.MqttAuth; 5 | 6 | /** 7 | * @author ben 8 | * @Title: basic 9 | * @Description: 10 | **/ 11 | 12 | public class AuthServiceImpl implements MqttAuth{ 13 | @Override 14 | public boolean checkValid(String deviceId, String username, String password) { 15 | NettyLog.debug("AuthServiceImpl"); 16 | return true; 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /ext.opensource.netty-server/src/main/java/ext/opensource/netty/server/httpsocket/HttpResourceProcess.java: -------------------------------------------------------------------------------- 1 | 2 | package ext.opensource.netty.server.httpsocket; 3 | 4 | import java.util.Map; 5 | 6 | import io.netty.handler.codec.http.HttpRequest; 7 | 8 | /** 9 | * @author ben 10 | * @Title: HttpResourceProcess.java 11 | * @Description: 12 | **/ 13 | 14 | public interface HttpResourceProcess { 15 | /** 16 | * porcessResPath 17 | * @param reqPath 18 | * @param reqParameter 19 | */ 20 | public void porcessResPath(HttpRequest req, String reqPath, Map reqParameter); 21 | } 22 | -------------------------------------------------------------------------------- /ext.opensource.netty-server/src/main/java/ext/opensource/netty/server/mqtt/protocol/data/ConsumerClientData.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.server.mqtt.protocol.data; 2 | 3 | import ext.opensource.netty.server.mqtt.common.ConsumerMessage; 4 | 5 | /** 6 | * @author ben 7 | * @Title: basic 8 | * @Description: 9 | **/ 10 | 11 | public class ConsumerClientData extends BaseDataInMap { 12 | private static final long serialVersionUID = 1L; 13 | 14 | public ConsumerClientData(String name) { 15 | super(name); 16 | } 17 | 18 | public ConsumerClientData() { 19 | 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /ext.opensource.netty-server/src/main/java/ext/opensource/netty/server/mqtt/protocol/data/ProcedureClientData.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.server.mqtt.protocol.data; 2 | 3 | import ext.opensource.netty.server.mqtt.common.ProcedureMessage; 4 | 5 | /** 6 | * @author ben 7 | * @Title: basic 8 | * @Description: 9 | **/ 10 | 11 | public class ProcedureClientData 12 | extends 13 | BaseDataInMap { 14 | private static final long serialVersionUID = 1L; 15 | 16 | public ProcedureClientData(String name) { 17 | super(name); 18 | } 19 | public ProcedureClientData() { 20 | 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /ext.opensource.netty-server-example/src/main/java/ext/opensource/netty/server/example/simple/SocketCmd.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.server.example.simple; 2 | 3 | import java.lang.annotation.Documented; 4 | import java.lang.annotation.ElementType; 5 | import java.lang.annotation.Retention; 6 | import java.lang.annotation.RetentionPolicy; 7 | import java.lang.annotation.Target; 8 | 9 | /** 10 | * @author ben 11 | * @Title: basic 12 | * @Description: 13 | **/ 14 | 15 | @Retention(RetentionPolicy.RUNTIME) 16 | @Target(ElementType.TYPE) 17 | @Documented 18 | public @interface SocketCmd { 19 | String value(); 20 | 21 | } 22 | -------------------------------------------------------------------------------- /ext.opensource.netty-client/src/main/java/ext/opensource/netty/client/mqtt/api/MqttConsumerListener.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.client.mqtt.api; 2 | 3 | /** 4 | * @author ben 5 | * @Title: basic 6 | * @Description: 7 | **/ 8 | 9 | public interface MqttConsumerListener { 10 | 11 | /** 12 | * 接收到的消息(确认过的) 13 | * @param msgId 14 | * @param topic 15 | * @param msg 16 | */ 17 | void receiveMessage(int msgId, String topic, String msg); 18 | 19 | 20 | /** 21 | * 接收到的消息(收到就转发) 22 | * @param msgId 23 | * @param topic 24 | * @param msg 25 | */ 26 | void receiveMessageByAny(int msgId, String topic, String msg); 27 | } 28 | -------------------------------------------------------------------------------- /ext.opensource.netty-common/src/main/java/ext/opensource/netty/common/core/BaseCacheList.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.common.core; 2 | 3 | /** 4 | * @author ben 5 | * @Title: basic 6 | * @Description: 7 | **/ 8 | 9 | public abstract class BaseCacheList implements CacheList { 10 | private String cacheName; 11 | public BaseCacheList() { 12 | } 13 | public BaseCacheList(String cacheName) { 14 | this.cacheName = cacheName; 15 | } 16 | 17 | @Override 18 | public String getCacheName() { 19 | return cacheName; 20 | } 21 | 22 | @Override 23 | public boolean containsKey(String key) { 24 | return exists(key); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /ext.opensource.netty-client/src/main/java/ext/opensource/netty/client/core/ConnectCheckClient.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.client.core; 2 | 3 | /** 4 | * @author ben 5 | * @Title: basic 6 | * @Description: 7 | **/ 8 | 9 | public class ConnectCheckClient implements Runnable { 10 | private long count; 11 | private BaseClient client = null; 12 | 13 | public ConnectCheckClient(BaseClient client) { 14 | this.client = client; 15 | } 16 | 17 | @Override 18 | public void run() { 19 | count ++; 20 | if (count >= Long.MAX_VALUE) { 21 | count= 0; 22 | } 23 | if (client != null) { 24 | client.reConnect(); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /ext.opensource.netty-common/src/main/java/ext/opensource/netty/common/core/UniqueIdInteger.java: -------------------------------------------------------------------------------- 1 | 2 | package ext.opensource.netty.common.core; 3 | 4 | import java.io.Serializable; 5 | import lombok.Data; 6 | 7 | /** 8 | * @author ben 9 | * @Title: UniqueIdInteger.java 10 | * @Description: 11 | **/ 12 | 13 | @Data 14 | public class UniqueIdInteger implements Serializable { 15 | private static final long serialVersionUID = 1L; 16 | 17 | private int value = 1; 18 | 19 | public int addInc() { 20 | value = value + 1; 21 | if (value > 65535) { 22 | value = 1; 23 | } 24 | return value; 25 | } 26 | 27 | public int id() { 28 | return value; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /ext.opensource.netty-common/src/main/java/ext/opensource/netty/common/api/GlobalUniqueIdSet.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.common.api; 2 | 3 | import ext.opensource.netty.common.core.CacheList; 4 | import ext.opensource.netty.common.core.UniqueIdInteger; 5 | 6 | /** 7 | * @author ben 8 | * @Title: basic 9 | * @Description: 10 | **/ 11 | public interface GlobalUniqueIdSet { 12 | /** 13 | * Custom set GlobalUniqueId object 14 | * @param globalUniquedId 15 | */ 16 | public void setGlobalUniqueId(GlobalUniqueId globalUniquedId); 17 | 18 | /** 19 | * 20 | * @param cacheList 21 | */ 22 | public void setGlobalUniqueIdCache(CacheList cacheList); 23 | } 24 | -------------------------------------------------------------------------------- /ext.opensource.netty-client/src/main/java/ext/opensource/netty/client/mqtt/common/DefautMqttConsumerListener.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.client.mqtt.common; 2 | 3 | import ext.opensource.netty.client.mqtt.api.MqttConsumerListener; 4 | 5 | /** 6 | * @author ben 7 | * @Title: basic 8 | * @Description: 9 | **/ 10 | public class DefautMqttConsumerListener implements MqttConsumerListener { 11 | 12 | @Override 13 | public void receiveMessage(int msgId, String topic, String msg) { 14 | // TODO Auto-generated method stub 15 | } 16 | 17 | @Override 18 | public void receiveMessageByAny(int msgId, String topic, String msg) { 19 | // TODO Auto-generated method stub 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /ext.opensource.netty-server-example/src/main/java/ext/opensource/netty/server/example/listen/ContextStopListener.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.server.example.listen; 2 | 3 | import org.springframework.context.ApplicationListener; 4 | import org.springframework.context.event.ContextStoppedEvent; 5 | import org.springframework.stereotype.Component; 6 | 7 | /** 8 | * @author ben 9 | * @Title: basic 10 | * @Description: 11 | **/ 12 | 13 | @Component 14 | public class ContextStopListener implements ApplicationListener{ 15 | @Override 16 | public void onApplicationEvent(ContextStoppedEvent event) { 17 | System.err.println("============Stop 执行=========== "); 18 | } 19 | } -------------------------------------------------------------------------------- /ext.opensource.netty-server-example/src/main/java/ext/opensource/netty/server/example/listen/ContextStartedListener.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.server.example.listen; 2 | 3 | import org.springframework.context.ApplicationListener; 4 | import org.springframework.context.event.ContextStartedEvent; 5 | import org.springframework.stereotype.Component; 6 | 7 | /** 8 | * @author ben 9 | * @Title: basic 10 | * @Description: 11 | **/ 12 | 13 | @Component 14 | public class ContextStartedListener implements ApplicationListener{ 15 | @Override 16 | public void onApplicationEvent(ContextStartedEvent event) { 17 | System.err.println("============Start 执行=========== "); 18 | } 19 | } -------------------------------------------------------------------------------- /ext.opensource.netty-client-example/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.profiles.active=dev 2 | spring.output.ansi.enabled=DETECT 3 | 4 | info.app.name=@project.name@ 5 | info.app.description=@project.description@ 6 | info.app.version=@project.version@ 7 | info.app.spring-boot-version=@project.parent.version@ 8 | info.app.build.ver=@build.ver@ 9 | 10 | #redis,ignite,local 11 | netty.client.cache=local 12 | 13 | #redis 14 | spring.redis.host=192.168.136.148 15 | spring.redis.port=6379 16 | spring.redis.database=0 17 | spring.redis.timeout=10000 18 | spring.redis.password= 19 | spring.redis.pool.maxActive=10 20 | spring.redis.pool.maxWait=100000 21 | spring.redis.pool.maxIdle=8 22 | spring.redis.pool.minIdle=0 23 | 24 | #ignite 25 | -------------------------------------------------------------------------------- /ext.opensource.netty-client-example/src/main/java/ext/opensource/netty/client/example/ignite/IgniteConditionConfig.java: -------------------------------------------------------------------------------- 1 | 2 | package ext.opensource.netty.client.example.ignite; 3 | 4 | import org.springframework.context.annotation.Bean; 5 | import org.springframework.context.annotation.Conditional; 6 | import org.springframework.context.annotation.Configuration; 7 | 8 | import ext.opensource.netty.client.example.mqtt.CustomMqttClientIgnite; 9 | 10 | /** 11 | * @author ben 12 | * @Title: xx.java 13 | * @Description: 14 | **/ 15 | @Configuration 16 | public class IgniteConditionConfig { 17 | @Bean 18 | @Conditional(IgniteConditionalCache.class) 19 | CustomMqttClientIgnite customMqttClientIgnite() { 20 | return new CustomMqttClientIgnite(); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /ext.opensource.netty-server/src/main/java/ext/opensource/netty/server/mqtt/protocol/data/TopicData.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.server.mqtt.protocol.data; 2 | 3 | import ext.opensource.netty.server.mqtt.common.RetainMessage; 4 | import ext.opensource.netty.server.mqtt.common.SubscribeTopicInfo; 5 | import lombok.Getter; 6 | import lombok.Setter; 7 | 8 | /** 9 | * @author ben 10 | * @Title: basic 11 | * @Description: 12 | **/ 13 | 14 | public class TopicData extends BaseDataInMap{ 15 | private static final long serialVersionUID = 1L; 16 | 17 | @Getter @Setter 18 | public RetainMessage retainMessageInfo; 19 | 20 | public TopicData() { 21 | 22 | } 23 | public TopicData(String name) { 24 | super(name); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.java.hsp 2 | *.sonarj 3 | *.sw* 4 | .DS_Store 5 | .settings 6 | .springBeans 7 | bin 8 | build.sh 9 | integration-repo 10 | ivy-cache 11 | jxl.log 12 | jmx.log 13 | derby.log 14 | spring-test/test-output/ 15 | .gradle 16 | argfile* 17 | activemq-data/ 18 | logs 19 | 20 | # jrebel 21 | rebel.xml 22 | 23 | classes/ 24 | /build 25 | buildSrc/build 26 | /spring-*/build 27 | /src/asciidoc/build 28 | target/ 29 | 30 | # Eclipse artifacts, including WTP generated manifests 31 | .classpath 32 | .project 33 | spring-*/src/main/java/META-INF/MANIFEST.MF 34 | 35 | # IDEA artifacts and output dirs 36 | *.iml 37 | *.ipr 38 | *.iws 39 | .idea 40 | out 41 | test-output 42 | atlassian-ide-plugin.xml 43 | .gradletasknamecache 44 | .rebel-remote.xml.bak 45 | .rebel.xml.bak 46 | -------------------------------------------------------------------------------- /ext.opensource.netty-common/src/main/java/ext/opensource/netty/common/exception/SocketRuntimeException.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.common.exception; 2 | 3 | /** 4 | * @author ben 5 | * @Title: basic 6 | * @Description: 7 | **/ 8 | 9 | public class SocketRuntimeException extends RuntimeException { 10 | private static final long serialVersionUID = 1L; 11 | 12 | public SocketRuntimeException() { 13 | super(); 14 | } 15 | 16 | public SocketRuntimeException(String message, Throwable cause) { 17 | super(message, cause); 18 | } 19 | 20 | public SocketRuntimeException(String message) { 21 | super(message); 22 | } 23 | 24 | public SocketRuntimeException(Throwable cause) { 25 | super(cause); 26 | } 27 | 28 | } -------------------------------------------------------------------------------- /ext.opensource.netty-server/src/main/java/ext/opensource/netty/server/mqtt/common/SubscribeTopicInfo.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.server.mqtt.common; 2 | 3 | import java.io.Serializable; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Builder; 6 | import lombok.Data; 7 | import lombok.Getter; 8 | import lombok.NoArgsConstructor; 9 | import lombok.Setter; 10 | 11 | /** 12 | * @author ben 13 | * @Title: basic 14 | * @Description: 15 | **/ 16 | 17 | @Getter 18 | @Setter 19 | @Builder 20 | @NoArgsConstructor 21 | @AllArgsConstructor 22 | @Data 23 | 24 | public class SubscribeTopicInfo implements Serializable { 25 | private static final long serialVersionUID = 1L; 26 | private String clientId; 27 | private String topicFilter; 28 | private int mqttQoS; 29 | } 30 | -------------------------------------------------------------------------------- /ext.opensource.netty-common/src/main/java/ext/opensource/netty/common/TranDataProto.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.common; 2 | 3 | import java.io.Serializable; 4 | 5 | import lombok.AllArgsConstructor; 6 | import lombok.Builder; 7 | import lombok.Data; 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | /** 12 | * @author ben 13 | * @Title: basic 14 | * @Description: 15 | **/ 16 | 17 | 18 | @Getter 19 | @Setter 20 | @Data 21 | @AllArgsConstructor 22 | @Builder 23 | public class TranDataProto implements Serializable { 24 | 25 | private static final long serialVersionUID = 1L; 26 | private int flag; 27 | private Integer sequence; 28 | private Integer code; 29 | private String content; 30 | 31 | public TranDataProto() { 32 | } 33 | 34 | } -------------------------------------------------------------------------------- /ext.opensource.netty-common/src/main/java/ext/opensource/netty/common/utils/MessageId.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.common.utils; 2 | 3 | 4 | import java.util.concurrent.atomic.AtomicInteger; 5 | 6 | /** 7 | * @author ben 8 | * @Title: basic 9 | * @Description: 10 | **/ 11 | 12 | public class MessageId { 13 | 14 | private static AtomicInteger index = new AtomicInteger(10); 15 | /** 16 | * 获取messageId 17 | * @return id 18 | */ 19 | public static int messageId(){ 20 | for (;;) { 21 | int current = index.get(); 22 | int next = (current >= Integer.MAX_VALUE ? 0: current + 1); 23 | if (index.compareAndSet(current, next)) { 24 | return current; 25 | } 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /ext.opensource.netty-common/src/main/java/ext/opensource/netty/common/NettyConstant.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.common; 2 | 3 | import io.netty.util.AttributeKey; 4 | 5 | /** 6 | * @author ben 7 | * @Title: basic 8 | * @Description: 9 | **/ 10 | 11 | public class NettyConstant { 12 | public final static String SYS_LINE_FEED = System.getProperty("line.separator", "\n"); 13 | public static final AttributeKey NETTY_CHANNEL_KEY = AttributeKey.valueOf("netty.cha"); 14 | public static final AttributeKey WEBSOCKET_KEY = AttributeKey.valueOf("cha.websocket"); 15 | public static final AttributeKey CLIENTID_KEY = AttributeKey.valueOf("cha.clientId"); 16 | public static final String HANDLER_NAME_HEARTCHECK = "idle"; 17 | public static final String HANDLER_NAME_SSL = "ssl"; 18 | } 19 | -------------------------------------------------------------------------------- /ext.opensource.netty-client/src/main/java/ext/opensource/netty/client/mqtt/api/MqttProducer.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.client.mqtt.api; 2 | 3 | import ext.opensource.netty.client.mqtt.common.MessageData; 4 | import ext.opensource.netty.common.api.GlobalUniqueIdSet; 5 | import ext.opensource.netty.common.core.CacheList; 6 | 7 | /** 8 | * @author ben 9 | * @Title: basic 10 | * @Description: 11 | **/ 12 | public interface MqttProducer extends GlobalUniqueIdSet { 13 | /** 14 | * 自定义缓存 15 | * @param msgList 16 | */ 17 | void setCacheList(CacheList msgList); 18 | 19 | 20 | /** 21 | * 发布消息 22 | * @param topic 23 | * @param message 24 | * @param qosValue 25 | * @param isRetain 26 | */ 27 | void sendPubishMessage(String topic, String message, int qosValue, boolean isRetain); 28 | 29 | 30 | } 31 | -------------------------------------------------------------------------------- /ext.opensource.netty-client-example/src/main/java/ext/opensource/netty/client/example/redis/RedisConditionalCache.java: -------------------------------------------------------------------------------- 1 | 2 | package ext.opensource.netty.client.example.redis; 3 | 4 | import org.springframework.context.annotation.Condition; 5 | import org.springframework.context.annotation.ConditionContext; 6 | import org.springframework.core.env.Environment; 7 | import org.springframework.core.type.AnnotatedTypeMetadata; 8 | 9 | /** 10 | * @author ben 11 | * @Title: xxx.java 12 | * @Description: 13 | **/ 14 | 15 | public class RedisConditionalCache implements Condition { 16 | @Override 17 | public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { 18 | Environment env = context.getEnvironment(); 19 | return "redis".equalsIgnoreCase( env.getProperty("netty.client.cache")); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /ext.opensource.netty-server-example/src/main/java/ext/opensource/netty/server/example/simple/SocketCmdService.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.server.example.simple; 2 | 3 | import org.springframework.stereotype.Component; 4 | import ext.opensource.netty.common.NettyLog; 5 | import ext.opensource.netty.common.TranDataProto; 6 | import ext.opensource.netty.common.TranDataProtoUtil; 7 | import ext.opensource.netty.server.simple.SocketCmdEvent; 8 | 9 | 10 | /** 11 | * @author ben 12 | * @Title: basic 13 | * @Description: 14 | **/ 15 | 16 | @Component 17 | public class SocketCmdService implements SocketCmdEvent { 18 | @Override 19 | public TranDataProto doCmd(String cmd, String message) { 20 | NettyLog.info("业务层收到的数据:" + message); 21 | return TranDataProtoUtil.getMsgInstance(10003, "中国人" + "\r\n"); 22 | } 23 | } -------------------------------------------------------------------------------- /ext.opensource.netty-client-example/src/main/java/ext/opensource/netty/client/example/ignite/IgniteConditionalCache.java: -------------------------------------------------------------------------------- 1 | 2 | package ext.opensource.netty.client.example.ignite; 3 | 4 | import org.springframework.context.annotation.Condition; 5 | import org.springframework.context.annotation.ConditionContext; 6 | import org.springframework.core.env.Environment; 7 | import org.springframework.core.type.AnnotatedTypeMetadata; 8 | 9 | /** 10 | * @author ben 11 | * @Title: xxx.java 12 | * @Description: 13 | **/ 14 | 15 | public class IgniteConditionalCache implements Condition { 16 | @Override 17 | public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { 18 | Environment env = context.getEnvironment(); 19 | return "ignite".equalsIgnoreCase( env.getProperty("netty.client.cache")); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /ext.opensource.netty-server-example/src/main/java/ext/opensource/netty/server/example/mqtt/redis/config/RedisConditionalCache.java: -------------------------------------------------------------------------------- 1 | 2 | package ext.opensource.netty.server.example.mqtt.redis.config; 3 | 4 | import org.springframework.context.annotation.Condition; 5 | import org.springframework.context.annotation.ConditionContext; 6 | import org.springframework.core.env.Environment; 7 | import org.springframework.core.type.AnnotatedTypeMetadata; 8 | 9 | /** 10 | * @author ben 11 | * @Title: xxx.java 12 | * @Description: 13 | **/ 14 | 15 | public class RedisConditionalCache implements Condition { 16 | @Override 17 | public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { 18 | Environment env = context.getEnvironment(); 19 | return "redis".equalsIgnoreCase( env.getProperty("netty.server.cache")); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /ext.opensource.netty-server-example/src/main/java/ext/opensource/netty/server/example/mqtt/ignite/config/IgniteConditionalCache.java: -------------------------------------------------------------------------------- 1 | 2 | package ext.opensource.netty.server.example.mqtt.ignite.config; 3 | 4 | import org.springframework.context.annotation.Condition; 5 | import org.springframework.context.annotation.ConditionContext; 6 | import org.springframework.core.env.Environment; 7 | import org.springframework.core.type.AnnotatedTypeMetadata; 8 | 9 | /** 10 | * @author ben 11 | * @Title: xxx.java 12 | * @Description: 13 | **/ 14 | 15 | public class IgniteConditionalCache implements Condition { 16 | @Override 17 | public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { 18 | Environment env = context.getEnvironment(); 19 | return "ignite".equalsIgnoreCase( env.getProperty("netty.server.cache")); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /ext.opensource.netty-common/src/main/java/ext/opensource/netty/common/NettyUtil.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.common; 2 | 3 | import io.netty.channel.Channel; 4 | import io.netty.util.Attribute; 5 | 6 | /** 7 | * @author ben 8 | * @Title: basic 9 | * @Description: 10 | **/ 11 | 12 | public class NettyUtil { 13 | public static String getClientId(Channel channel) { 14 | Attribute attr = channel.attr(NettyConstant.CLIENTID_KEY); 15 | return attr.get(); 16 | } 17 | 18 | public static void setClientId(Channel channel, String clientId) { 19 | Attribute attr = channel.attr(NettyConstant.CLIENTID_KEY); 20 | attr.set(clientId); 21 | } 22 | 23 | public static boolean isLogin(Channel channel) { 24 | String clientId = (String) channel.attr(NettyConstant.CLIENTID_KEY).get(); 25 | return clientId != null && clientId.trim().length() > 0; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /ext.opensource.netty-server-example/src/main/java/ext/opensource/netty/server/example/mqtt/kafka/config/KafkaConditionalCommunicate.java: -------------------------------------------------------------------------------- 1 | 2 | package ext.opensource.netty.server.example.mqtt.kafka.config; 3 | 4 | import org.springframework.context.annotation.Condition; 5 | import org.springframework.context.annotation.ConditionContext; 6 | import org.springframework.core.env.Environment; 7 | import org.springframework.core.type.AnnotatedTypeMetadata; 8 | 9 | /** 10 | * @author ben 11 | * @Title: basic 12 | * @Description: 13 | **/ 14 | 15 | public class KafkaConditionalCommunicate implements Condition { 16 | @Override 17 | public boolean matches(ConditionContext context, 18 | AnnotatedTypeMetadata metadata) { 19 | Environment env = context.getEnvironment(); 20 | return "kafka".equalsIgnoreCase( 21 | env.getProperty("netty.server.interal.communicate")); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /ext.opensource.netty-server-example/src/main/java/ext/opensource/netty/server/example/mqtt/redis/config/RedisConditionalCommunicate.java: -------------------------------------------------------------------------------- 1 | 2 | package ext.opensource.netty.server.example.mqtt.redis.config; 3 | 4 | import org.springframework.context.annotation.Condition; 5 | import org.springframework.context.annotation.ConditionContext; 6 | import org.springframework.core.env.Environment; 7 | import org.springframework.core.type.AnnotatedTypeMetadata; 8 | 9 | /** 10 | * @author ben 11 | * @Title: xxx.java 12 | * @Description: 13 | **/ 14 | 15 | public class RedisConditionalCommunicate implements Condition { 16 | @Override 17 | public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { 18 | Environment env = context.getEnvironment(); 19 | return "redis".equalsIgnoreCase(env.getProperty("netty.server.interal.communicate")); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /ext.opensource.netty-server/src/main/java/ext/opensource/netty/server/mqtt/common/InternalMessage.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.server.mqtt.common; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.Getter; 7 | import lombok.NoArgsConstructor; 8 | import lombok.Setter; 9 | 10 | /** 11 | * @author ben 12 | * @Title: basic 13 | * @Description: 14 | **/ 15 | 16 | @Getter 17 | @Setter 18 | @Builder 19 | @NoArgsConstructor 20 | @AllArgsConstructor 21 | @Data 22 | public class InternalMessage { 23 | private String topicName; 24 | private int respQoS; 25 | private byte[] msgBytes; 26 | 27 | //@Builder.Default 28 | //private int borkerMsgId = -1; 29 | 30 | @Builder.Default 31 | private boolean retain = false; 32 | @Builder.Default 33 | private boolean dup = false; 34 | 35 | private String destClientId; 36 | } 37 | -------------------------------------------------------------------------------- /ext.opensource.netty-server-example/src/main/java/ext/opensource/netty/server/example/mqtt/ignite/config/IgniteConditionalCommunicate.java: -------------------------------------------------------------------------------- 1 | 2 | package ext.opensource.netty.server.example.mqtt.ignite.config; 3 | 4 | import org.springframework.context.annotation.Condition; 5 | import org.springframework.context.annotation.ConditionContext; 6 | import org.springframework.core.env.Environment; 7 | import org.springframework.core.type.AnnotatedTypeMetadata; 8 | 9 | /** 10 | * @author ben 11 | * @Title: basic 12 | * @Description: 13 | **/ 14 | 15 | public class IgniteConditionalCommunicate implements Condition { 16 | @Override 17 | public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { 18 | Environment env = context.getEnvironment(); 19 | return "ignite".equalsIgnoreCase(env.getProperty("netty.server.interal.communicate")); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /ext.opensource.netty-client/src/main/java/ext/opensource/netty/client/mqtt/api/MqttConsumer.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.client.mqtt.api; 2 | 3 | import ext.opensource.netty.client.mqtt.common.MessageData; 4 | import ext.opensource.netty.common.api.GlobalUniqueIdSet; 5 | import ext.opensource.netty.common.core.CacheList; 6 | 7 | /** 8 | * @author ben 9 | * @Title: basic 10 | * @Description: 11 | **/ 12 | 13 | public interface MqttConsumer extends GlobalUniqueIdSet { 14 | /** 15 | * 自定义缓存 16 | * @param msgList 17 | */ 18 | public void setCacheList(CacheList msgList); 19 | 20 | /** 21 | * 订阅主题 22 | * @param topic 23 | * @param qosValue 24 | */ 25 | public void subscribe(String topic, int qosValue); 26 | 27 | /** 28 | * 接收订阅主题消息 29 | * @param listener 30 | */ 31 | public void setConsumerListener(MqttConsumerListener listener); 32 | 33 | 34 | } 35 | -------------------------------------------------------------------------------- /ext.opensource.netty-client-example/src/main/java/ext/opensource/netty/client/example/redis/RedisConditionConfig.java: -------------------------------------------------------------------------------- 1 | 2 | package ext.opensource.netty.client.example.redis; 3 | 4 | import org.infrastructure.redis.config.RedisConfig; 5 | import org.springframework.context.annotation.Bean; 6 | import org.springframework.context.annotation.Conditional; 7 | import org.springframework.context.annotation.Configuration; 8 | import org.springframework.context.annotation.Import; 9 | 10 | import ext.opensource.netty.client.example.mqtt.CustomMqttClientRedis; 11 | 12 | /** 13 | * @author ben 14 | * @Title: xx.java 15 | * @Description: 16 | **/ 17 | @Configuration 18 | @Import({ RedisConfig.class }) 19 | public class RedisConditionConfig { 20 | @Bean 21 | @Conditional(RedisConditionalCache.class) 22 | CustomMqttClientRedis customMqttClientRedis() { 23 | return new CustomMqttClientRedis(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /ext.opensource.netty-server-example/src/main/java/ext/opensource/netty/server/example/mqtt/kafka/CustomKafkaCommunicate.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.server.example.mqtt.kafka; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | 5 | import ext.opensource.netty.server.example.mqtt.MqttCustomCommunicate; 6 | 7 | /** 8 | * @author ben 9 | * @Title: basic 10 | * @Description: 11 | **/ 12 | 13 | public class CustomKafkaCommunicate extends MqttCustomCommunicate { 14 | private KafkaSubribleLister kafkaSubribleLister; 15 | @Autowired 16 | public void setKafkaSubribleLister(KafkaSubribleLister kafkaSubribleLister) { 17 | this.kafkaSubribleLister = kafkaSubribleLister; 18 | this.kafkaSubribleLister.setServerRecvice(this); 19 | } 20 | 21 | @Override 22 | protected void processInternalSend(String msg) { 23 | kafkaSubribleLister.sendPublishMessage(msg); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /ext.opensource.netty-server/src/main/java/ext/opensource/netty/server/mqtt/common/ConsumerMessage.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.server.mqtt.common; 2 | 3 | import java.io.Serializable; 4 | 5 | import lombok.AllArgsConstructor; 6 | import lombok.Builder; 7 | import lombok.Data; 8 | import lombok.Getter; 9 | import lombok.NoArgsConstructor; 10 | import lombok.Setter; 11 | 12 | /** 13 | * @author ben 14 | * @Title: basic 15 | * @Description: 16 | **/ 17 | 18 | @Getter 19 | @Setter 20 | @Builder 21 | @NoArgsConstructor 22 | @AllArgsConstructor 23 | @Data 24 | 25 | public class ConsumerMessage implements Serializable { 26 | private static final long serialVersionUID = 1L; 27 | 28 | private String sourceClientId; 29 | private String topic; 30 | private int mqttQoS; 31 | private byte[] messageBytes; 32 | private int messageId; 33 | private boolean retain; 34 | private boolean dup; 35 | } 36 | -------------------------------------------------------------------------------- /ext.opensource.netty-client/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | ext.opensource 6 | netty 7 | 0.0.1-SNAPSHOT 8 | 9 | netty-client 10 | 11 | 12 | 13 | ext.opensource 14 | netty-common 15 | ${project.parent.version} 16 | 17 | 18 | 19 | 20 | 21 | 22 | org.apache.maven.plugins 23 | maven-jar-plugin 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /ext.opensource.netty-server/src/main/java/ext/opensource/netty/server/mqtt/common/ProcedureMessage.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.server.mqtt.common; 2 | 3 | import java.io.Serializable; 4 | 5 | import lombok.AllArgsConstructor; 6 | import lombok.Builder; 7 | import lombok.Data; 8 | import lombok.Getter; 9 | import lombok.NoArgsConstructor; 10 | import lombok.Setter; 11 | 12 | /** 13 | * @author ben 14 | * @Title: basic 15 | * @Description: 16 | **/ 17 | 18 | 19 | @Getter 20 | @Setter 21 | @Builder 22 | @NoArgsConstructor 23 | @AllArgsConstructor 24 | @Data 25 | public class ProcedureMessage implements Serializable { 26 | private static final long serialVersionUID = 1L; 27 | 28 | private String sourceClientId; 29 | private int sourceMsgId; 30 | private String topicName; 31 | private int iQosLevel; 32 | private byte[] msgBytes; 33 | 34 | //@Builder.Default 35 | //private int borkerMsgId = -1; 36 | } 37 | -------------------------------------------------------------------------------- /ext.opensource.netty-server/src/main/resources/banner.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | ___ ____ ___ ____ _____ ___ __ __ ____ __ ___ 4 | / \ | \ / _]| \ / ___/ / \ | | || \ / ] / _] 5 | | || o ) [_ | _ ( \_ | || | || D ) / / / [_ 6 | | O || _/ _]| | |\__ || O || | || / / / | _] 7 | | || | | [_ | | |/ \ || || : || \ / \_ | [_ 8 | | || | | || | |\ || || || . \\ || | 9 | \___/ |__| |_____||__|__| \___| \___/ \__,_||__|\_| \____||_____| 10 | 11 | 12 | :: netty server example :: 13 | 14 | Build Version: ${info.app.build.ver} 15 | Application Version: ${application.version}${application.formatted-version} 16 | Spring Boot Version: ${spring-boot.version}${spring-boot.formatted-version} 17 | Spring Profiles Active: ${spring.profiles.active} 18 | 19 | -------------------------------------------------------------------------------- /ext.opensource.netty-client-example/src/main/resources/banner.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | ___ ____ ___ ____ _____ ___ __ __ ____ __ ___ 4 | / \ | \ / _]| \ / ___/ / \ | | || \ / ] / _] 5 | | || o ) [_ | _ ( \_ | || | || D ) / / / [_ 6 | | O || _/ _]| | |\__ || O || | || / / / | _] 7 | | || | | [_ | | |/ \ || || : || \ / \_ | [_ 8 | | || | | || | |\ || || || . \\ || | 9 | \___/ |__| |_____||__|__| \___| \___/ \__,_||__|\_| \____||_____| 10 | 11 | 12 | :: netty client example :: 13 | 14 | Build Version: ${info.app.build.ver} 15 | Application Version: ${application.version}${application.formatted-version} 16 | Spring Boot Version: ${spring-boot.version}${spring-boot.formatted-version} 17 | Spring Profiles Active: ${spring.profiles.active} 18 | 19 | -------------------------------------------------------------------------------- /ext.opensource.netty-server-example/src/main/resources/banner.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | ___ ____ ___ ____ _____ ___ __ __ ____ __ ___ 4 | / \ | \ / _]| \ / ___/ / \ | | || \ / ] / _] 5 | | || o ) [_ | _ ( \_ | || | || D ) / / / [_ 6 | | O || _/ _]| | |\__ || O || | || / / / | _] 7 | | || | | [_ | | |/ \ || || : || \ / \_ | [_ 8 | | || | | || | |\ || || || . \\ || | 9 | \___/ |__| |_____||__|__| \___| \___/ \__,_||__|\_| \____||_____| 10 | 11 | 12 | :: netty server example :: 13 | 14 | Build Version: ${info.app.build.ver} 15 | Application Version: ${application.version}${application.formatted-version} 16 | Spring Boot Version: ${spring-boot.version}${spring-boot.formatted-version} 17 | Spring Profiles Active: ${spring.profiles.active} 18 | 19 | -------------------------------------------------------------------------------- /ext.opensource.netty-server/src/main/java/ext/opensource/netty/server/mqtt/MqttWebSocketCodec.java: -------------------------------------------------------------------------------- 1 | 2 | package ext.opensource.netty.server.mqtt; 3 | 4 | import java.util.List; 5 | 6 | import io.netty.buffer.ByteBuf; 7 | import io.netty.channel.ChannelHandlerContext; 8 | import io.netty.handler.codec.MessageToMessageCodec; 9 | import io.netty.handler.codec.http.websocketx.BinaryWebSocketFrame; 10 | 11 | /** 12 | * @author ben 13 | * @Title: basic 14 | * @Description: 15 | **/ 16 | 17 | public class MqttWebSocketCodec extends MessageToMessageCodec { 18 | @Override 19 | protected void encode(ChannelHandlerContext ctx, ByteBuf msg, List out) throws Exception { 20 | out.add(new BinaryWebSocketFrame(msg.retain())); 21 | } 22 | 23 | @Override 24 | protected void decode(ChannelHandlerContext ctx, BinaryWebSocketFrame msg, List out) throws Exception { 25 | out.add(msg.retain().content()); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /ext.opensource.netty-common/src/main/java/ext/opensource/netty/common/exception/MethodNotSupportException.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.common.exception; 2 | 3 | 4 | /** 5 | * @author ben 6 | * @Title: basic 7 | * @Description: 8 | **/ 9 | 10 | public class MethodNotSupportException extends RuntimeException { 11 | private static final long serialVersionUID = 1L; 12 | 13 | public MethodNotSupportException() { 14 | super(getMsgStr()); 15 | } 16 | 17 | private static String getMsgStr() { 18 | String className = ""; 19 | String methodName = ""; 20 | Thread cur = Thread.currentThread(); 21 | int iLevel = 3; 22 | if (cur != null) { 23 | StackTraceElement[] ary = cur.getStackTrace(); 24 | if ((ary != null) && (ary.length > iLevel)) { 25 | className = ary[iLevel].getClassName(); 26 | methodName = ary[iLevel].getMethodName(); 27 | } 28 | } 29 | 30 | return String.format("Method Not Support: %s-%s", className, methodName); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /ext.opensource.netty-client/src/main/java/ext/opensource/netty/client/mqtt/common/MessageData.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.client.mqtt.common; 2 | 3 | import java.io.Serializable; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Builder; 6 | import lombok.Data; 7 | import lombok.NoArgsConstructor; 8 | 9 | /** 10 | * @author ben 11 | * @Title: basic 12 | * @Description: 13 | **/ 14 | 15 | @Builder 16 | @Data 17 | @NoArgsConstructor 18 | @AllArgsConstructor 19 | public class MessageData implements Serializable { 20 | private static final long serialVersionUID = 1L; 21 | private String topic; 22 | private byte[] payload; 23 | 24 | private int qos; 25 | private boolean retained; 26 | private boolean dup; 27 | private int messageId; 28 | 29 | @Builder.Default 30 | private long timestamp = System.currentTimeMillis(); 31 | 32 | private volatile MessageStatus status; 33 | 34 | public String getStringId() { 35 | return String.valueOf(messageId); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /ext.opensource.netty-server-example/src/main/java/ext/opensource/netty/server/example/simple/BizDispatchCollect.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.server.example.simple; 2 | 3 | import java.util.Map; 4 | import java.util.concurrent.ConcurrentHashMap; 5 | 6 | 7 | /** 8 | * @author ben 9 | * @Title: basic 10 | * @Description: 11 | **/ 12 | 13 | public class BizDispatchCollect { 14 | private static Map coursesTable = new ConcurrentHashMap<>(); 15 | 16 | public static void setCourses(Map courseMap) { 17 | coursesTable.clear(); 18 | if (courseMap != null && courseMap.size() > 0) { 19 | for (Map.Entry entry : courseMap.entrySet()) { 20 | coursesTable.put(entry.getKey(), entry.getValue()); 21 | } 22 | } 23 | } 24 | 25 | public static Object getBizDispatchObject(String code) { 26 | return coursesTable.get(code); 27 | } 28 | 29 | public static void processMesage(String code, String dataContent) { 30 | // 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /ext.opensource.netty-common/src/main/java/ext/opensource/netty/common/api/GlobalUniqueIdImpl.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.common.api; 2 | 3 | 4 | import ext.opensource.netty.common.core.CacheList; 5 | import ext.opensource.netty.common.core.CacheListLocalMemory; 6 | import ext.opensource.netty.common.core.UniqueIdInteger; 7 | 8 | /** 9 | * @author ben 10 | * @Title: basic 11 | * @Description: 12 | **/ 13 | 14 | public class GlobalUniqueIdImpl implements GlobalUniqueId { 15 | private CacheList list = new CacheListLocalMemory(); 16 | 17 | public void setCacheList(CacheList cacheList) { 18 | this.list = cacheList; 19 | } 20 | 21 | @Override 22 | public int getNextMessageId(String clientId) { 23 | UniqueIdInteger value = list.get(clientId); 24 | if (value == null) { 25 | value = new UniqueIdInteger(); 26 | } else { 27 | value.addInc(); 28 | } 29 | list.put(clientId, value); 30 | return value.id(); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /ext.opensource.netty-server/src/main/java/ext/opensource/netty/server/mqtt/common/RetainMessage.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.server.mqtt.common; 2 | 3 | import java.io.Serializable; 4 | import lombok.AllArgsConstructor; 5 | import lombok.Builder; 6 | import lombok.Data; 7 | import lombok.Getter; 8 | import lombok.NoArgsConstructor; 9 | import lombok.Setter; 10 | 11 | /** 12 | * @author ben 13 | * @Title: basic 14 | * @Description: 15 | **/ 16 | 17 | @Getter 18 | @Setter 19 | @Builder 20 | @NoArgsConstructor 21 | @AllArgsConstructor 22 | @Data 23 | 24 | public class RetainMessage implements Serializable { 25 | private static final long serialVersionUID = 1L; 26 | 27 | private String sourceClientId; 28 | private int sourceMsgId; 29 | 30 | private String topicName; 31 | private int iQosLevel; 32 | private byte[] msgBytes; 33 | 34 | //@Builder.Default 35 | //private int borkerMsgId = -1; 36 | 37 | @Builder.Default 38 | private long timestamp = System.currentTimeMillis(); 39 | } 40 | -------------------------------------------------------------------------------- /ext.opensource.netty-client/src/main/java/ext/opensource/netty/client/mqtt/common/MqttConnectOptions.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.client.mqtt.common; 2 | 3 | import io.netty.handler.codec.mqtt.MqttVersion; 4 | import lombok.Data; 5 | import lombok.Getter; 6 | import lombok.Setter; 7 | 8 | /** 9 | * @author ben 10 | * @Title: basic 11 | * @Description: 12 | **/ 13 | 14 | @Getter 15 | @Setter 16 | @Data 17 | public class MqttConnectOptions { 18 | private MqttVersion mqttVersion = MqttVersion.MQTT_3_1_1; 19 | 20 | private String clientIdentifier = ""; 21 | private String willTopic=""; 22 | private String userName=""; 23 | private byte[] willMessage; 24 | private byte[] password; 25 | private int willQos=0; 26 | private int keepAliveTime=60; 27 | 28 | private boolean hasUserName = false; 29 | private boolean hasPassword = false; 30 | private boolean hasWillRetain = false; 31 | private boolean hasWillFlag = false; 32 | private boolean hasCleanSession = false; 33 | 34 | public MqttConnectOptions() { 35 | 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /ext.opensource.netty-server/src/main/java/ext/opensource/netty/server/httpsocket/HttpResourceFile.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.server.httpsocket; 2 | 3 | import java.io.InputStream; 4 | import java.util.Map; 5 | import io.netty.buffer.ByteBuf; 6 | import io.netty.buffer.ByteBufAllocator; 7 | 8 | /** 9 | * @author ben 10 | * @Title: basic 11 | * @Description: 12 | **/ 13 | 14 | public class HttpResourceFile extends BaseHttpResource { 15 | 16 | @Override 17 | protected ByteBuf buildRes(String resPath, Map parameters) { 18 | try { 19 | InputStream inputStream = HttpResourceFile.class.getResourceAsStream("/" + this.getRootDir() + resPath); 20 | if (inputStream != null) { 21 | int available = inputStream.available(); 22 | if (available != 0) { 23 | byte[] bytes = new byte[available]; 24 | inputStream.read(bytes); 25 | return ByteBufAllocator.DEFAULT.buffer(bytes.length).writeBytes(bytes); 26 | } 27 | } 28 | } catch (Exception e) { 29 | } 30 | return null; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /ext.opensource.netty-common/src/main/java/ext/opensource/netty/common/core/CacheListLocalMemory.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.common.core; 2 | 3 | import java.util.concurrent.ConcurrentHashMap; 4 | 5 | /** 6 | * @author ben 7 | * @Title: basic 8 | * @Description: 9 | **/ 10 | 11 | public class CacheListLocalMemory extends BaseCacheList< V> { 12 | private ConcurrentHashMap msgList = new ConcurrentHashMap(); 13 | 14 | @Override 15 | public boolean put(String key, V value) { 16 | return msgList.put(key, value) == null; 17 | } 18 | 19 | @Override 20 | public V get(String key) { 21 | if (key == null) { 22 | return null; 23 | } else { 24 | return msgList.getOrDefault(key, null); 25 | } 26 | } 27 | 28 | @Override 29 | public V remove(String key) { 30 | return msgList.remove(key); 31 | } 32 | 33 | @Override 34 | public long size() { 35 | return msgList.size(); 36 | } 37 | 38 | @Override 39 | public boolean exists(String key) { 40 | return msgList.containsKey(key); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /ext.opensource.netty-server-example/src/main/java/ext/opensource/netty/server/example/mqtt/kafka/config/KafkaConditionConfig.java: -------------------------------------------------------------------------------- 1 | 2 | package ext.opensource.netty.server.example.mqtt.kafka.config; 3 | 4 | import org.springframework.context.annotation.Bean; 5 | import org.springframework.context.annotation.Conditional; 6 | import org.springframework.context.annotation.Configuration; 7 | import ext.opensource.netty.server.example.mqtt.kafka.CustomKafkaCommunicate; 8 | import ext.opensource.netty.server.example.mqtt.kafka.KafkaSubribleLister; 9 | 10 | 11 | /** 12 | * @author ben 13 | * @Title: basic 14 | * @Description: 15 | **/ 16 | @Configuration 17 | public class KafkaConditionConfig { 18 | @Bean 19 | @Conditional(KafkaConditionalCommunicate.class) 20 | public KafkaSubribleLister kafkaSubribleLister(){ 21 | return new KafkaSubribleLister(); 22 | } 23 | 24 | @Bean 25 | @Conditional(KafkaConditionalCommunicate.class) 26 | public CustomKafkaCommunicate customKafkaCommunicate() { 27 | return new CustomKafkaCommunicate(); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /ext.opensource.netty-server/src/main/java/ext/opensource/netty/server/httpsocket/WebSocketServer.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.server.httpsocket; 2 | 3 | import io.netty.handler.codec.http.websocketx.TextWebSocketFrame; 4 | import lombok.Getter; 5 | import lombok.NonNull; 6 | import lombok.Setter; 7 | 8 | /** 9 | * @author ben 10 | * @Title: basic 11 | * @Description: 12 | **/ 13 | 14 | public class WebSocketServer extends HttpServer { 15 | @Getter 16 | @Setter 17 | @NonNull 18 | private WebSocketEvent webSocketEvent; 19 | 20 | @Setter 21 | private String websocketPath; 22 | 23 | public WebSocketServer() { 24 | } 25 | 26 | @Override 27 | public void broadcastMessageString(String msg) { 28 | super.broadcastMessage(new TextWebSocketFrame(msg)); 29 | } 30 | 31 | @Override 32 | protected void processHttpHandler(HttpServerHandler httpServerHandler) { 33 | if (httpServerHandler != null) { 34 | httpServerHandler.setWebSocketEvent(webSocketEvent); 35 | httpServerHandler.setWebsocketPath(websocketPath); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /ext.opensource.netty-client/src/main/java/ext/opensource/netty/client/mqtt/api/MqttProducerProcess.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.client.mqtt.api; 2 | 3 | import ext.opensource.netty.client.mqtt.common.MessageData; 4 | 5 | /** 6 | * @author ben 7 | * @Title: basic 8 | * @Description: 9 | **/ 10 | public interface MqttProducerProcess extends MqttProducer { 11 | 12 | /** 13 | * processPubAck 14 | * @param messageId 15 | */ 16 | void processPubAck(int messageId); 17 | 18 | /** 19 | * processPubRec 20 | * @param messageId 21 | */ 22 | void processPubRec(int messageId); 23 | 24 | /** 25 | * processPubComp 26 | * @param messageId 27 | */ 28 | public void processPubComp(int messageId); 29 | 30 | /** 31 | * sendPubRel 32 | * @param messageId 33 | */ 34 | void sendPubRel(int messageId); 35 | 36 | /** 37 | * saveMessage 38 | * @param recviceMessage 39 | */ 40 | void saveMessage(MessageData recviceMessage); 41 | 42 | /** 43 | * delMessage 44 | * @param messageId 45 | */ 46 | void delMessage(int messageId); 47 | } 48 | -------------------------------------------------------------------------------- /ext.opensource.netty-server/src/main/java/ext/opensource/netty/server/mqtt/common/BorkerMessage.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.server.mqtt.common; 2 | 3 | import java.io.Serializable; 4 | 5 | import lombok.AllArgsConstructor; 6 | import lombok.Builder; 7 | import lombok.Data; 8 | import lombok.Getter; 9 | import lombok.NoArgsConstructor; 10 | import lombok.Setter; 11 | 12 | /** 13 | * @author ben 14 | * @Title: basic 15 | * @Description: 16 | **/ 17 | 18 | @Getter 19 | @Setter 20 | @Builder 21 | @NoArgsConstructor 22 | @AllArgsConstructor 23 | @Data 24 | public class BorkerMessage implements Serializable { 25 | private static final long serialVersionUID = 1L; 26 | 27 | private String sourceClientId; 28 | private int sourceMsgId; 29 | 30 | private String topicName; 31 | private int iQosLevel; 32 | private byte[] msgBytes; 33 | 34 | @Builder.Default 35 | private boolean retain = false; 36 | 37 | @Builder.Default 38 | private boolean dup = false; 39 | 40 | @Builder.Default 41 | private long timestamp = System.currentTimeMillis(); 42 | } 43 | -------------------------------------------------------------------------------- /ext.opensource.netty-server-example/src/main/java/ext/opensource/netty/server/example/listen/ContextClosedListener.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.server.example.listen; 2 | 3 | 4 | 5 | import java.util.Map; 6 | import java.util.Map.Entry; 7 | import org.springframework.context.ApplicationListener; 8 | import org.springframework.context.event.ContextClosedEvent; 9 | import org.springframework.stereotype.Component; 10 | import ext.opensource.netty.common.api.SocketApplication; 11 | 12 | /** 13 | * @author ben 14 | * @Title: basic 15 | * @Description: 16 | **/ 17 | 18 | @Component 19 | public class ContextClosedListener implements ApplicationListener { 20 | @Override 21 | public void onApplicationEvent(ContextClosedEvent event) { 22 | System.err.println("============Close 执行=========== "); 23 | 24 | Map result = event.getApplicationContext().getBeansOfType(SocketApplication.class); 25 | 26 | for (Entry app : result.entrySet()) { 27 | System.err.println(app.getKey()); 28 | app.getValue().shutdown(); 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /ext.opensource.netty-client-example/src/main/java/ext/opensource/netty/client/example/listen/ContextClosedListener.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.client.example.listen; 2 | 3 | import java.util.Map; 4 | import java.util.Map.Entry; 5 | 6 | import org.springframework.context.ApplicationListener; 7 | import org.springframework.context.event.ContextClosedEvent; 8 | import org.springframework.stereotype.Component; 9 | 10 | import ext.opensource.netty.common.api.SocketApplication; 11 | 12 | 13 | /** 14 | * @author ben 15 | * @Title: basic 16 | * @Description: 17 | **/ 18 | 19 | @Component 20 | public class ContextClosedListener implements ApplicationListener{ 21 | @Override 22 | public void onApplicationEvent(ContextClosedEvent event) { 23 | System.err.println("============Close 执行=========== "); 24 | 25 | Map result = event.getApplicationContext().getBeansOfType(SocketApplication.class); 26 | 27 | for (Entry app : result.entrySet()) { 28 | System.err.println(app.getKey()); 29 | app.getValue().shutdown(); 30 | } 31 | 32 | } 33 | } -------------------------------------------------------------------------------- /ext.opensource.netty-common/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | ext.opensource 6 | netty 7 | 0.0.1-SNAPSHOT 8 | 9 | netty-common 10 | netty-common 11 | 12 | 13 | 4.1.42.Final 14 | 15 | 16 | 17 | 18 | io.netty 19 | netty-all 20 | ${netty.version} 21 | 22 | 23 | 24 | com.alibaba 25 | fastjson 26 | 27 | 28 | 29 | 30 | 31 | 32 | org.apache.maven.plugins 33 | maven-jar-plugin 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /ext.opensource.netty-server-example/src/main/java/ext/opensource/netty/server/example/mqtt/ignite/InternalCommunicationIgnite.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.server.example.mqtt.ignite; 2 | 3 | import javax.annotation.PostConstruct; 4 | import org.apache.ignite.IgniteMessaging; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import ext.opensource.netty.server.mqtt.common.BorkerMessage; 7 | 8 | /** 9 | * @author ben 10 | * @Title: basic 11 | * @Description: 12 | **/ 13 | 14 | public class InternalCommunicationIgnite { 15 | private final String internalTopic = "internal-ignite-topic"; 16 | 17 | @Autowired 18 | private IgniteMessaging igniteMessaging; 19 | 20 | @PostConstruct 21 | private void internalListen() { 22 | igniteMessaging.localListen(internalTopic, (nodeId, msg) -> { 23 | ///InternalMessage internalMessage = (InternalMessage) msg; 24 | return true; 25 | }); 26 | } 27 | 28 | public void internalSend(BorkerMessage bMsg) { 29 | if (igniteMessaging.clusterGroup().nodes() != null && igniteMessaging.clusterGroup().nodes().size() > 0) { 30 | igniteMessaging.send(internalTopic, bMsg); 31 | } 32 | } 33 | 34 | 35 | } 36 | -------------------------------------------------------------------------------- /ext.opensource.netty-server-example/src/main/java/ext/opensource/netty/server/example/mqtt/redis/config/RedisConditionConfig.java: -------------------------------------------------------------------------------- 1 | 2 | package ext.opensource.netty.server.example.mqtt.redis.config; 3 | 4 | import org.infrastructure.redis.config.RedisConfig; 5 | import org.springframework.context.annotation.Bean; 6 | import org.springframework.context.annotation.Conditional; 7 | import org.springframework.context.annotation.Configuration; 8 | import org.springframework.context.annotation.Import; 9 | 10 | import ext.opensource.netty.server.example.mqtt.redis.CustomRedisCommunicate; 11 | import ext.opensource.netty.server.example.mqtt.redis.CustomRedisCache; 12 | 13 | /** 14 | * @author ben 15 | * @Title: xx.java 16 | * @Description: 17 | **/ 18 | @Configuration 19 | @Import({ RedisConfig.class }) 20 | public class RedisConditionConfig { 21 | @Bean 22 | @Conditional(RedisConditionalCache.class) 23 | CustomRedisCache customRedisCache() { 24 | return new CustomRedisCache(); 25 | } 26 | 27 | @Bean 28 | @Conditional(RedisConditionalCommunicate.class) 29 | CustomRedisCommunicate customCommunicateRedis() { 30 | return new CustomRedisCommunicate(); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /ext.opensource.netty-server-example/src/main/java/ext/opensource/netty/server/example/mqtt/MqttCustom.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.server.example.mqtt; 2 | 3 | import ext.opensource.netty.server.mqtt.MqttServer; 4 | import ext.opensource.netty.server.mqtt.api.MqttAuth; 5 | import ext.opensource.netty.server.mqtt.api.PubishMessageLister; 6 | import ext.opensource.netty.server.mqtt.common.BorkerMessage; 7 | 8 | 9 | /** 10 | * @author ben 11 | * @Title: basic 12 | * @Description: 13 | **/ 14 | 15 | public class MqttCustom extends BaseMqttCustom implements MqttAuth, PubishMessageLister { 16 | @Override 17 | public boolean checkValid(String clientId, String username, String password) { 18 | System.err.println(String.format("login: clientId-%s, username-%s, password-%s", clientId, username, password)); 19 | return true; 20 | } 21 | 22 | @Override 23 | public void processMessage(BorkerMessage msg) { 24 | System.err.println("msg: " + msg); 25 | } 26 | 27 | @Override 28 | public void init(MqttServer mqttServer) { 29 | super.init(mqttServer); 30 | mqttServer.initMqtt().setAuthService(this); 31 | mqttServer.initMqtt().setPubishMessageLister(this); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /ext.opensource.netty-server-example/src/main/java/ext/opensource/netty/server/example/mqtt/redis/CustomRedisCommunicate.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.server.example.mqtt.redis; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | 5 | import ext.opensource.netty.server.example.mqtt.MqttCustomCommunicate; 6 | import ext.opensource.netty.server.example.mqtt.redis.config.RedisSubribleLister; 7 | 8 | /** 9 | * @author ben 10 | * @Title: basic 11 | * @Description: 12 | **/ 13 | 14 | public class CustomRedisCommunicate extends MqttCustomCommunicate { 15 | private RedisSubribleLister redisSubribleLister; 16 | 17 | @Autowired 18 | public void setInternalRedisLister( 19 | RedisSubribleLister redisSubribleLister) { 20 | this.redisSubribleLister = redisSubribleLister; 21 | this.redisSubribleLister.setServerRecvice(this); 22 | } 23 | 24 | @Override 25 | protected void processInternalSend(String msg) { 26 | redisSubribleLister.sendPublishMessage(msg); 27 | } 28 | 29 | /* 30 | * @Scheduled(fixedRate = 3000) public void test() { InternalMessage msg = 31 | * InternalMessage.builder().topicName("aaa").build(); internalSend(msg); } 32 | */ 33 | } 34 | -------------------------------------------------------------------------------- /ext.opensource.netty-common/src/main/java/ext/opensource/netty/common/core/CacheList.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.common.core; 2 | 3 | /** 4 | * @author ben 5 | * @Title: basic 6 | * @Description: 7 | **/ 8 | 9 | public interface CacheList { 10 | /** 11 | * getCacheName 12 | * @return 13 | */ 14 | public String getCacheName(); 15 | 16 | /** 17 | * put 18 | * @param key 19 | * @param value 20 | * @return 21 | */ 22 | public boolean put(String key, V value); 23 | 24 | /** 25 | * get 26 | * @param key 27 | * @return 28 | */ 29 | public V get(String key); 30 | 31 | /** 32 | * remove 33 | * @param key 34 | * @return 35 | */ 36 | public V remove(String key); 37 | 38 | /** 39 | * exists 40 | * @param key 41 | * @return 42 | */ 43 | public boolean exists(String key); 44 | 45 | /** 46 | * containsKey 47 | * @param key 48 | * @return 49 | */ 50 | public boolean containsKey(String key); 51 | 52 | /** 53 | * size 54 | * @return 55 | */ 56 | public long size(); 57 | 58 | 59 | /// 60 | //public Set> entrySet(); 61 | //public Collection valueList(); 62 | //public Collection keyList(); 63 | } 64 | -------------------------------------------------------------------------------- /ext.opensource.netty-client/src/main/java/ext/opensource/netty/client/core/LoginCheckThread.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.client.core; 2 | 3 | 4 | /** 5 | * @author ben 6 | * @Title: basic 7 | * @Description: 8 | **/ 9 | 10 | public class LoginCheckThread extends Thread { 11 | private BaseClient client; 12 | private long timeOutMillis; 13 | private long startTime; 14 | public LoginCheckThread(BaseClient client, long startTime, long timeOutMillis) { 15 | this.client = client; 16 | this.timeOutMillis = timeOutMillis; 17 | this.startTime = startTime; 18 | } 19 | 20 | @Override 21 | public void run() { 22 | check(); 23 | } 24 | 25 | public void check() { 26 | boolean bTimeOut = false; 27 | while (true) { 28 | try { 29 | Thread.sleep(500); 30 | } catch (InterruptedException e) { 31 | break; 32 | } 33 | 34 | if (timeOutMillis > 0) { 35 | if ((System.currentTimeMillis() - startTime) > timeOutMillis) { 36 | bTimeOut = true; 37 | } 38 | } 39 | 40 | if ((this.client== null) || (this.client.checkConnectFlag(bTimeOut, System.currentTimeMillis() - startTime))) { 41 | break; 42 | } 43 | if (bTimeOut) { 44 | break; 45 | } 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /ext.opensource.netty-server-example/src/main/java/ext/opensource/netty/server/example/mqtt/redis/config/RedisSubribleLister.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.server.example.mqtt.redis.config; 2 | 3 | import org.springframework.beans.factory.annotation.Autowired; 4 | import org.springframework.data.redis.core.StringRedisTemplate; 5 | import org.springframework.stereotype.Component; 6 | import ext.opensource.netty.common.NettyLog; 7 | import ext.opensource.netty.server.example.mqtt.MqttServerRecvice; 8 | import lombok.Setter; 9 | 10 | /** 11 | * @author ben 12 | * @Title: basic 13 | * @Description: 14 | **/ 15 | 16 | @Component 17 | public class RedisSubribleLister { 18 | @Setter 19 | private MqttServerRecvice serverRecvice; 20 | @Autowired 21 | private StringRedisTemplate sendRedisTemplate; 22 | 23 | public void sendPublishMessage(String message) { 24 | NettyLog.info("internalSend: " + message); 25 | sendRedisTemplate.convertAndSend(RedisSubListenerConfig.MQTT_TOPIC_NAME, message); 26 | } 27 | 28 | public void receiveMessage(String message) { 29 | NettyLog.info("internalRecvice: " + message); 30 | 31 | if (serverRecvice != null) { 32 | serverRecvice.processServerRecviceMesage(message); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /ext.opensource.netty-server/src/main/java/ext/opensource/netty/server/TestServerApplication.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.server; 2 | 3 | import org.springframework.boot.CommandLineRunner; 4 | import org.springframework.boot.SpringApplication; 5 | import org.springframework.boot.autoconfigure.SpringBootApplication; 6 | 7 | import ext.opensource.netty.common.NettyLog; 8 | import ext.opensource.netty.common.api.SocketApplication; 9 | import ext.opensource.netty.server.core.BaseServer; 10 | import ext.opensource.netty.server.mqtt.MqttServer; 11 | 12 | /** 13 | * @author ben 14 | * @Title: basic 15 | * @Description: 16 | **/ 17 | 18 | @SpringBootApplication 19 | public class TestServerApplication implements CommandLineRunner , SocketApplication { 20 | public static void main(String[] args) { 21 | SpringApplication.run(TestServerApplication.class, args); 22 | } 23 | 24 | private BaseServer scoketServer; 25 | 26 | @Override 27 | public void run(String... strings) { 28 | scoketServer = new MqttServer(); 29 | scoketServer.bind(8989); 30 | NettyLog.info("testserver run end "); 31 | } 32 | 33 | @Override 34 | public void shutdown() { 35 | if (scoketServer != null) { 36 | scoketServer.shutdown(); 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /ext.opensource.netty-server-example/src/main/java/ext/opensource/netty/server/example/scanner/InvokerHoler.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.server.example.scanner; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | /** 7 | * @author ben 8 | * @Title: basic 9 | * @Description: 10 | **/ 11 | public class InvokerHoler { 12 | 13 | /**命令调用器*/ 14 | private static Map> invokers = new HashMap<>(); 15 | 16 | /** 17 | * 添加命令调用 18 | * @param module 19 | * @param cmd 20 | * @param invoker 21 | */ 22 | public static void addInvoker(short module, short cmd, Invoker invoker){ 23 | Map map = invokers.get(module); 24 | if(map == null){ 25 | map = new HashMap<>(16); 26 | invokers.put(module, map); 27 | } 28 | map.put(cmd, invoker); 29 | } 30 | 31 | 32 | /** 33 | * 获取命令调用 34 | * @param module 35 | * @param cmd 36 | * @param invoker 37 | */ 38 | public static Invoker getInvoker(short module, short cmd){ 39 | Map map = invokers.get(module); 40 | if(map != null){ 41 | return map.get(cmd); 42 | } 43 | return null; 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /ext.opensource.netty-server/src/main/java/ext/opensource/netty/server/SimpleServerApplication.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.server; 2 | 3 | import org.springframework.boot.CommandLineRunner; 4 | import org.springframework.boot.SpringApplication; 5 | import ext.opensource.netty.common.NettyLog; 6 | import ext.opensource.netty.common.api.SocketApplication; 7 | import ext.opensource.netty.server.simple.SimpleServer; 8 | 9 | /** 10 | * @author ben 11 | * @Title: basic 12 | * @Description: 13 | **/ 14 | 15 | //@SpringBootApplication 16 | 17 | public class SimpleServerApplication implements CommandLineRunner, SocketApplication { 18 | public static void main(String[] args) { 19 | SpringApplication.run(SimpleServerApplication.class, args); 20 | } 21 | private SimpleServer nettyServer; 22 | 23 | @Override 24 | public void run(String... strings) { 25 | nettyServer = new SimpleServer(); 26 | ///nettyServer.setSocketModel(SocketModel.BLOCK); 27 | nettyServer.setCheckHeartbeat(false); 28 | nettyServer.setAllIdleTimeSeconds(90); 29 | nettyServer.bind(8989); 30 | 31 | NettyLog.info("simple server run end "); 32 | } 33 | 34 | @Override 35 | public void shutdown() { 36 | if (nettyServer != null) { 37 | nettyServer.shutdown(); 38 | } 39 | } 40 | } -------------------------------------------------------------------------------- /ext.opensource.netty-server/src/main/java/ext/opensource/netty/server/mqtt/api/ConsumerDataService.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.server.mqtt.api; 2 | 3 | import java.util.List; 4 | 5 | import ext.opensource.netty.common.core.CacheList; 6 | import ext.opensource.netty.server.mqtt.common.ConsumerMessage; 7 | import ext.opensource.netty.server.mqtt.protocol.data.ConsumerClientData; 8 | 9 | /** 10 | * @author ben 11 | * @Title: basic 12 | * @Description: 13 | **/ 14 | 15 | public interface ConsumerDataService { 16 | /** 17 | * 自定义缓存 18 | * @param cacheList 19 | */ 20 | public void setConsumerCacheList(CacheList cacheList); 21 | 22 | /** 23 | * 向消费者发送信息 24 | * @param clientId 25 | * @param dupPublishMessage 26 | */ 27 | public void putPublishMessage(String clientId, ConsumerMessage dupPublishMessage); 28 | 29 | /** 30 | * 获取未确认的信息 31 | * @param clientId 32 | * @return 33 | */ 34 | public List getPublishMessage(String clientId); 35 | 36 | /** 37 | * 删除指定用户的信息 38 | * @param clientId 39 | * @param messageId 40 | */ 41 | public void removePublishMessage(String clientId, int messageId); 42 | 43 | /** 44 | * 用户退出处理 45 | * @param clientId 46 | */ 47 | public void removeByClient(String clientId); 48 | } 49 | -------------------------------------------------------------------------------- /ext.opensource.netty-server/src/main/java/ext/opensource/netty/server/httpsocket/WebSocketEvent.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.server.httpsocket; 2 | 3 | import java.util.Map; 4 | 5 | import ext.opensource.netty.server.core.BaseServer; 6 | import io.netty.buffer.ByteBuf; 7 | 8 | /** 9 | * @author ben 10 | * @Title: basic 11 | * @Description: 12 | **/ 13 | 14 | public interface WebSocketEvent { 15 | /** 16 | * onOpenEvent 17 | * @param sevice 18 | * @param session 19 | * @param parameter 20 | */ 21 | public void onOpenEvent(BaseServer sevice, WebSocketSession session, Map parameter); 22 | 23 | /** 24 | * onCloseEvent 25 | * @param sevice 26 | * @param ctx 27 | */ 28 | public void onCloseEvent(BaseServer sevice, WebSocketSession ctx); 29 | 30 | /*public void OnErrorEvent(WebSocketSession wsSession);*/ 31 | 32 | /** 33 | * onMessageStringEvent 34 | * @param sevice 35 | * @param session 36 | * @param msg 37 | */ 38 | public void onMessageStringEvent(BaseServer sevice, WebSocketSession session, String msg); 39 | 40 | /** 41 | * onMessageBinaryEvent 42 | * @param sevice 43 | * @param session 44 | * @param msg 45 | */ 46 | public void onMessageBinaryEvent(BaseServer sevice, WebSocketSession session, ByteBuf msg); 47 | } 48 | 49 | -------------------------------------------------------------------------------- /ext.opensource.redis/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | ext.opensource 6 | netty 7 | 0.0.1-SNAPSHOT 8 | 9 | ext.opensource.redis 10 | 11 | 12 | 13 | org.springframework.boot 14 | spring-boot-starter-data-redis 15 | 16 | 17 | 18 | com.alibaba 19 | fastjson 20 | 21 | 22 | 23 | com.fasterxml.jackson.module 24 | jackson-module-jaxb-annotations 25 | 26 | 27 | 28 | com.google.code.gson 29 | gson 30 | 31 | 32 | 33 | 34 | 35 | 36 | org.apache.maven.plugins 37 | maven-jar-plugin 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /ext.opensource.netty-client-example/src/main/java/ext/opensource/netty/client/example/WebSocketClientApplication.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.client.example; 2 | 3 | import org.springframework.boot.CommandLineRunner; 4 | import org.springframework.boot.SpringApplication; 5 | import ext.opensource.netty.client.httpsocket.WebSocketClient; 6 | import ext.opensource.netty.common.api.SocketApplication; 7 | 8 | /** 9 | * @author ben 10 | * @Title: basic 11 | * @Description: 12 | **/ 13 | 14 | //@SpringBootApplication 15 | 16 | public class WebSocketClientApplication implements CommandLineRunner, SocketApplication { 17 | private WebSocketClient webScoketClient; 18 | 19 | public static void main(String[] args) { 20 | SpringApplication.run(WebSocketClientApplication.class, args); 21 | } 22 | 23 | @Override 24 | public void run(String... strings) { 25 | WebSocketClient webScoketClient = new WebSocketClient("/websocket"); 26 | webScoketClient.setCheckConnectFlag(true); 27 | webScoketClient.connect(8989); 28 | webScoketClient.requireSync(); 29 | webScoketClient.sendMessage("test"); 30 | System.err.println("websocket client run end"); 31 | } 32 | 33 | @Override 34 | public void shutdown() { 35 | if (webScoketClient != null) { 36 | webScoketClient.shutdown(); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /ext.opensource.netty-server-example/src/main/java/ext/opensource/netty/server/example/mqtt/MqttCustomCommunicate.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.server.example.mqtt; 2 | 3 | import com.alibaba.fastjson.JSON; 4 | import ext.opensource.netty.server.mqtt.MqttServer; 5 | import ext.opensource.netty.server.mqtt.api.InternalSend; 6 | import ext.opensource.netty.server.mqtt.common.InternalMessage; 7 | 8 | 9 | /** 10 | * @author ben 11 | * @Title: basic 12 | * @Description: 13 | **/ 14 | 15 | public class MqttCustomCommunicate extends BaseMqttCustom implements InternalSend, MqttServerRecvice { 16 | @Override 17 | public void init(MqttServer mqttServer) { 18 | super.init(mqttServer); 19 | mqttServer.initMqtt().setInternalSend(this); 20 | } 21 | 22 | @Override 23 | public void internalSend(InternalMessage msg) { 24 | processInternalSend(JSON.toJSONString(msg)); 25 | } 26 | protected void processInternalSend(String msg) { 27 | } 28 | 29 | public boolean processInternalRecvice(InternalMessage msg) { 30 | return mqttServer.internalRecvice().processInternalRecvice(msg); 31 | } 32 | 33 | @Override 34 | public boolean processServerRecviceMesage(String message) { 35 | InternalMessage msgObj = JSON.parseObject(message, InternalMessage.class); 36 | return processInternalRecvice(msgObj); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /ext.opensource.netty-server/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | ext.opensource 6 | netty 7 | 0.0.1-SNAPSHOT 8 | 9 | netty-server 10 | netty-server 11 | 12 | 13 | 3.0.11.RELEASE 14 | 2.1.2 15 | 2.7.0 16 | 17 | 18 | 19 | 20 | org.springframework.boot 21 | spring-boot-starter 22 | 23 | 24 | 25 | ext.opensource 26 | netty-common 27 | ${project.parent.version} 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | org.apache.maven.plugins 36 | maven-jar-plugin 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /ext.opensource.netty-server/src/main/java/ext/opensource/netty/server/simple/SimpleServer.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.server.simple; 2 | 3 | import java.nio.charset.Charset; 4 | 5 | import ext.opensource.netty.common.LogDispatchHandler; 6 | import ext.opensource.netty.common.TranDataProtoUtil; 7 | import ext.opensource.netty.server.core.BaseServer; 8 | import io.netty.channel.socket.SocketChannel; 9 | import io.netty.handler.codec.LineBasedFrameDecoder; 10 | import io.netty.handler.codec.string.StringDecoder; 11 | import io.netty.handler.codec.string.StringEncoder; 12 | 13 | /** 14 | * @author ben 15 | * @Title: basic 16 | * @Description: 17 | **/ 18 | 19 | public class SimpleServer extends BaseServer { 20 | @Override 21 | protected void initSocketChannel(SocketChannel ch) { 22 | super.initSocketChannel(ch); 23 | ch.pipeline().addLast(new LineBasedFrameDecoder(1024)); 24 | ch.pipeline().addLast(new StringEncoder(Charset.forName("UTF-8"))); 25 | ch.pipeline().addLast(new StringDecoder(Charset.forName("UTF-8"))); 26 | ch.pipeline().addLast(new LogDispatchHandler()); 27 | ch.pipeline().addLast(new SimpleServerHandler()); 28 | } 29 | 30 | @Override 31 | public void broadcastMessageString(String msg) { 32 | super.broadcastMessage(TranDataProtoUtil.getMsgSocketData(TranDataProtoUtil.getMsgInstance(1003, "test"))); 33 | } 34 | 35 | 36 | } -------------------------------------------------------------------------------- /ext.opensource.netty-client-example/src/main/java/ext/opensource/netty/client/example/SimpleClientApplication.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.client.example; 2 | 3 | import java.net.URISyntaxException; 4 | 5 | import org.springframework.boot.CommandLineRunner; 6 | import org.springframework.boot.SpringApplication; 7 | import ext.opensource.netty.client.simple.SimpleClient; 8 | import ext.opensource.netty.common.api.SocketApplication; 9 | 10 | /** 11 | * @author ben 12 | * @Title: basic 13 | * @Description: 14 | **/ 15 | 16 | //@SpringBootApplication 17 | 18 | public class SimpleClientApplication implements CommandLineRunner, SocketApplication { 19 | private SimpleClient nettyClient; 20 | 21 | public static void main(String[] args) { 22 | SpringApplication.run(SimpleClientApplication.class, args); 23 | } 24 | 25 | @Override 26 | public void run(String... strings) throws URISyntaxException { 27 | 28 | nettyClient = new SimpleClient(); 29 | /// 30 | // nettyClient.setSocketModel(SocketModel.BLOCK); 31 | nettyClient.setCheckHeartbeat(false); 32 | nettyClient.setReaderIdleTimeSeconds(10); 33 | nettyClient.setCheckConnectFlag(true); 34 | nettyClient.connect(8989); 35 | 36 | System.err.println("simple client run end"); 37 | } 38 | 39 | @Override 40 | public void shutdown() { 41 | if (nettyClient != null) { 42 | nettyClient.shutdown(); 43 | nettyClient = null; 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /ext.opensource.netty-server/src/main/java/ext/opensource/netty/server/httpsocket/HttpServer.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.server.httpsocket; 2 | 3 | import ext.opensource.netty.server.core.BaseServer; 4 | import io.netty.channel.socket.SocketChannel; 5 | import io.netty.handler.codec.http.HttpObjectAggregator; 6 | import io.netty.handler.codec.http.HttpServerCodec; 7 | import io.netty.handler.stream.ChunkedWriteHandler; 8 | import lombok.Getter; 9 | import lombok.Setter; 10 | 11 | /** 12 | * @author ben 13 | * @Title: basic 14 | * @Description: 15 | **/ 16 | 17 | public class HttpServer extends BaseServer { 18 | @Getter @Setter 19 | private BaseHttpResource httpResource; 20 | 21 | @Override 22 | public void broadcastMessageString(String msg) { 23 | // TODO Auto-generated method stub 24 | } 25 | 26 | 27 | 28 | @Override 29 | protected void initSocketChannel(SocketChannel ch) { 30 | super.initSocketChannel(ch); 31 | ch.pipeline().addLast(new HttpServerCodec()); 32 | ch.pipeline().addLast(new HttpObjectAggregator(65536)); 33 | ch.pipeline().addLast(new ChunkedWriteHandler()); 34 | 35 | HttpServerHandler httpServerHandler = new HttpServerHandler(this, httpResource); 36 | processHttpHandler(httpServerHandler); 37 | 38 | ch.pipeline().addLast("http", httpServerHandler); 39 | } 40 | 41 | 42 | protected void processHttpHandler(HttpServerHandler httpServerHandler) { 43 | 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /ext.opensource.netty-server-example/src/main/java/ext/opensource/netty/server/example/mqtt/kafka/KafkaSubribleLister.java: -------------------------------------------------------------------------------- 1 | 2 | package ext.opensource.netty.server.example.mqtt.kafka; 3 | 4 | 5 | import org.apache.kafka.clients.consumer.ConsumerRecord; 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.kafka.annotation.KafkaListener; 8 | import org.springframework.kafka.core.KafkaTemplate; 9 | import ext.opensource.netty.common.NettyLog; 10 | import ext.opensource.netty.server.example.mqtt.MqttServerRecvice; 11 | import lombok.Setter; 12 | 13 | /** 14 | * @author ben 15 | * @Title: basic 16 | * @Description: 17 | **/ 18 | 19 | public class KafkaSubribleLister { 20 | @Autowired 21 | private KafkaTemplate kafkaTemplate; 22 | 23 | @Setter 24 | private MqttServerRecvice serverRecvice; 25 | 26 | public void sendPublishMessage(String message) { 27 | NettyLog.info("internalSend: " + message); 28 | kafkaTemplate.send("mqtt-internal", message); 29 | } 30 | 31 | @KafkaListener(topics = {"mqtt-internal"}) 32 | public void consumer(ConsumerRecord consumerRecord) { 33 | String kafkaMessage = consumerRecord.value(); 34 | NettyLog.info("internalRecvice: " + kafkaMessage); 35 | 36 | if (kafkaMessage != null) { 37 | if (serverRecvice != null) { 38 | serverRecvice.processServerRecviceMesage(kafkaMessage); 39 | } 40 | } 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /ext.opensource.netty-client-example/src/main/java/ext/opensource/netty/client/example/redis/CacheListRedis.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.client.example.redis; 2 | 3 | 4 | import org.infrastructure.redis.IRedisHashService; 5 | import ext.opensource.netty.common.core.BaseCacheList; 6 | 7 | /** 8 | * @author ben 9 | * @Title: basic 10 | * @Description: 11 | **/ 12 | 13 | @SuppressWarnings("rawtypes") 14 | public class CacheListRedis extends BaseCacheList { 15 | private IRedisHashService redisService; 16 | 17 | @SuppressWarnings("unchecked") 18 | public CacheListRedis(String cacheName, IRedisHashService redisService) { 19 | super(cacheName); 20 | this.redisService = redisService; 21 | } 22 | 23 | @Override 24 | public boolean put(String key, V value) { 25 | return redisService.hSet(getCacheName(), key, value); 26 | } 27 | 28 | @Override 29 | public V get(String key) { 30 | return redisService.hGet(getCacheName(), key); 31 | } 32 | 33 | @Override 34 | public V remove(String key) { 35 | V value = get(key); 36 | redisService.hDel(getCacheName(), key); 37 | return value; 38 | } 39 | 40 | @Override 41 | public long size() { 42 | return redisService.hLen(getCacheName()); 43 | } 44 | 45 | @Override 46 | public boolean exists(String key) { 47 | return redisService.hExists(getCacheName(), key); 48 | } 49 | 50 | @Override 51 | public boolean containsKey(String key) { 52 | return exists(key); 53 | } 54 | } -------------------------------------------------------------------------------- /ext.opensource.netty-server-example/src/main/java/ext/opensource/netty/server/example/mqtt/redis/CacheListRedis.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.server.example.mqtt.redis; 2 | 3 | import org.infrastructure.redis.IRedisHashService; 4 | import ext.opensource.netty.common.core.BaseCacheList; 5 | 6 | /** 7 | * @author ben 8 | * @Title: basic 9 | * @Description: 10 | **/ 11 | 12 | @SuppressWarnings("rawtypes") 13 | public class CacheListRedis extends BaseCacheList { 14 | private IRedisHashService redisService; 15 | 16 | @SuppressWarnings("unchecked") 17 | public CacheListRedis(String cacheName, IRedisHashService redisService) { 18 | super(cacheName); 19 | this.redisService = redisService; 20 | } 21 | 22 | @Override 23 | public boolean put(String key, V value) { 24 | return redisService.hSet(getCacheName(), key, value); 25 | } 26 | 27 | @Override 28 | public V get(String key) { 29 | return redisService.hGet(getCacheName(), key); 30 | } 31 | 32 | @Override 33 | public V remove(String key) { 34 | V value = get(key); 35 | redisService.hDel(getCacheName(), key); 36 | return value; 37 | } 38 | 39 | @Override 40 | public long size() { 41 | return redisService.hLen(getCacheName()); 42 | } 43 | 44 | @Override 45 | public boolean exists(String key) { 46 | return redisService.hExists(getCacheName(), key); 47 | } 48 | 49 | @Override 50 | public boolean containsKey(String key) { 51 | return exists(key); 52 | } 53 | } -------------------------------------------------------------------------------- /ext.opensource.netty-common/src/main/java/ext/opensource/netty/common/HeartbeatServerHandler.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.common; 2 | 3 | import io.netty.channel.ChannelHandler; 4 | import io.netty.channel.ChannelHandlerContext; 5 | import io.netty.channel.ChannelInboundHandlerAdapter; 6 | import io.netty.handler.timeout.IdleState; 7 | import io.netty.handler.timeout.IdleStateEvent; 8 | 9 | /** 10 | * @author ben 11 | * @Title: basic 12 | * @Description: 13 | **/ 14 | 15 | @ChannelHandler.Sharable 16 | public class HeartbeatServerHandler extends ChannelInboundHandlerAdapter { 17 | //private static final Logger logger = LoggerFactory.getLogger(HeartbeatServerHandler.class); 18 | 19 | @Override 20 | public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { 21 | if (evt instanceof IdleStateEvent) { 22 | IdleStateEvent e = (IdleStateEvent) evt; 23 | if (e.state() == IdleState.WRITER_IDLE) { 24 | NettyLog.info("WRITER_IDLE"); 25 | } else if (e.state() == IdleState.READER_IDLE) { 26 | NettyLog.info("READER_IDLE"); 27 | //ctx.channel().close(); 28 | } else if (e.state() == IdleState.ALL_IDLE) { 29 | NettyLog.info("ALL_IDLE"); 30 | // 31 | ctx.close(); 32 | return ; 33 | } 34 | } 35 | super.userEventTriggered(ctx, evt); 36 | } 37 | 38 | 39 | } 40 | -------------------------------------------------------------------------------- /ext.opensource.netty-server-example/src/main/java/ext/opensource/netty/server/example/websocket/WebSocketEventChat.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.server.example.websocket; 2 | 3 | import java.util.Map; 4 | 5 | import ext.opensource.netty.server.core.BaseServer; 6 | import ext.opensource.netty.server.httpsocket.BaseWebSocketEvent; 7 | import ext.opensource.netty.server.httpsocket.WebSocketSession; 8 | 9 | import io.netty.buffer.ByteBuf; 10 | 11 | /** 12 | * @author ben 13 | * @Title: basic 14 | * @Description: 15 | **/ 16 | 17 | public class WebSocketEventChat extends BaseWebSocketEvent { 18 | @Override 19 | public void onMessageStringEvent(BaseServer sevice, WebSocketSession session, String msg) { 20 | String msgStr = msg + " < " + session.id().asShortText(); 21 | System.out.println("recv msg:" + msgStr); 22 | sevice.broadcastMessageString(msgStr); 23 | } 24 | 25 | @Override 26 | public void onMessageBinaryEvent(BaseServer sevice, WebSocketSession session, ByteBuf msg) { 27 | session.sendBinaryMessage(msg); 28 | } 29 | 30 | @Override 31 | public void onOpenEvent(BaseServer sevice, WebSocketSession session, Map parameter) { 32 | System.err.println("onOpenEvent parameter:" + parameter); 33 | sevice.broadcastMessageString("weclome " + session.channel().id().asShortText()); 34 | } 35 | 36 | @Override 37 | public void onCloseEvent(BaseServer sevice, WebSocketSession ctx) { 38 | System.err.println("close"); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /ext.opensource.netty-client/src/main/java/ext/opensource/netty/client/mqtt/api/MqttConsumerProcess.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.client.mqtt.api; 2 | 3 | import ext.opensource.netty.client.mqtt.common.MessageData; 4 | 5 | /** 6 | * @author ben 7 | * @Title: basic 8 | * @Description: 9 | **/ 10 | 11 | public interface MqttConsumerProcess extends MqttConsumer { 12 | /** 13 | * processSubAck 14 | * @param messageId 15 | */ 16 | void processSubAck(int messageId); 17 | 18 | /** 19 | * processUnSubBack 20 | * @param messageId 21 | */ 22 | void processUnSubBack(int messageId); 23 | 24 | /** 25 | * processPubRel 26 | * @param messageId 27 | */ 28 | void processPubRel(int messageId); 29 | 30 | /** 31 | * processPublish 32 | * @param recviceMessage 33 | */ 34 | void processPublish(MessageData recviceMessage); 35 | 36 | /** 37 | * sendPubRecMessage 38 | * @param messageId 39 | */ 40 | void sendPubRecMessage(int messageId); 41 | 42 | /** 43 | * sendPubAckMessage 44 | * @param messageId 45 | */ 46 | void sendPubAckMessage(int messageId); 47 | 48 | /** 49 | * sendPubCompMessage 50 | * @param messageId 51 | */ 52 | void sendPubCompMessage(int messageId); 53 | 54 | /** 55 | * saveMesage 56 | * @param recviceMessage 57 | */ 58 | void saveMesage(MessageData recviceMessage); 59 | 60 | /** 61 | * delMesage 62 | * @param messageId 63 | */ 64 | void delMesage(int messageId); 65 | } 66 | -------------------------------------------------------------------------------- /ext.opensource.netty-server/src/main/java/ext/opensource/netty/server/httpsocket/MapUrlParamsUtil.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.server.httpsocket; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | /** 7 | * @author ben 8 | * @Title: basic 9 | * @Description: 10 | **/ 11 | 12 | public class MapUrlParamsUtil { 13 | /** 14 | * 将url参数转换成map 15 | * 16 | * @param param 17 | * aa=11&bb=22&cc=33 18 | * @return 19 | */ 20 | public static Map getUrlParams(String param) { 21 | Map map = new HashMap(0); 22 | if ((param == null || param.trim().length() == 0)) { 23 | return map; 24 | } 25 | String[] params = param.split("&"); 26 | for (int i = 0; i < params.length; i++) { 27 | String[] p = params[i].split("="); 28 | if (p.length == 2) { 29 | map.put(p[0], p[1]); 30 | } 31 | } 32 | return map; 33 | } 34 | 35 | /** 36 | * 将map转换成url 37 | * 38 | * @param map 39 | * @return 40 | */ 41 | public static String getUrlParamsByMap(Map map) { 42 | if (map == null) { 43 | return ""; 44 | } 45 | String connectSymbol = "&"; 46 | 47 | StringBuffer sb = new StringBuffer(); 48 | for (Map.Entry entry : map.entrySet()) { 49 | sb.append(entry.getKey() + "=" + entry.getValue()); 50 | sb.append(connectSymbol); 51 | } 52 | String s = sb.toString(); 53 | if (s.endsWith(connectSymbol)) { 54 | s = s.substring(0, s.length() -1); 55 | } 56 | return s; 57 | } 58 | } -------------------------------------------------------------------------------- /ext.opensource.netty-server/src/main/java/ext/opensource/netty/server/httpsocket/WebSocketUtil.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.server.httpsocket; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import io.netty.channel.ChannelFuture; 5 | import io.netty.channel.ChannelHandlerContext; 6 | import io.netty.channel.ChannelPipeline; 7 | import io.netty.handler.codec.http.HttpHeaderNames; 8 | import io.netty.handler.codec.http.HttpRequest; 9 | import io.netty.handler.codec.http.websocketx.BinaryWebSocketFrame; 10 | import io.netty.handler.codec.http.websocketx.TextWebSocketFrame; 11 | import io.netty.handler.ssl.SslHandler; 12 | 13 | /** 14 | * @author ben 15 | * @Title: basic 16 | * @Description: 17 | **/ 18 | 19 | public class WebSocketUtil { 20 | public static ChannelFuture sendTextMessage(ChannelHandlerContext ctx, String msg) { 21 | return ctx.writeAndFlush(new TextWebSocketFrame(msg)); 22 | } 23 | public static ChannelFuture sendBinnaryMessage(ChannelHandlerContext ctx, ByteBuf msg){ 24 | return ctx.writeAndFlush(new BinaryWebSocketFrame(msg)); 25 | } 26 | 27 | public static String getWebSocketLocation(ChannelPipeline cp, HttpRequest req, String path) { 28 | return getWebSocketLocation(cp.get(SslHandler.class) != null, req, path); 29 | } 30 | 31 | public static String getWebSocketLocation(boolean bSSL, HttpRequest req, String path) { 32 | String protocol = "ws"; 33 | if (bSSL) { 34 | protocol = "wss"; 35 | } 36 | return protocol + "://" + req.headers().get(HttpHeaderNames.HOST) + path; 37 | } 38 | } 39 | 40 | -------------------------------------------------------------------------------- /ext.opensource.netty-client-example/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | ext.opensource 6 | netty 7 | 0.0.1-SNAPSHOT 8 | 9 | nettye-client-example 10 | nettye-client-example 11 | 12 | 13 | 2.7.0 14 | 15 | 16 | 17 | 18 | org.springframework.boot 19 | spring-boot-starter 20 | 21 | 22 | 23 | ext.opensource 24 | netty-client 25 | ${project.parent.version} 26 | 27 | 28 | 29 | org.apache.ignite 30 | ignite-core 31 | ${ignite.version} 32 | 33 | 34 | 35 | org.apache.ignite 36 | ignite-slf4j 37 | ${ignite.version} 38 | 39 | 40 | 41 | ext.opensource 42 | ext.opensource.redis 43 | ${project.parent.version} 44 | 45 | 46 | -------------------------------------------------------------------------------- /ext.opensource.netty-server/src/main/java/ext/opensource/netty/server/mqtt/api/ProcedureDataService.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.server.mqtt.api; 2 | 3 | import java.util.List; 4 | 5 | import ext.opensource.netty.common.core.CacheList; 6 | import ext.opensource.netty.server.mqtt.common.ProcedureMessage; 7 | import ext.opensource.netty.server.mqtt.protocol.data.ProcedureClientData; 8 | 9 | /** 10 | * @author ben 11 | * @Title: basic 12 | * @Description: 13 | **/ 14 | 15 | public interface ProcedureDataService { 16 | /** 17 | * custom set procedure cache 18 | * @param cacheList 19 | */ 20 | public void setProcedureCacheList(CacheList cacheList); 21 | 22 | /** 23 | * removeByClient 24 | * @param clientId 25 | */ 26 | public void removeByClient(String clientId); 27 | 28 | /** 29 | * getPubRelMessageForClient 30 | * @param clientId 31 | * @return 32 | */ 33 | public List getPubRelMessageForClient(String clientId); 34 | 35 | /** 36 | * getPubRelMessage 37 | * @param clientId 38 | * @param packId 39 | * @return 40 | */ 41 | public ProcedureMessage getPubRelMessage(String clientId, int packId); 42 | 43 | /** 44 | * removePubRelMessage 45 | * @param clientId 46 | * @param packId 47 | * @return 48 | */ 49 | public ProcedureMessage removePubRelMessage(String clientId, int packId); 50 | 51 | /** 52 | * putPubRelMessage 53 | * @param clientId 54 | * @param info 55 | */ 56 | public void putPubRelMessage(String clientId, ProcedureMessage info); 57 | } 58 | -------------------------------------------------------------------------------- /ext.opensource.redis/src/main/java/org/infrastructure/redis/core/GsonRedisSerializer.java: -------------------------------------------------------------------------------- 1 | package org.infrastructure.redis.core; 2 | 3 | import java.nio.charset.Charset; 4 | 5 | import org.springframework.data.redis.serializer.RedisSerializer; 6 | import org.springframework.data.redis.serializer.SerializationException; 7 | import org.springframework.util.Assert; 8 | import com.fasterxml.jackson.databind.ObjectMapper; 9 | 10 | /** 11 | * @author ben 12 | * @Title: basic 13 | * @Description: 14 | **/ 15 | public class GsonRedisSerializer implements RedisSerializer { 16 | private static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8"); 17 | 18 | @SuppressWarnings("unused") 19 | private ObjectMapper objectMapper = new ObjectMapper(); 20 | private Class clazz; 21 | 22 | public GsonRedisSerializer(Class clazz) { 23 | super(); 24 | this.clazz = clazz; 25 | } 26 | 27 | @Override 28 | public byte[] serialize(T t) throws SerializationException { 29 | if (t == null) { 30 | return new byte[0]; 31 | } 32 | return JosnRedisUtil.toJson(t).getBytes(DEFAULT_CHARSET); 33 | } 34 | 35 | @Override 36 | public T deserialize(byte[] bytes) throws SerializationException { 37 | if (bytes == null || bytes.length <= 0) { 38 | return null; 39 | } 40 | String str = new String(bytes, DEFAULT_CHARSET); 41 | 42 | return JosnRedisUtil.toBean(str, clazz); 43 | } 44 | 45 | public void setObjectMapper(ObjectMapper objectMapper) { 46 | Assert.notNull(objectMapper, "'objectMapper' must not be null"); 47 | this.objectMapper = objectMapper; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /ext.opensource.netty-server-example/src/main/java/ext/opensource/netty/server/example/scanner/Invoker.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.server.example.scanner; 2 | 3 | import java.lang.reflect.InvocationTargetException; 4 | import java.lang.reflect.Method; 5 | 6 | /** 7 | * @author ben 8 | * @Title: basic 9 | * @Description: 10 | **/ 11 | 12 | public class Invoker { 13 | 14 | /** 15 | * 方法 16 | */ 17 | private Method method; 18 | 19 | /** 20 | * 目标对象 21 | */ 22 | private Object target; 23 | 24 | public static Invoker valueOf(Method method, Object target){ 25 | Invoker invoker = new Invoker(); 26 | invoker.setMethod(method); 27 | invoker.setTarget(target); 28 | return invoker; 29 | } 30 | 31 | /** 32 | * 执行 33 | * @param paramValues 34 | * @return 35 | * @throws InvocationTargetException 36 | * @throws IllegalArgumentException 37 | * @throws IllegalAccessException 38 | */ 39 | public Object invoke(Object... paramValues){ 40 | try { 41 | return method.invoke(target, paramValues); 42 | } catch (IllegalAccessException e) { 43 | e.printStackTrace(); 44 | } catch (IllegalArgumentException e) { 45 | e.printStackTrace(); 46 | } catch (InvocationTargetException e) { 47 | e.printStackTrace(); 48 | } 49 | return null; 50 | } 51 | 52 | public Method getMethod() { 53 | return method; 54 | } 55 | 56 | public void setMethod(Method method) { 57 | this.method = method; 58 | } 59 | 60 | public Object getTarget() { 61 | return target; 62 | } 63 | 64 | public void setTarget(Object target) { 65 | this.target = target; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /ext.opensource.netty-server-example/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.profiles.active=dev 2 | spring.output.ansi.enabled=DETECT 3 | 4 | info.app.name=@project.name@ 5 | info.app.description=@project.description@ 6 | info.app.version=@project.version@ 7 | info.app.spring-boot-version=@project.parent.version@ 8 | info.app.build.ver=@build.ver@ 9 | 10 | #redis,ignite,local 11 | netty.server.cache=local 12 | #redis,ignite,kafka,none 13 | netty.server.interal.communicate=none 14 | 15 | #redis 16 | spring.redis.host=192.168.136.148 17 | spring.redis.port=6379 18 | spring.redis.database=0 19 | spring.redis.timeout=10000 20 | spring.redis.password= 21 | spring.redis.pool.maxActive=10 22 | spring.redis.pool.maxWait=100000 23 | spring.redis.pool.maxIdle=8 24 | spring.redis.pool.minIdle=0 25 | 26 | 27 | #kafka 28 | # \u6307\u5b9akafka \u4ee3\u7406\u5730\u5740\uff0c\u53ef\u4ee5\u591a\u4e2a 29 | spring.kafka.bootstrap-servers=192.168.136.148:9092 30 | 31 | #=============== provider ======================= 32 | spring.kafka.producer.retries=0 33 | # \u6bcf\u6b21\u6279\u91cf\u53d1\u9001\u6d88\u606f\u7684\u6570\u91cf 34 | spring.kafka.producer.batch-size=16384 35 | spring.kafka.producer.buffer-memory=33554432 36 | spring.kafka.producer.acks=all 37 | spring.kafka.producer.retries=0 38 | spring.kafka.producer.linger.ms=1 39 | 40 | #=============== consumer ======================= 41 | # \u6307\u5b9a\u9ed8\u8ba4\u6d88\u8d39\u8005group id 42 | spring.kafka.consumer.group-id= 43 | spring.kafka.consumer.enable-auto-commit=true 44 | spring.kafka.consumer.auto-commit-interval=100 45 | spring.kafka.consumer.session.timeout.ms=1500 46 | 47 | -------------------------------------------------------------------------------- /ext.opensource.netty-server/src/main/java/ext/opensource/netty/server/mqtt/api/MqttSessionService.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.server.mqtt.api; 2 | 3 | import ext.opensource.netty.common.core.CacheList; 4 | import ext.opensource.netty.server.mqtt.MqttSession; 5 | import io.netty.handler.codec.mqtt.MqttPublishMessage; 6 | 7 | /** 8 | * @author ben 9 | * @Title: basic 10 | * @Description: 11 | **/ 12 | 13 | 14 | public interface MqttSessionService { 15 | /** 16 | * 会话远端缓存 17 | * @param cacheList 18 | */ 19 | void setRemoteSessionCache(CacheList cacheList); 20 | 21 | /** 22 | * 存储会话 23 | * @param clientId 24 | * @param sessionStore 25 | */ 26 | void put(String clientId, MqttSession sessionStore); 27 | 28 | /** 29 | * 获取会话 30 | * @param clientId 31 | * @return 32 | */ 33 | MqttSession getSession(String clientId); 34 | 35 | /** 36 | * clientId的会话是否存在 37 | * @param clientId 38 | * @return 39 | */ 40 | boolean containsKey(String clientId); 41 | 42 | /** 43 | * 删除会话 44 | * @param clientId 45 | */ 46 | void remove(String clientId); 47 | 48 | /** 49 | * writeAndFlush 50 | * @param clientId 51 | * @param obj 52 | */ 53 | void writeAndFlush(String clientId, Object obj); 54 | 55 | /** 56 | * isCleanSession 57 | * @param clientId 58 | * @return 59 | */ 60 | boolean isCleanSession(String clientId); 61 | 62 | /** 63 | * closeSession 64 | * @param clientId 65 | */ 66 | void closeSession(String clientId); 67 | 68 | /** 69 | * getWillMessage 70 | * @param clientId 71 | * @return 72 | */ 73 | MqttPublishMessage getWillMessage(String clientId); 74 | } 75 | -------------------------------------------------------------------------------- /ext.opensource.netty-server/src/main/java/ext/opensource/netty/server/mqtt/protocol/data/BaseDataInMap.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.server.mqtt.protocol.data; 2 | 3 | import java.io.Serializable; 4 | import java.util.Collection; 5 | import java.util.Map; 6 | import java.util.Set; 7 | import java.util.concurrent.ConcurrentHashMap; 8 | import java.util.function.BiConsumer; 9 | 10 | /** 11 | * @author ben 12 | * @Title: basic 13 | * @Description: 14 | **/ 15 | 16 | public class BaseDataInMap implements Serializable { 17 | private static final long serialVersionUID = 1L; 18 | 19 | private String name; 20 | private ConcurrentHashMap map= new ConcurrentHashMap(); 21 | 22 | public BaseDataInMap() { 23 | } 24 | public BaseDataInMap(String name) { 25 | this.name = name; 26 | } 27 | 28 | public String getName() { 29 | return name; 30 | } 31 | 32 | public void put(K key, V value) { 33 | map.put(key, value); 34 | } 35 | 36 | public V get(K key) { 37 | return map.get(key); 38 | } 39 | 40 | public boolean containsKey(K key) { 41 | return map.containsKey(key); 42 | } 43 | 44 | public void remove(K key) { 45 | map.remove(key); 46 | } 47 | 48 | public long size() { 49 | return map.size(); 50 | } 51 | 52 | public Collection values() { 53 | return map.values(); 54 | } 55 | 56 | public Collection keys() { 57 | return map.keySet(); 58 | } 59 | 60 | public Set> entrySet() { 61 | return map.entrySet(); 62 | } 63 | 64 | public void clear() { 65 | map.clear(); 66 | } 67 | 68 | public void forEach(BiConsumer action) { 69 | map.forEach(action); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /ext.opensource.netty-client-example/src/main/java/ext/opensource/netty/client/example/ignite/CacheListIgnite.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.client.example.ignite; 2 | 3 | import org.apache.ignite.Ignite; 4 | import org.apache.ignite.IgniteCache; 5 | import org.apache.ignite.cache.CacheMode; 6 | import org.apache.ignite.configuration.CacheConfiguration; 7 | import ext.opensource.netty.common.core.BaseCacheList; 8 | 9 | /** 10 | * @author ben 11 | * @Title: basic 12 | * @Description: 13 | **/ 14 | 15 | public class CacheListIgnite extends BaseCacheList { 16 | private IgniteCache msgList; 17 | 18 | public void setMsgList(IgniteCache msgList) { 19 | } 20 | 21 | public CacheListIgnite(String cacheName, Ignite ignite) { 22 | super(cacheName); 23 | CacheConfiguration cacheConfiguration = new CacheConfiguration(); 24 | cacheConfiguration.setDataRegionName("persistence-data-region").setCacheMode(CacheMode.LOCAL) 25 | .setName(getCacheName()); 26 | this.msgList = (IgniteCache) ignite.getOrCreateCache(cacheConfiguration); 27 | } 28 | 29 | @Override 30 | public boolean put(String key, T value) { 31 | msgList.put(key, value); 32 | return true; 33 | } 34 | 35 | @Override 36 | public T get(String key) { 37 | if (msgList.containsKey(key)) { 38 | return msgList.get(key); 39 | } else { 40 | return null; 41 | } 42 | } 43 | 44 | @Override 45 | public T remove(String key) { 46 | return msgList.getAndRemove(key); 47 | } 48 | 49 | @Override 50 | public long size() { 51 | return msgList.size(); 52 | } 53 | 54 | @Override 55 | public boolean exists(String key) { 56 | return msgList.containsKey(key); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /ext.opensource.redis/src/main/java/org/infrastructure/redis/IRedisHashService.java: -------------------------------------------------------------------------------- 1 | package org.infrastructure.redis; 2 | 3 | /** 4 | * @author ben 5 | * @Title: basic 6 | * @Description: 7 | **/ 8 | public interface IRedisHashService { 9 | 10 | /** 11 | * setValueClass 12 | * @param clz 13 | */ 14 | public void setValueClass(Class clz); 15 | 16 | 17 | /** 18 | * hSet 19 | * @param key 20 | * @param field 21 | * @param obj 22 | * @return 23 | */ 24 | public Boolean hSet(final String key, final String field, V obj); 25 | 26 | /** 27 | * hGet 28 | * @param key 29 | * @param field 30 | * @return 31 | */ 32 | public V hGet(final String key, final String field); 33 | 34 | /** 35 | * hDel 36 | * @param key 37 | * @param field 38 | */ 39 | public void hDel(final String key, final String field); 40 | 41 | /** 42 | * hExists 43 | * @param key 44 | * @param field 45 | * @return 46 | */ 47 | public boolean hExists(final String key, final String field); 48 | 49 | /** 50 | * hLen 51 | * @param key 52 | * @return 53 | */ 54 | public long hLen(final String key); 55 | 56 | /** 57 | * hIncrBy 58 | * @param key 59 | * @param field 60 | * @param number 61 | * @return 62 | */ 63 | public long hIncrBy(final String key, final String field, final long number); 64 | 65 | /** 66 | * incr 67 | * @param key 68 | * @return 69 | */ 70 | public long incr(final String key); 71 | 72 | /** 73 | * delKey 74 | * @param key 75 | * @return 76 | */ 77 | public boolean delKey(final String key); 78 | } 79 | -------------------------------------------------------------------------------- /ext.opensource.netty-client-example/src/main/java/ext/opensource/netty/client/example/mqtt/CustomMqttClientIgnite.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.client.example.mqtt; 2 | 3 | import javax.annotation.Resource; 4 | 5 | import org.apache.ignite.Ignite; 6 | 7 | import ext.opensource.netty.client.example.ignite.CacheListIgnite; 8 | import ext.opensource.netty.client.mqtt.MqttClient; 9 | import ext.opensource.netty.client.mqtt.common.DefautMqttConsumerListener; 10 | import ext.opensource.netty.client.mqtt.common.MessageData; 11 | import ext.opensource.netty.common.core.CacheList; 12 | import ext.opensource.netty.common.core.UniqueIdInteger; 13 | 14 | /** 15 | * @author ben 16 | * @Title: basic 17 | * @Description: 18 | **/ 19 | 20 | public class CustomMqttClientIgnite extends CustomMqttClient { 21 | @Resource 22 | private Ignite ignite; 23 | 24 | @Override 25 | public void init(MqttClient nettyClient) { 26 | super.init(nettyClient); 27 | 28 | String clientId = nettyClient.mqttOptions().getClientIdentifier(); 29 | 30 | CacheList consumerCache = new CacheListIgnite( 31 | "mqttclient-consumer-" + clientId, ignite); 32 | CacheList procedureCache = new CacheListIgnite( 33 | "mqttclient-procedure-" + clientId, ignite); 34 | 35 | CacheList idCache = new CacheListIgnite( 36 | "mqttclient-gid-" + clientId, ignite); 37 | 38 | nettyClient.consumer().setGlobalUniqueIdCache(idCache); 39 | nettyClient.consumer().setCacheList(consumerCache); 40 | nettyClient.consumer().setConsumerListener(new DefautMqttConsumerListener()); 41 | nettyClient.producer().setGlobalUniqueIdCache(idCache); 42 | nettyClient.producer().setCacheList(procedureCache); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /ext.opensource.netty-server/src/main/java/ext/opensource/netty/server/httpsocket/BaseHttpResource.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.server.httpsocket; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | import io.netty.buffer.ByteBuf; 6 | import io.netty.handler.codec.http.HttpRequest; 7 | import lombok.Getter; 8 | import lombok.NonNull; 9 | import lombok.Setter; 10 | 11 | /** 12 | * @author ben 13 | * @Title: basic 14 | * @Description: 15 | **/ 16 | 17 | public abstract class BaseHttpResource { 18 | private static String STR_SLASH = "/"; 19 | 20 | @Getter 21 | @Setter 22 | @NonNull 23 | private String rootDir = ""; 24 | 25 | @Getter 26 | @Setter 27 | @NonNull 28 | private String defaultIndexName; 29 | 30 | @Getter 31 | @Setter 32 | private HttpResourceProcess httpResourceProcess; 33 | 34 | /** 35 | * buildRes 36 | * @param resPath 37 | * @param parameters 38 | * @return 39 | */ 40 | protected abstract ByteBuf buildRes(String resPath, 41 | Map parameters); 42 | 43 | public ByteBuf buildWebSocketRes(String filename, 44 | Map parameters) { 45 | if (STR_SLASH.equals(filename)) { 46 | return buildRes( defaultIndexName, parameters); 47 | } else { 48 | return buildRes(filename, parameters); 49 | } 50 | } 51 | 52 | public ByteBuf buildWebSocketRes(HttpRequest req, String filename) { 53 | String reqFileName = filename; 54 | if (STR_SLASH.equals(filename)) { 55 | reqFileName = defaultIndexName; 56 | } 57 | 58 | Map reqParameter = new HashMap(16); 59 | if (httpResourceProcess != null) { 60 | httpResourceProcess.porcessResPath(req, reqFileName, reqParameter); 61 | } 62 | 63 | return buildRes(reqFileName, reqParameter); 64 | } 65 | 66 | } 67 | -------------------------------------------------------------------------------- /ext.opensource.netty-client-example/src/main/java/ext/opensource/netty/client/example/listen/SpringBeanUtil.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.client.example.listen; 2 | 3 | import org.springframework.beans.BeansException; 4 | import org.springframework.context.ApplicationContext; 5 | import org.springframework.context.ApplicationContextAware; 6 | import org.springframework.stereotype.Component; 7 | 8 | /** 9 | * @author ben 10 | * @Title: basic 11 | * @Description: 12 | **/ 13 | 14 | @Component 15 | public class SpringBeanUtil implements ApplicationContextAware { 16 | private static ApplicationContext applicationContext; 17 | 18 | @Override 19 | public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { 20 | System.err.println("SpringBeanUtil"); 21 | SpringBeanUtil.applicationContext = applicationContext; 22 | } 23 | 24 | /** 25 | * 获取applicationContext 26 | * @return 27 | */ 28 | public static ApplicationContext getApplicationContext() { 29 | return applicationContext; 30 | } 31 | 32 | /** 33 | * 通过name获取 Bean. 34 | * @param name 35 | * @return 36 | */ 37 | public static Object getBean(String name){ 38 | return getApplicationContext().getBean(name); 39 | } 40 | 41 | /** 42 | * 通过class获取Bean. 43 | * @param clazz 44 | * @return 45 | */ 46 | public static T getBean(Class clazz){ 47 | try { 48 | return getApplicationContext().getBean(clazz); 49 | } catch (Exception ex) { 50 | return null; 51 | } 52 | } 53 | 54 | /** 55 | * 通过name,以及Clazz返回指定的Bean 56 | * @param name 57 | * @param clazz 58 | * @return 59 | */ 60 | public static T getBean(String name,Class clazz){ 61 | return getApplicationContext().getBean(name, clazz); 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /ext.opensource.netty-server/src/main/java/ext/opensource/netty/server/mqtt/MqttWebSocketServer.java: -------------------------------------------------------------------------------- 1 | 2 | package ext.opensource.netty.server.mqtt; 3 | 4 | import ext.opensource.netty.server.httpsocket.BaseHttpResource; 5 | import ext.opensource.netty.server.httpsocket.HttpResourceHander; 6 | 7 | import io.netty.channel.socket.SocketChannel; 8 | import io.netty.handler.codec.http.HttpContentCompressor; 9 | import io.netty.handler.codec.http.HttpObjectAggregator; 10 | import io.netty.handler.codec.http.HttpServerCodec; 11 | import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler; 12 | import io.netty.handler.stream.ChunkedWriteHandler; 13 | import lombok.Getter; 14 | import lombok.Setter; 15 | 16 | /** 17 | * @author ben 18 | * @Title: basic 19 | * @Description: 20 | **/ 21 | 22 | public class MqttWebSocketServer extends MqttServer { 23 | @Getter @Setter 24 | private BaseHttpResource httpResource; 25 | @Setter 26 | private String websocketPath; 27 | 28 | @Override 29 | protected void initSocketChannel(SocketChannel ch) { 30 | super.initSocketChannel(ch); 31 | ch.pipeline().addBefore(HANDLER_MQTTDECODER, "HttpServerCodec", new HttpServerCodec()); 32 | ch.pipeline().addBefore(HANDLER_MQTTDECODER, "HttpObjectAggregator", new HttpObjectAggregator(65536)); 33 | ch.pipeline().addBefore(HANDLER_MQTTDECODER, "ChunkedWriteHandler", new ChunkedWriteHandler()); 34 | ch.pipeline().addBefore(HANDLER_MQTTDECODER, "compressor ", new HttpContentCompressor()); 35 | ch.pipeline().addBefore(HANDLER_MQTTDECODER, "protocol", new WebSocketServerProtocolHandler(websocketPath, "mqtt,mqttv3.1,mqttv3.1.1", true, 65536)); 36 | ch.pipeline().addBefore(HANDLER_MQTTDECODER, "mqttWebSocket", new MqttWebSocketCodec()); 37 | 38 | HttpResourceHander httpResourceHander = new HttpResourceHander(httpResource); 39 | ch.pipeline().addLast("httpResource", httpResourceHander); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /ext.opensource.netty-server-example/src/main/java/ext/opensource/netty/server/example/listen/SpringBeanUtil.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.server.example.listen; 2 | 3 | import org.springframework.beans.BeansException; 4 | import org.springframework.context.ApplicationContext; 5 | import org.springframework.context.ApplicationContextAware; 6 | import org.springframework.stereotype.Component; 7 | 8 | /** 9 | * @author ben 10 | * @Title: basic 11 | * @Description: 12 | **/ 13 | 14 | @Component 15 | public class SpringBeanUtil implements ApplicationContextAware { 16 | private static ApplicationContext applicationContext; 17 | 18 | 19 | @Override 20 | public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { 21 | System.err.println("SpringBeanUtil"); 22 | SpringBeanUtil.applicationContext = applicationContext; 23 | } 24 | 25 | /** 26 | * 获取applicationContext 27 | * @return 28 | */ 29 | public static ApplicationContext getApplicationContext() { 30 | return applicationContext; 31 | } 32 | 33 | /** 34 | * 通过name获取 Bean. 35 | * @param name 36 | * @return 37 | */ 38 | public static Object getBean(String name){ 39 | return getApplicationContext().getBean(name); 40 | } 41 | 42 | /** 43 | * 通过class获取Bean. 44 | * @param clazz 45 | * @return 46 | */ 47 | public static T getBean(Class clazz){ 48 | try { 49 | return getApplicationContext().getBean(clazz); 50 | } catch (Exception ex) { 51 | return null; 52 | } 53 | } 54 | 55 | /** 56 | * 通过name,以及Clazz返回指定的Bean 57 | * @param name 58 | * @param clazz 59 | * @return 60 | */ 61 | public static T getBean(String name,Class clazz){ 62 | return getApplicationContext().getBean(name, clazz); 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /ext.opensource.netty-common/src/main/java/ext/opensource/netty/common/LogDispatchHandler.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.common; 2 | 3 | import ext.opensource.netty.common.NettyLog; 4 | import io.netty.channel.ChannelHandlerContext; 5 | import io.netty.channel.ChannelInboundHandlerAdapter; 6 | 7 | /** 8 | * @author ben 9 | * @Title: basic 10 | * @Description: 11 | **/ 12 | 13 | public class LogDispatchHandler extends ChannelInboundHandlerAdapter { 14 | 15 | @Override 16 | public void channelRegistered(ChannelHandlerContext ctx) throws Exception { 17 | NettyLog.info(String.format("Registered id:%s", ctx.channel().id().asLongText())); 18 | super.channelRegistered(ctx); 19 | } 20 | 21 | 22 | @Override 23 | public void channelUnregistered(ChannelHandlerContext ctx) throws Exception { 24 | NettyLog.info(String.format("UnRegistered id:%s", ctx.channel().id().asLongText())); 25 | super.channelUnregistered(ctx); 26 | } 27 | 28 | @Override 29 | public void channelActive(ChannelHandlerContext ctx) throws Exception { 30 | NettyLog.info(String.format("Active id:%s", ctx.channel().id().asLongText())); 31 | super.channelActive(ctx); 32 | } 33 | 34 | @Override 35 | public void channelInactive(ChannelHandlerContext ctx) throws Exception { 36 | NettyLog.info(String.format("Inactive id:%s", ctx.channel().id().asLongText())); 37 | super.channelInactive(ctx); 38 | } 39 | 40 | @Override 41 | public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { 42 | NettyLog.info(String.format("Read id:%s", ctx.channel().id().asLongText())); 43 | super.channelRead(ctx, msg); 44 | } 45 | 46 | @Override 47 | public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { 48 | NettyLog.info(String.format("exceptionCaught id:%s", ctx.channel().id().asLongText())); 49 | super.exceptionCaught(ctx, cause); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /ext.opensource.netty-client/src/main/java/ext/opensource/netty/client/mqtt/api/ClientProcess.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.client.mqtt.api; 2 | 3 | import java.nio.charset.Charset; 4 | 5 | import ext.opensource.netty.client.core.BaseClient; 6 | import ext.opensource.netty.common.NettyUtil; 7 | import ext.opensource.netty.common.api.GlobalUniqueId; 8 | import ext.opensource.netty.common.api.GlobalUniqueIdImpl; 9 | import ext.opensource.netty.common.api.GlobalUniqueIdSet; 10 | import ext.opensource.netty.common.core.CacheList; 11 | import ext.opensource.netty.common.core.UniqueIdInteger; 12 | 13 | import io.netty.channel.Channel; 14 | 15 | /** 16 | * @author ben 17 | * @Title: basic 18 | * @Description: 19 | **/ 20 | 21 | public class ClientProcess implements GlobalUniqueIdSet { 22 | private BaseClient client; 23 | private GlobalUniqueId globalUniqueId; 24 | 25 | public ClientProcess(BaseClient client) { 26 | globalUniqueId = new GlobalUniqueIdImpl(); 27 | this.client = client; 28 | } 29 | 30 | @Override 31 | public void setGlobalUniqueId(GlobalUniqueId globalUniqueId) { 32 | if (globalUniqueId != null) { 33 | this.globalUniqueId = globalUniqueId; 34 | } 35 | } 36 | @Override 37 | public void setGlobalUniqueIdCache(CacheList cacheList) { 38 | globalUniqueId.setCacheList(cacheList); 39 | } 40 | 41 | protected String getClientId() { 42 | return NettyUtil.getClientId(client.getChannel()); 43 | } 44 | 45 | public Channel channel() { 46 | return client.getChannel(); 47 | } 48 | 49 | public GlobalUniqueId messageId() { 50 | return globalUniqueId; 51 | } 52 | 53 | public byte[] encoded(String data) { 54 | if (data == null) { 55 | return null; 56 | } 57 | return data.getBytes(Charset.forName(this.client.getCharsetName())); 58 | } 59 | 60 | public String decode(byte[] data) { 61 | return new String(data, Charset.forName(this.client.getCharsetName())); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /ext.opensource.netty-server-example/src/main/java/ext/opensource/netty/server/example/mqtt/redis/config/RedisSubListenerConfig.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.server.example.mqtt.redis.config; 2 | 3 | import java.util.concurrent.CountDownLatch; 4 | 5 | import org.springframework.context.annotation.Bean; 6 | import org.springframework.context.annotation.Conditional; 7 | import org.springframework.context.annotation.Configuration; 8 | import org.springframework.data.redis.connection.RedisConnectionFactory; 9 | import org.springframework.data.redis.core.StringRedisTemplate; 10 | import org.springframework.data.redis.listener.PatternTopic; 11 | import org.springframework.data.redis.listener.RedisMessageListenerContainer; 12 | import org.springframework.data.redis.listener.adapter.MessageListenerAdapter; 13 | 14 | /** 15 | * @author ben 16 | * @Title: basic 17 | * @Description: 18 | **/ 19 | 20 | @Configuration 21 | public class RedisSubListenerConfig { 22 | public static final String MQTT_TOPIC_NAME="mqtt-index"; 23 | @Bean 24 | @Conditional(RedisConditionalCommunicate.class) 25 | RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory, 26 | MessageListenerAdapter listenerAdapter) { 27 | RedisMessageListenerContainer container = new RedisMessageListenerContainer(); 28 | container.setConnectionFactory(connectionFactory); 29 | container.addMessageListener(listenerAdapter, new PatternTopic(MQTT_TOPIC_NAME)); 30 | return container; 31 | } 32 | 33 | @Bean 34 | MessageListenerAdapter listenerAdapter(RedisSubribleLister redisSubribleLister) { 35 | return new MessageListenerAdapter(redisSubribleLister, "receiveMessage"); 36 | } 37 | 38 | @Bean 39 | CountDownLatch latch() { 40 | return new CountDownLatch(1); 41 | } 42 | 43 | @Bean("name=sendRedisTemplate") 44 | StringRedisTemplate template(RedisConnectionFactory connectionFactory) { 45 | return new StringRedisTemplate(connectionFactory); 46 | } 47 | 48 | } -------------------------------------------------------------------------------- /ext.opensource.netty-common/src/main/java/ext/opensource/netty/common/ChannelManagerHandler.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.common; 2 | 3 | import io.netty.channel.ChannelHandlerContext; 4 | import io.netty.channel.ChannelInboundHandlerAdapter; 5 | 6 | /** 7 | * @author ben 8 | * @Title: basic 9 | * @Description: 10 | **/ 11 | 12 | public class ChannelManagerHandler extends ChannelInboundHandlerAdapter { 13 | protected ChannelManager clientManager; 14 | 15 | protected ChannelManagerHandler() { 16 | } 17 | 18 | public ChannelManagerHandler(ChannelManager clientManager) { 19 | this.clientManager = clientManager; 20 | if (null == this.clientManager) { 21 | throw new RuntimeException("clientManager is null"); 22 | } 23 | } 24 | 25 | @Override 26 | public void channelRegistered(ChannelHandlerContext ctx) throws Exception { 27 | super.channelRegistered(ctx); 28 | } 29 | 30 | @Override 31 | public void channelUnregistered(ChannelHandlerContext ctx) throws Exception { 32 | super.channelUnregistered(ctx); 33 | } 34 | 35 | @Override 36 | public void channelActive(ChannelHandlerContext ctx) throws Exception { 37 | super.channelActive(ctx); 38 | 39 | ///System.out.println("channelActivexx: " + ctx.channel().id().asShortText()); 40 | 41 | if (this.clientManager != null) { 42 | clientManager.addChannel(ctx.channel()); 43 | } 44 | } 45 | 46 | @Override 47 | public void channelInactive(ChannelHandlerContext ctx) throws Exception { 48 | super.channelInactive(ctx); 49 | 50 | ///System.out.println("channelInactive: " + ctx.channel().id().asShortText()); 51 | 52 | if (this.clientManager != null) { 53 | clientManager.removeChannel(ctx.channel()); 54 | } 55 | 56 | } 57 | 58 | @Override 59 | public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { 60 | if (this.clientManager != null) { 61 | clientManager.addReceiveCount(); 62 | } 63 | super.channelRead(ctx, msg); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /ext.opensource.netty-server/src/main/java/ext/opensource/netty/server/mqtt/api/TopicService.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.server.mqtt.api; 2 | 3 | import java.util.List; 4 | 5 | import ext.opensource.netty.common.core.CacheList; 6 | import ext.opensource.netty.server.mqtt.common.RetainMessage; 7 | import ext.opensource.netty.server.mqtt.common.SubscribeTopicInfo; 8 | import ext.opensource.netty.server.mqtt.protocol.data.ClientTopic; 9 | import ext.opensource.netty.server.mqtt.protocol.data.TopicData; 10 | 11 | /** 12 | * @author ben 13 | * @Title: basic 14 | * @Description: 15 | **/ 16 | 17 | 18 | public interface TopicService { 19 | 20 | /** 21 | * 自定义主题缓存 22 | * @param cacheList 23 | */ 24 | void setTopicList(CacheList cacheList); 25 | 26 | /** 27 | * 自定义用户主题缓存 28 | * @param cacheList 29 | */ 30 | void setClientTopicList(CacheList cacheList); 31 | 32 | 33 | /** 34 | * 存储订阅 35 | * @param topicFilter 36 | * @param subscribeStore 37 | * @return 38 | */ 39 | boolean put(String topicFilter, SubscribeTopicInfo subscribeStore); 40 | 41 | /** 42 | * 删除订阅 43 | * @param topicFilter 44 | * @param clientId 45 | */ 46 | void remove(String topicFilter, String clientId); 47 | 48 | /** 49 | * 删除clientId的订阅 50 | * @param clientId 51 | */ 52 | void removeForClient(String clientId); 53 | 54 | /** 55 | * 获取订阅集 56 | * @param topic 57 | * @return 58 | */ 59 | List search(String topic); 60 | 61 | 62 | /** 63 | * putRetainMessage 64 | * @param topic 65 | * @param retainMessageInfo 66 | */ 67 | void putRetainMessage(String topic, RetainMessage retainMessageInfo); 68 | 69 | /** 70 | * delete retain message 71 | * @param topic 72 | */ 73 | void removeRetainMessage(String topic); 74 | 75 | /** 76 | * search retain message 77 | * @param topicFilter 78 | * @return 79 | */ 80 | List searchRetainMessage(String topicFilter); 81 | } 82 | -------------------------------------------------------------------------------- /ext.opensource.netty-server-example/src/main/java/ext/opensource/netty/server/example/listen/ContextRefreshedListener.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.server.example.listen; 2 | 3 | import java.lang.annotation.Annotation; 4 | import java.util.HashMap; 5 | import java.util.Map; 6 | 7 | import org.springframework.context.ApplicationListener; 8 | import org.springframework.context.event.ContextRefreshedEvent; 9 | import org.springframework.stereotype.Component; 10 | 11 | import ext.opensource.netty.server.example.simple.BizDispatchCollect; 12 | import ext.opensource.netty.server.example.simple.SocketCmd; 13 | 14 | /** 15 | * @author ben 16 | * @Title: basic 17 | * @Description: 18 | **/ 19 | 20 | @Component 21 | public class ContextRefreshedListener implements ApplicationListener { 22 | 23 | @Override 24 | public void onApplicationEvent(ContextRefreshedEvent event) { 25 | System.err.println("refresh"); 26 | 27 | Map map = new HashMap<>(16); 28 | Map bizMap = event.getApplicationContext().getBeansWithAnnotation(SocketCmd.class); 29 | for (Map.Entry entry : bizMap.entrySet()) { 30 | Object object = entry.getValue(); 31 | Class c = object.getClass(); 32 | Annotation[] annotations = c.getDeclaredAnnotations(); 33 | 34 | for (Annotation annotation : annotations) { 35 | if (annotation.annotationType().equals(SocketCmd.class)) { 36 | SocketCmd cmdOrder = (SocketCmd) annotation; 37 | if (!map.containsKey(cmdOrder.value())) { 38 | map.put(cmdOrder.value(), object); 39 | } else { 40 | System.err.println(String.format("Mult cmdOrder:%s className: %s", cmdOrder.value(), c)); 41 | } 42 | } 43 | } 44 | } 45 | 46 | BizDispatchCollect.setCourses(map); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # 项目介绍 2 | 3 | 基于Netty框架,提供对MQTT、WebSocket等协议的服务端与客户端的封装 (易伸缩、易扩展) 4 | 5 | * MQTT服务器 (核心实现、可扩展消息存储、可集群、可处理消息) 6 | * MQTT客户端 (核心实现、可扩展消息存储) 7 | * WebSocket服务器 (核心实现、可处理消息) 8 | * WebSocket客户端 (核心实现) 9 | 10 | # 项目结构 11 | ``` 12 | ext-opensource-netty 13 | ├── ext.opensource.redis -- redis公用 14 | ├── netty-client -- MQTT客户端 、WebSocket客户端等核心实现 15 | ├── netty-client-example -- MQTT客户端 、Websocket客户端等扩展用例 16 | ├── netty-common -- 公共类及其它 17 | ├── netty-server -- MQTT服务器 、Websocket服务器等核心实现 18 | ├── netty-server-example -- MQTT服务器 、Websocket服务器扩展用例 19 | ``` 20 | 21 | # 开发规范 22 | * IDE: Eclipse + Lombok + JDK1.8 + Maven 23 | * 应用技术: netty、 spring boot、 redis、 ignite、 kafka. 24 | * 代码质量: Spotbugs 25 | * 代码规范: 阿里代码插件 26 | 27 | # 开发配置 28 | * 源码格式要求,导入standard目录下的代码格式文件至IDE中. 29 | eclipse添加自定义用户名: 在eclipse.ini 中 -vmargs下面 30 | 添加一行 -Duser.name=您的名字 31 | * 代码简化插件: Lombok 32 | * 1. 将maven本地包对应的lombok.jar 复制到 eclipse.ini 所在的文件夹目录下 33 | * 2. 打开 eclipse.ini ,在最后面插入以下两行并保存. 34 | -Xbootclasspath/a:lombok.jar 35 | -javaagent:lombok.jar 36 | * 3.重启 eclipse 37 | 38 | # Socket通信 39 | * 数据粘包 40 | * 数据拆包 41 | * 数据验证 42 | * 数据安全 43 | * 数据序列化 44 | * 鉴权 45 | * 心跳 46 | * 重连 47 | 48 | # Todo List 49 | * MQTT监控 50 | * MQTT管理 51 | * 订阅通配符支持 52 | 53 | 54 | # 参考资料 55 | * Netty实战 (诺曼-毛瑞尔) 56 | * Netty权威指南 57 | * mqtt协议(英文): 58 | * mqtt协议(中文): 59 | * mqtt压测: 60 | * mqtt流程: 61 | * mqtt官网: 62 | * paho开源: 63 | * iot-mqtt-server: 64 | * iot-push: 65 | 66 | 67 | link: 68 | weixin: chinaxjc208 69 | -------------------------------------------------------------------------------- /ext.opensource.netty-server/src/main/java/ext/opensource/netty/server/mqtt/MqttSession.java: -------------------------------------------------------------------------------- 1 | 2 | package ext.opensource.netty.server.mqtt; 3 | 4 | import io.netty.buffer.ByteBuf; 5 | import io.netty.channel.Channel; 6 | import io.netty.channel.ChannelFuture; 7 | import io.netty.handler.codec.mqtt.MqttPublishMessage; 8 | import java.io.Serializable; 9 | 10 | import ext.opensource.netty.common.BaseSocketSession; 11 | import ext.opensource.netty.common.exception.MethodNotSupportException; 12 | 13 | /** 14 | * @author ben 15 | * @Title: basic 16 | * @Description: 17 | **/ 18 | 19 | public class MqttSession extends BaseSocketSession implements Serializable { 20 | private static final long serialVersionUID = 1L; 21 | private String clientId; 22 | private boolean cleanSession; 23 | private transient MqttPublishMessage willMessage; 24 | 25 | public MqttSession(String clientId, Channel channel, boolean cleanSession, MqttPublishMessage willMessage) { 26 | super(channel); 27 | 28 | this.clientId = clientId; 29 | this.cleanSession = cleanSession; 30 | this.willMessage = willMessage; 31 | } 32 | 33 | public String getClientId() { 34 | return clientId; 35 | } 36 | 37 | public MqttSession setClientId(String clientId) { 38 | this.clientId = clientId; 39 | return this; 40 | } 41 | 42 | public boolean isCleanSession() { 43 | return cleanSession; 44 | } 45 | 46 | public MqttSession setCleanSession(boolean cleanSession) { 47 | this.cleanSession = cleanSession; 48 | return this; 49 | } 50 | 51 | public MqttPublishMessage getWillMessage() { 52 | return willMessage; 53 | } 54 | 55 | public MqttSession setWillMessage(MqttPublishMessage willMessage) { 56 | this.willMessage = willMessage; 57 | return this; 58 | } 59 | 60 | @Override 61 | public ChannelFuture sendTextMessage(String message) { 62 | throw new MethodNotSupportException(); 63 | } 64 | 65 | @Override 66 | public ChannelFuture sendBinaryMessage(ByteBuf byteBuf) { 67 | throw new MethodNotSupportException(); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /ext.opensource.redis/src/main/java/org/infrastructure/redis/core/JosnRedisUtil.java: -------------------------------------------------------------------------------- 1 | package org.infrastructure.redis.core; 2 | 3 | import java.util.ArrayList; 4 | import java.util.HashMap; 5 | import java.util.List; 6 | import java.util.Map; 7 | 8 | import com.google.gson.Gson; 9 | import com.google.gson.JsonArray; 10 | import com.google.gson.JsonElement; 11 | import com.google.gson.JsonObject; 12 | import com.google.gson.JsonParser; 13 | import com.google.gson.reflect.TypeToken; 14 | 15 | /** 16 | * @author ben 17 | * @Title: basic 18 | * @Description: 19 | **/ 20 | 21 | public class JosnRedisUtil { 22 | 23 | private static Gson gson = null; 24 | 25 | static{ 26 | gson = new Gson(); 27 | } 28 | 29 | public static synchronized Gson newInstance(){ 30 | if(gson == null){ 31 | gson = new Gson(); 32 | } 33 | return gson; 34 | } 35 | 36 | public static String toJson(Object obj){ 37 | return gson.toJson(obj); 38 | } 39 | 40 | public static T toBean(String json,Class clz){ 41 | return gson.fromJson(json, clz); 42 | } 43 | 44 | public static Map toMap(String json,Class clz){ 45 | Map map = gson.fromJson(json, new TypeToken>(){}.getType()); 46 | Map result = new HashMap<>(16); 47 | for(String key:map.keySet()){ 48 | result.put(key,gson.fromJson(map.get(key),clz) ); 49 | } 50 | return result; 51 | } 52 | 53 | public static Map toMap(String json){ 54 | Map map = gson.fromJson(json, new TypeToken>(){}.getType()); 55 | return map; 56 | } 57 | 58 | public static List toList(String json,Class clz){ 59 | JsonArray array = new JsonParser().parse(json).getAsJsonArray(); 60 | List list = new ArrayList<>(); 61 | for(final JsonElement elem : array){ 62 | list.add(gson.fromJson(elem, clz)); 63 | } 64 | return list; 65 | } 66 | 67 | public static void main(String[] args) { 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /ext.opensource.netty-server-example/src/main/java/ext/opensource/netty/server/example/http/HttpResourceThymeleaf.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.server.example.http; 2 | 3 | import java.util.Map; 4 | 5 | import org.thymeleaf.TemplateEngine; 6 | import org.thymeleaf.context.Context; 7 | import org.thymeleaf.templateresolver.ClassLoaderTemplateResolver; 8 | 9 | import ext.opensource.netty.server.httpsocket.HttpResourceFile; 10 | 11 | import io.netty.buffer.ByteBuf; 12 | import io.netty.buffer.Unpooled; 13 | import io.netty.util.CharsetUtil; 14 | 15 | /** 16 | * @author ben 17 | * @Title: basic 18 | * @Description: 19 | **/ 20 | 21 | public class HttpResourceThymeleaf extends HttpResourceFile { 22 | private final TemplateEngine engine = new TemplateEngine(); 23 | private final String HTML_FLAG = "html"; 24 | private final String HTM_FLAG = "htm"; 25 | 26 | private boolean isThymeleafFile(String resPath) { 27 | if (resPath == null) { 28 | return false; 29 | } 30 | String suffixName = resPath.substring(resPath.lastIndexOf(".") + 1); 31 | if (suffixName.equalsIgnoreCase(HTML_FLAG) || suffixName.equalsIgnoreCase(HTM_FLAG)) { 32 | return true; 33 | } else { 34 | return false; 35 | } 36 | } 37 | 38 | @Override 39 | protected ByteBuf buildRes(String resPath, Map parameters) { 40 | if (!isThymeleafFile(resPath)) { 41 | 42 | return super.buildRes(resPath, parameters); 43 | } else { 44 | try { 45 | Context context = new Context(); 46 | context.setVariables(parameters); 47 | 48 | if (!engine.isInitialized()) { 49 | ClassLoaderTemplateResolver resolver = new ClassLoaderTemplateResolver(); 50 | resolver.setPrefix(this.getRootDir()); 51 | //设置不缓存 52 | resolver.setCacheable(false); 53 | engine.setTemplateResolver(resolver); 54 | } 55 | 56 | String htmlContext = engine.process(resPath, context); 57 | return Unpooled.copiedBuffer(htmlContext, CharsetUtil.UTF_8); 58 | } catch (Exception ex) { 59 | ex.printStackTrace(); 60 | } 61 | return null; 62 | } 63 | } 64 | } -------------------------------------------------------------------------------- /ext.opensource.netty-server-example/src/main/java/ext/opensource/netty/server/example/scanner/HandlerScaner.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.server.example.scanner; 2 | 3 | import org.springframework.beans.BeansException; 4 | import org.springframework.beans.factory.config.BeanPostProcessor; 5 | import org.springframework.stereotype.Component; 6 | 7 | 8 | /** 9 | * @author ben 10 | * @Title: basic 11 | * @Description: 12 | **/ 13 | 14 | @Component 15 | public class HandlerScaner implements BeanPostProcessor { 16 | 17 | @Override 18 | public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { 19 | //System.err.println("postProcessBeforeInitialization: " + beanName); 20 | return bean; 21 | } 22 | 23 | @Override 24 | public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { 25 | 26 | Class clazz = bean.getClass(); 27 | 28 | Class[] interfaces = clazz.getInterfaces(); 29 | 30 | if(interfaces != null && interfaces.length > 0){ 31 | /* //扫描类的所有接口父类 32 | for (Class interFace : interfaces) { 33 | //判断是否为handler接口类 34 | SocketModule socketModule = interFace.getAnnotation(SocketModule.class); 35 | if (socketModule == null) { 36 | continue; 37 | } 38 | 39 | //找出命令方法 40 | Method[] methods = interFace.getMethods(); 41 | if(methods != null && methods.length > 0){ 42 | for(Method method : methods){ 43 | SocketCommand socketCommand = method.getAnnotation(SocketCommand.class); 44 | if(socketCommand == null){ 45 | continue; 46 | } 47 | 48 | final short module = socketModule.module(); 49 | final short cmd = socketCommand.cmd(); 50 | 51 | if(InvokerHoler.getInvoker(module, cmd) == null){ 52 | InvokerHoler.addInvoker(module, cmd, Invoker.valueOf(method, bean)); 53 | }else{ 54 | System.out.println("重复命令:"+"module:"+module +" "+"cmd:" + cmd); 55 | } 56 | } 57 | } 58 | 59 | }*/ 60 | } 61 | return bean; 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /ext.opensource.netty-server/src/main/java/ext/opensource/netty/server/mqtt/api/CustomConfig.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.server.mqtt.api; 2 | 3 | import ext.opensource.netty.common.core.CacheList; 4 | import ext.opensource.netty.common.core.UniqueIdInteger; 5 | import ext.opensource.netty.server.mqtt.MqttSession; 6 | import ext.opensource.netty.server.mqtt.protocol.data.ClientTopic; 7 | import ext.opensource.netty.server.mqtt.protocol.data.ConsumerClientData; 8 | import ext.opensource.netty.server.mqtt.protocol.data.ProcedureClientData; 9 | import ext.opensource.netty.server.mqtt.protocol.data.TopicData; 10 | 11 | /** 12 | * @author ben 13 | * @Title: basic 14 | * @Description: 15 | **/ 16 | 17 | public interface CustomConfig { 18 | /** 19 | * setInternalSend 20 | * @param internalSend 21 | */ 22 | public void setInternalSend(InternalSend internalSend); 23 | 24 | /** 25 | * setAuthService 26 | * @param authService 27 | */ 28 | public void setAuthService(MqttAuth authService); 29 | 30 | /** 31 | * setConsumerCacheList 32 | * @param cacheList 33 | */ 34 | public void setConsumerCacheList(CacheList cacheList); 35 | 36 | /** 37 | * setProcedureCacheList 38 | * @param cacheList 39 | */ 40 | public void setProcedureCacheList(CacheList cacheList); 41 | 42 | /** 43 | * setTopicList 44 | * @param cacheList 45 | */ 46 | public void setTopicList(CacheList cacheList); 47 | 48 | /** 49 | * setClientTopicList 50 | * @param cacheList 51 | */ 52 | public void setClientTopicList(CacheList cacheList); 53 | 54 | 55 | /** 56 | * setGlobalUniqueIdCacheList 57 | * @param cacheList 58 | */ 59 | public void setGlobalUniqueIdCacheList(CacheList cacheList); 60 | 61 | /** 62 | * 自定义生产者消息处理 63 | * @param msgLister 64 | */ 65 | public void setPubishMessageLister(PubishMessageLister msgLister); 66 | 67 | /** 68 | * 会话远端存储设置 69 | * @param cacheList 70 | */ 71 | public void setRemoteSessionCache(CacheList cacheList); 72 | } 73 | -------------------------------------------------------------------------------- /ext.opensource.netty-common/src/main/java/ext/opensource/netty/common/HeartbeatClientHandler.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.common; 2 | 3 | import io.netty.channel.ChannelHandler; 4 | import io.netty.channel.ChannelHandlerContext; 5 | import io.netty.channel.ChannelInboundHandlerAdapter; 6 | import io.netty.handler.timeout.IdleState; 7 | import io.netty.handler.timeout.IdleStateEvent; 8 | 9 | /** 10 | * @author ben 11 | * @Title: basic 12 | * @Description: 13 | **/ 14 | 15 | @ChannelHandler.Sharable 16 | public class HeartbeatClientHandler extends ChannelInboundHandlerAdapter { 17 | //private static final Logger logger = LoggerFactory.getLogger(HeartbeatClientHandler.class); 18 | 19 | @Override 20 | public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { 21 | if (evt instanceof IdleStateEvent) { 22 | IdleStateEvent e = (IdleStateEvent) evt; 23 | if (e.state() == IdleState.WRITER_IDLE) { 24 | NettyLog.info("client WRITER_IDLE"); 25 | } else if (e.state() == IdleState.READER_IDLE) { 26 | TranDataProtoUtil.writeAndFlushTranData(ctx, TranDataProtoUtil.getPingInstance()); 27 | 28 | NettyLog.info("client READER_IDLE"); 29 | return; 30 | 31 | } else if (e.state() == IdleState.ALL_IDLE) { 32 | NettyLog.info("client ALL_IDLE"); 33 | ctx.close(); 34 | } 35 | } 36 | super.userEventTriggered(ctx, evt); 37 | } 38 | 39 | @Override 40 | public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { 41 | /* if (msg instanceof Heartbeat) { 42 | if (logger.isDebugEnabled()) { 43 | logger.debug("Heartbeat received."); 44 | } 45 | 46 | Server server = ServerContext.getContext().getServer(); 47 | if(server != null) { 48 | server.getCountInfo().getHeartbeatNum().incrementAndGet(); 49 | } 50 | return; 51 | }*/ 52 | super.channelRead(ctx, msg); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /ext.opensource.netty-common/src/main/java/ext/opensource/netty/common/utils/IpUtil.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.common.utils; 2 | 3 | import java.net.Inet4Address; 4 | import java.net.InetAddress; 5 | import java.net.NetworkInterface; 6 | import java.util.Enumeration; 7 | 8 | /** 9 | * @author ben 10 | * @Title: basic 11 | * @Description: 12 | **/ 13 | 14 | public class IpUtil { 15 | 16 | /*** 17 | * 获取外网IP 18 | * @return 19 | */ 20 | public static String getInternetIp() { 21 | try { 22 | 23 | Enumeration networks = NetworkInterface.getNetworkInterfaces(); 24 | InetAddress inetAddress = null; 25 | Enumeration inetAddresses = null; 26 | while (networks.hasMoreElements()) { 27 | inetAddresses = networks.nextElement().getInetAddresses(); 28 | while (inetAddresses.hasMoreElements()) { 29 | inetAddress = inetAddresses.nextElement(); 30 | if (inetAddress != null 31 | && inetAddress instanceof Inet4Address 32 | && !inetAddress.isSiteLocalAddress() 33 | && !inetAddress.isLoopbackAddress() 34 | && inetAddress.getHostAddress().indexOf(":") == -1) { 35 | return inetAddress.getHostAddress(); 36 | } 37 | } 38 | } 39 | 40 | return null; 41 | 42 | } catch (Exception e) { 43 | 44 | throw new RuntimeException(e); 45 | } 46 | } 47 | 48 | /** 49 | * 获取内网IP 50 | * 51 | * @return 52 | */ 53 | public static String getIntranetIp() { 54 | try { 55 | return InetAddress.getLocalHost().getHostAddress(); 56 | } catch (Exception e) { 57 | throw new RuntimeException(e); 58 | } 59 | } 60 | 61 | /** 62 | * 获取服务启动host 63 | * @return 64 | */ 65 | public static String getHost(){ 66 | return getInternetIp()==null? getIntranetIp(): getInternetIp(); 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /ext.opensource.netty-server/src/main/java/ext/opensource/netty/server/httpsocket/WebSocketSession.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.server.httpsocket; 2 | 3 | import java.nio.ByteBuffer; 4 | 5 | import ext.opensource.netty.common.BaseSocketSession; 6 | import io.netty.buffer.ByteBuf; 7 | import io.netty.channel.Channel; 8 | import io.netty.channel.ChannelFuture; 9 | import io.netty.handler.codec.http.websocketx.BinaryWebSocketFrame; 10 | import io.netty.handler.codec.http.websocketx.TextWebSocketFrame; 11 | 12 | /** 13 | * @author ben 14 | * @Title: basic 15 | * @Description: 16 | **/ 17 | 18 | public class WebSocketSession extends BaseSocketSession { 19 | private static final long serialVersionUID = 1L; 20 | 21 | public WebSocketSession(Channel channel) { 22 | super(channel); 23 | // TODO Auto-generated constructor stub 24 | } 25 | 26 | @Override 27 | public ChannelFuture sendTextMessage(String message) { 28 | return channel().writeAndFlush(new TextWebSocketFrame(message)); 29 | } 30 | 31 | public ChannelFuture sendTextMessage(ByteBuf byteBuf) { 32 | return channel().writeAndFlush(new TextWebSocketFrame(byteBuf)); 33 | } 34 | 35 | public ChannelFuture sendTextMessage(ByteBuffer byteBuffer) { 36 | ByteBuf buffer = channel().alloc().buffer(byteBuffer.remaining()); 37 | buffer.writeBytes(byteBuffer); 38 | return channel().writeAndFlush(new TextWebSocketFrame(buffer)); 39 | } 40 | 41 | public ChannelFuture sendBinaryMessage(byte[] bytes) { 42 | ByteBuf buffer = channel().alloc().buffer(bytes.length); 43 | return channel().writeAndFlush(new BinaryWebSocketFrame(buffer.writeBytes(bytes))); 44 | } 45 | @Override 46 | public ChannelFuture sendBinaryMessage(ByteBuf byteBuf) { 47 | return channel().writeAndFlush(new BinaryWebSocketFrame(byteBuf)); 48 | } 49 | 50 | public ChannelFuture sendBinaryMessage(ByteBuffer byteBuffer) { 51 | ByteBuf buffer = channel().alloc().buffer(byteBuffer.remaining()); 52 | buffer.writeBytes(byteBuffer); 53 | return channel().writeAndFlush(new BinaryWebSocketFrame(buffer)); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /ext.opensource.netty-common/src/main/java/ext/opensource/netty/common/TranDataProtoUtil.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.common; 2 | 3 | import com.alibaba.fastjson.JSON; 4 | 5 | import io.netty.channel.Channel; 6 | import io.netty.channel.ChannelHandlerContext; 7 | 8 | /** 9 | * @author ben 10 | * @Title: basic 11 | * @Description: 12 | **/ 13 | 14 | public class TranDataProtoUtil { 15 | public interface TranFlag { 16 | public static final int PING = 1; 17 | public static final int PONG = 2; 18 | public static final int MESSAGE = 3; 19 | public static final int MONITER = 4; 20 | } 21 | 22 | public static TranDataProto getPingInstance() { 23 | TranDataProto data = new TranDataProto(); 24 | data.setFlag(TranFlag.PING); 25 | return data; 26 | } 27 | 28 | public static TranDataProto getPongInstance() { 29 | TranDataProto data = new TranDataProto(); 30 | data.setFlag(TranFlag.PONG); 31 | return data; 32 | } 33 | 34 | public static TranDataProto getMsgInstance(int code, String content) { 35 | TranDataProto data = new TranDataProto(); 36 | data.setFlag(TranFlag.MESSAGE); 37 | data.setCode(code); 38 | data.setContent(content); 39 | return data; 40 | } 41 | 42 | public static Object getMsgSocketData(TranDataProto data) { 43 | return JSON.toJSONString(data) + "\r\n"; 44 | } 45 | 46 | public static void writeTranData(ChannelHandlerContext ctx, TranDataProto data) { 47 | ctx.write(getMsgSocketData(data)); 48 | } 49 | 50 | public static void writeAndFlushTranData(ChannelHandlerContext ctx, TranDataProto data) { 51 | writeTranData(ctx, data); 52 | ctx.flush(); 53 | } 54 | 55 | public static void writeTranData(Channel ch, TranDataProto data) { 56 | ch.write(getMsgSocketData(data)); 57 | } 58 | 59 | public static void writeAndFlushTranData(Channel ch, TranDataProto data) { 60 | writeTranData(ch, data); 61 | ch.flush(); 62 | } 63 | 64 | public static TranDataProto readTranData(String str) { 65 | TranDataProto reqData = null; 66 | try { 67 | reqData = JSON.parseObject(str, TranDataProto.class); 68 | } catch (Exception ex) { 69 | NettyLog.error("error josn: " + str); 70 | } 71 | return reqData; 72 | } 73 | 74 | } 75 | -------------------------------------------------------------------------------- /ext.opensource.netty-client-example/src/main/java/ext/opensource/netty/client/example/ignite/IgniteProperties.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.client.example.ignite; 2 | 3 | import org.springframework.boot.context.properties.ConfigurationProperties; 4 | 5 | /** 6 | * @author ben 7 | * @Title: basic 8 | * @Description: 9 | **/ 10 | 11 | @ConfigurationProperties(prefix = "spring.ignite.cache") 12 | public class IgniteProperties { 13 | /** 14 | * 持久化缓存内存初始化大小(MB), 默认值: 64 15 | */ 16 | private int persistenceInitialSize = 16; 17 | 18 | /** 19 | * 持久化缓存占用内存最大值(MB), 默认值: 128 20 | */ 21 | private int persistenceMaxSize = 512; 22 | 23 | /** 24 | * 持久化磁盘存储路径 25 | */ 26 | private String persistenceStorePath=""; 27 | 28 | /** 29 | * 非持久化缓存内存初始化大小(MB), 默认值: 64 30 | */ 31 | private int notPersistenceInitialSize = 16; 32 | 33 | /** 34 | * 非持久化缓存占用内存最大值(MB), 默认值: 128 35 | */ 36 | private int notPersistenceMaxSize = 512; 37 | 38 | public int getPersistenceInitialSize() { 39 | return persistenceInitialSize; 40 | } 41 | 42 | public IgniteProperties setPersistenceInitialSize(int persistenceInitialSize) { 43 | this.persistenceInitialSize = persistenceInitialSize; 44 | return this; 45 | } 46 | 47 | public int getPersistenceMaxSize() { 48 | return persistenceMaxSize; 49 | } 50 | 51 | public IgniteProperties setPersistenceMaxSize(int persistenceMaxSize) { 52 | this.persistenceMaxSize = persistenceMaxSize; 53 | return this; 54 | } 55 | 56 | public String getPersistenceStorePath() { 57 | return persistenceStorePath; 58 | } 59 | 60 | public IgniteProperties setPersistenceStorePath(String persistenceStorePath) { 61 | this.persistenceStorePath = persistenceStorePath; 62 | return this; 63 | } 64 | 65 | public int getNotPersistenceInitialSize() { 66 | return notPersistenceInitialSize; 67 | } 68 | 69 | public IgniteProperties setNotPersistenceInitialSize(int notPersistenceInitialSize) { 70 | this.notPersistenceInitialSize = notPersistenceInitialSize; 71 | return this; 72 | } 73 | 74 | public int getNotPersistenceMaxSize() { 75 | return notPersistenceMaxSize; 76 | } 77 | 78 | public IgniteProperties setNotPersistenceMaxSize(int notPersistenceMaxSize) { 79 | this.notPersistenceMaxSize = notPersistenceMaxSize; 80 | return this; 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /ext.opensource.netty-client/src/main/java/ext/opensource/netty/client/mqtt/MqttClientHandler.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.client.mqtt; 2 | 3 | import ext.opensource.netty.client.mqtt.protocol.ClientProtocolProcess; 4 | import ext.opensource.netty.common.NettyLog; 5 | import io.netty.channel.ChannelHandlerContext; 6 | import io.netty.channel.SimpleChannelInboundHandler; 7 | import io.netty.handler.codec.mqtt.MqttConnAckMessage; 8 | import io.netty.handler.codec.mqtt.MqttFixedHeader; 9 | import io.netty.handler.codec.mqtt.MqttMessage; 10 | import io.netty.handler.codec.mqtt.MqttPublishMessage; 11 | import io.netty.handler.codec.mqtt.MqttSubAckMessage; 12 | 13 | /** 14 | * @author ben 15 | * @Title: basic 16 | * @Description: 17 | **/ 18 | 19 | public class MqttClientHandler extends SimpleChannelInboundHandler { 20 | private ClientProtocolProcess clientProtocolProcess; 21 | 22 | public MqttClientHandler(ClientProtocolProcess clientProtocolProcess) { 23 | this.clientProtocolProcess = clientProtocolProcess; 24 | } 25 | 26 | @Override 27 | protected void channelRead0(ChannelHandlerContext ctx, Object msgx) throws Exception { 28 | if (msgx == null) {return ;} 29 | MqttMessage msg = (MqttMessage) msgx; 30 | NettyLog.debug("read: {}", msg.fixedHeader().messageType()); 31 | MqttFixedHeader mqttFixedHeader = msg.fixedHeader(); 32 | switch (mqttFixedHeader.messageType()) { 33 | case CONNACK: 34 | clientProtocolProcess.processConnectBack(ctx.channel(), (MqttConnAckMessage) msg); 35 | break; 36 | case UNSUBACK: 37 | clientProtocolProcess.processUnSubBack(ctx.channel(), msg); 38 | break; 39 | case PUBLISH: 40 | clientProtocolProcess.processPublish(ctx.channel(), (MqttPublishMessage) msg); 41 | break; 42 | case PUBACK: 43 | clientProtocolProcess.processPubAck(ctx.channel(), msg); 44 | break; 45 | case PUBREC: 46 | clientProtocolProcess.processPubRec(ctx.channel(), msg); 47 | break; 48 | case PUBREL: 49 | clientProtocolProcess.processPubRel(ctx.channel(), msg); 50 | break; 51 | case PUBCOMP: 52 | clientProtocolProcess.processPubComp(ctx.channel(), msg); 53 | break; 54 | case SUBACK: 55 | clientProtocolProcess.processSubAck(ctx.channel(), (MqttSubAckMessage) msg); 56 | break; 57 | default: 58 | break; 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /ext.opensource.netty-client-example/src/main/java/ext/opensource/netty/client/example/mqtt/CustomMqttClientRedis.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.client.example.mqtt; 2 | 3 | import org.infrastructure.redis.IRedisHashService; 4 | import org.springframework.beans.factory.annotation.Autowired; 5 | 6 | import ext.opensource.netty.client.example.redis.CacheListRedis; 7 | import ext.opensource.netty.client.mqtt.MqttClient; 8 | import ext.opensource.netty.client.mqtt.common.DefautMqttConsumerListener; 9 | import ext.opensource.netty.client.mqtt.common.MessageData; 10 | import ext.opensource.netty.common.core.CacheList; 11 | import ext.opensource.netty.common.core.UniqueIdInteger; 12 | 13 | /** 14 | * @author ben 15 | * @Title: basic 16 | * @Description: 17 | **/ 18 | 19 | public class CustomMqttClientRedis extends CustomMqttClient { 20 | private IRedisHashService redisHashService; 21 | @Autowired 22 | private void setRedisHashService(IRedisHashService redisHashService) { 23 | this.redisHashService = redisHashService; 24 | this.redisHashService.setValueClass(MessageData.class); 25 | } 26 | 27 | private IRedisHashService uniqueIdListService; 28 | @Autowired 29 | private void setUniqueIdListService(IRedisHashService uniqueIdListService) { 30 | this.uniqueIdListService = uniqueIdListService; 31 | this.uniqueIdListService.setValueClass(UniqueIdInteger.class); 32 | } 33 | 34 | @Override 35 | public void init(MqttClient nettyClient) { 36 | super.init(nettyClient); 37 | 38 | String clientId = nettyClient.mqttOptions().getClientIdentifier(); 39 | 40 | CacheList consumerCache = new CacheListRedis( 41 | "mqttclient:consumer:" + clientId, redisHashService); 42 | CacheList procedureCache = new CacheListRedis( 43 | "mqttclient:procedure:" + clientId, redisHashService); 44 | 45 | CacheList idCache = new CacheListRedis( 46 | "mqttclient:gid:" + clientId, uniqueIdListService); 47 | 48 | nettyClient.consumer().setGlobalUniqueIdCache(idCache); 49 | nettyClient.consumer().setCacheList(consumerCache); 50 | nettyClient.consumer().setConsumerListener(new DefautMqttConsumerListener()); 51 | 52 | nettyClient.producer().setGlobalUniqueIdCache(idCache); 53 | nettyClient.producer().setCacheList(procedureCache); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /ext.opensource.netty-common/src/main/java/ext/opensource/netty/common/ChannelManager.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.common; 2 | 3 | import java.util.concurrent.ConcurrentHashMap; 4 | import java.util.concurrent.atomic.AtomicLong; 5 | import io.netty.buffer.ByteBuf; 6 | import io.netty.buffer.ByteBufHolder; 7 | import io.netty.channel.Channel; 8 | import io.netty.util.ReferenceCountUtil; 9 | 10 | /** 11 | * @author ben 12 | * @Title: basic 13 | * @Description: 14 | **/ 15 | 16 | public class ChannelManager { 17 | /// ChannelGroup netty 18 | // private static final ChannelGroup channelsx = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE); 19 | 20 | private ConcurrentHashMap channels = new ConcurrentHashMap<>(); 21 | private AtomicLong receiveCount = new AtomicLong(0); 22 | private AtomicLong sendCount = new AtomicLong(0); 23 | private AtomicLong heartbeatCount = new AtomicLong(0); 24 | 25 | public void addChannel(Channel channel) { 26 | if (null != channel) { 27 | channels.putIfAbsent(channel.id().asLongText(), channel); 28 | } 29 | } 30 | 31 | public void removeChannel(Channel channel) { 32 | if (null != channel) { 33 | channels.remove(channel.id().asLongText()); 34 | } 35 | } 36 | 37 | public long clientCount() { 38 | return channels.mappingCount(); 39 | } 40 | 41 | public long addReceiveCount() { 42 | return receiveCount.incrementAndGet(); 43 | } 44 | 45 | public long receiveCount() { 46 | return receiveCount.get(); 47 | } 48 | 49 | public long addSendCount() { 50 | return sendCount.incrementAndGet(); 51 | } 52 | 53 | public long sendCount() { 54 | return sendCount.get(); 55 | } 56 | 57 | public long heartbeatCount() { 58 | return heartbeatCount.get(); 59 | } 60 | 61 | private static Object safeDuplicate(Object message) { 62 | if (message instanceof ByteBuf) { 63 | return ((ByteBuf) message).retainedDuplicate(); 64 | } else if (message instanceof ByteBufHolder) { 65 | return ((ByteBufHolder) message).retainedDuplicate(); 66 | } else { 67 | return ReferenceCountUtil.retain(message); 68 | } 69 | } 70 | 71 | public void broadcastMessage(Object msg) { 72 | System.out.println("broad count:" + clientCount()); 73 | for (Channel ch : channels.values()) { 74 | if (ch != null && ch.isActive()) { 75 | ch.writeAndFlush(safeDuplicate(msg)); 76 | } 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /ext.opensource.redis/src/main/java/org/infrastructure/redis/core/FastJsonRedisSerializer.java: -------------------------------------------------------------------------------- 1 | package org.infrastructure.redis.core; 2 | 3 | import com.alibaba.fastjson.JSON; 4 | import com.fasterxml.jackson.databind.JavaType; 5 | import com.fasterxml.jackson.databind.ObjectMapper; 6 | import com.fasterxml.jackson.databind.type.TypeFactory; 7 | import org.springframework.data.redis.serializer.RedisSerializer; 8 | import org.springframework.data.redis.serializer.SerializationException; 9 | import com.alibaba.fastjson.parser.ParserConfig; 10 | import org.springframework.util.Assert; 11 | import java.nio.charset.Charset; 12 | 13 | /** 14 | * @author ben 15 | * @Title: basic 16 | * @Description: 17 | **/ 18 | 19 | public class FastJsonRedisSerializer implements RedisSerializer { 20 | @SuppressWarnings("unused") 21 | private ObjectMapper objectMapper = new ObjectMapper(); 22 | public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8"); 23 | 24 | private Class clazz; 25 | 26 | static { 27 | ParserConfig.getGlobalInstance().setAsmEnable(true); 28 | //ParserConfig.getGlobalInstance().setAutoTypeSupport(true); 29 | //如果遇到反序列化autoType is not support错误,请添加并修改一下包名到bean文件路径 30 | // ParserConfig.getGlobalInstance().addAccept("com.xxxxx.xxx"); 31 | } 32 | public FastJsonRedisSerializer(Class clazz) { 33 | super(); 34 | this.clazz = clazz; 35 | } 36 | 37 | @Override 38 | public byte[] serialize(T t) throws SerializationException { 39 | if (t == null) { 40 | return new byte[0]; 41 | } 42 | return JSON.toJSONString(t).getBytes(DEFAULT_CHARSET); 43 | //return JSON.toJSONString(t, SerializerFeature.WriteClassName).getBytes(DEFAULT_CHARSET); 44 | } 45 | 46 | @Override 47 | public T deserialize(byte[] bytes) throws SerializationException { 48 | if (bytes == null || bytes.length <= 0) { 49 | return null; 50 | } 51 | String str = new String(bytes, DEFAULT_CHARSET); 52 | 53 | return JSON.parseObject(str, clazz); 54 | } 55 | public void setObjectMapper(ObjectMapper objectMapper) { 56 | Assert.notNull(objectMapper, "'objectMapper' must not be null"); 57 | this.objectMapper = objectMapper; 58 | } 59 | 60 | protected JavaType getJavaType(Class clazz) { 61 | return TypeFactory.defaultInstance().constructType(clazz); 62 | } 63 | } -------------------------------------------------------------------------------- /ext.opensource.netty-server-example/src/main/java/ext/opensource/netty/server/example/mqtt/kafka/config/KafkaProducerConfig.java: -------------------------------------------------------------------------------- 1 | 2 | package ext.opensource.netty.server.example.mqtt.kafka.config; 3 | 4 | import java.util.HashMap; 5 | import java.util.Map; 6 | 7 | import org.apache.kafka.clients.producer.ProducerConfig; 8 | import org.apache.kafka.common.serialization.StringSerializer; 9 | import org.springframework.beans.factory.annotation.Value; 10 | import org.springframework.context.annotation.Bean; 11 | import org.springframework.context.annotation.Configuration; 12 | import org.springframework.kafka.annotation.EnableKafka; 13 | import org.springframework.kafka.core.DefaultKafkaProducerFactory; 14 | import org.springframework.kafka.core.KafkaTemplate; 15 | import org.springframework.kafka.core.ProducerFactory; 16 | 17 | /** 18 | * @author ben 19 | * @Title: basic 20 | * @Description: 21 | **/ 22 | 23 | @Configuration 24 | @EnableKafka 25 | public class KafkaProducerConfig { 26 | @Value("${spring.kafka.bootstrap-servers}") 27 | private String servers; 28 | @Value("${spring.kafka.producer.acks}") 29 | private String acks; 30 | @Value("${spring.kafka.producer.retries}") 31 | private String retries; 32 | @Value("${spring.kafka.producer.batch-size}") 33 | private String batchSize; 34 | @Value("${spring.kafka.producer.linger.ms}") 35 | private String lingerMs; 36 | @Value("${spring.kafka.producer.buffer-memory}") 37 | private String bufferMemory; 38 | 39 | public Map producerConfigs() { 40 | Map props = new HashMap<>(16); 41 | props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, servers); 42 | props.put(ProducerConfig.ACKS_CONFIG, acks); 43 | props.put(ProducerConfig.RETRIES_CONFIG, retries); 44 | props.put(ProducerConfig.BATCH_SIZE_CONFIG, batchSize); 45 | props.put(ProducerConfig.LINGER_MS_CONFIG, lingerMs); 46 | props.put(ProducerConfig.BUFFER_MEMORY_CONFIG, bufferMemory); 47 | props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, 48 | StringSerializer.class); 49 | props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, 50 | StringSerializer.class); 51 | return props; 52 | } 53 | 54 | public ProducerFactory producerFactory() { 55 | return new DefaultKafkaProducerFactory<>(producerConfigs()); 56 | } 57 | 58 | @Bean 59 | public KafkaTemplate kafkaTemplate() { 60 | return new KafkaTemplate(producerFactory()); 61 | } 62 | 63 | 64 | } -------------------------------------------------------------------------------- /ext.opensource.netty-server/src/main/java/ext/opensource/netty/server/mqtt/MqttServer.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.server.mqtt; 2 | 3 | import ext.opensource.netty.server.core.BaseServer; 4 | import ext.opensource.netty.server.mqtt.api.CustomConfig; 5 | import ext.opensource.netty.server.mqtt.api.InternalRecvice; 6 | import ext.opensource.netty.server.mqtt.common.InternalMessage; 7 | import ext.opensource.netty.server.mqtt.protocol.ProtocolProcess; 8 | import ext.opensource.netty.server.mqtt.protocol.ProtocolProcessConfig; 9 | import ext.opensource.netty.server.mqtt.protocol.ProtocolUtil; 10 | 11 | import io.netty.channel.socket.SocketChannel; 12 | import io.netty.handler.codec.mqtt.MqttDecoder; 13 | import io.netty.handler.codec.mqtt.MqttEncoder; 14 | 15 | /** 16 | * @author ben 17 | * @Title: basic 18 | * @Description: 19 | **/ 20 | 21 | public class MqttServer extends BaseServer { 22 | protected final String HANDLER_MQTTDECODER="mqttDecoder"; 23 | protected final String HANDLER_MQTTENCODER="mqttEncoder"; 24 | protected final String HANDLER_MQTTHANDER="mqttHander"; 25 | 26 | private ProtocolProcessConfig cfg; 27 | private ProtocolProcess protocolProcess; 28 | 29 | public MqttServer() { 30 | checkHeartbeat = true; 31 | readerIdleTimeSeconds = 0; 32 | writerIdleTimeSeconds = 0; 33 | allIdleTimeSeconds = 60; 34 | 35 | protocolProcess = new ProtocolProcess(); 36 | cfg = new ProtocolProcessConfig(protocolProcess); 37 | protocolProcess.init(cfg); 38 | } 39 | 40 | public InternalRecvice internalRecvice() { 41 | return this.protocolProcess; 42 | } 43 | 44 | public CustomConfig initMqtt() { 45 | return cfg; 46 | } 47 | 48 | @Override 49 | public void broadcastMessageString(String msg) { 50 | this.broadcastMessage(ProtocolUtil.publishMessage("/broadcast", msg.getBytes())); 51 | } 52 | 53 | 54 | 55 | @Override 56 | protected void initSocketChannel(SocketChannel ch) { 57 | super.initSocketChannel(ch); 58 | ch.pipeline().addLast(HANDLER_MQTTDECODER, new MqttDecoder()); 59 | ch.pipeline().addLast(HANDLER_MQTTENCODER, MqttEncoder.INSTANCE); 60 | ch.pipeline().addLast(HANDLER_MQTTHANDER, new MqttServerHandler(protocolProcess)); 61 | } 62 | 63 | public void testInternalMessage() { 64 | InternalMessage msg = 65 | InternalMessage.builder().topicName("testInternalMessage").build(); 66 | if (cfg.consumerProcess.getInternalSend() != null) { 67 | cfg.consumerProcess.getInternalSend().internalSend(msg); 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /ext.opensource.netty-server/src/main/java/ext/opensource/netty/server/mqtt/api/impl/ConsumerDataServiceImpl.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.server.mqtt.api.impl; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Collection; 5 | import java.util.List; 6 | 7 | import ext.opensource.netty.common.core.CacheList; 8 | import ext.opensource.netty.common.core.CacheListLocalMemory; 9 | import ext.opensource.netty.server.mqtt.api.ConsumerDataService; 10 | import ext.opensource.netty.server.mqtt.common.ConsumerMessage; 11 | import ext.opensource.netty.server.mqtt.protocol.data.ConsumerClientData; 12 | 13 | /** 14 | * @author ben 15 | * @Title: basic 16 | * @Description: 17 | **/ 18 | 19 | public class ConsumerDataServiceImpl implements ConsumerDataService { 20 | private CacheList sureDataCache; 21 | 22 | public ConsumerDataServiceImpl() { 23 | sureDataCache = new CacheListLocalMemory(); 24 | } 25 | 26 | @Override 27 | public void setConsumerCacheList(CacheList cache) { 28 | if (cache != null) { 29 | this.sureDataCache = cache; 30 | } 31 | } 32 | 33 | @Override 34 | public void putPublishMessage(String clientId, ConsumerMessage dupPublishMessage) { 35 | ConsumerClientData map = sureDataCache.containsKey(clientId) ? sureDataCache.get(clientId) 36 | : null; 37 | if (map == null) { 38 | map = new ConsumerClientData(clientId); 39 | } 40 | map.put(dupPublishMessage.getMessageId(), dupPublishMessage); 41 | sureDataCache.put(clientId, map); 42 | } 43 | 44 | @Override 45 | public List getPublishMessage(String clientId) { 46 | if (sureDataCache.containsKey(clientId)) { 47 | ConsumerClientData map = sureDataCache.get(clientId); 48 | Collection collection = map.values(); 49 | return new ArrayList(collection); 50 | } 51 | return new ArrayList(); 52 | } 53 | 54 | @Override 55 | public void removePublishMessage(String clientId, int messageId) { 56 | if (sureDataCache.containsKey(clientId)) { 57 | ConsumerClientData map = sureDataCache.get(clientId); 58 | if (map.containsKey(messageId)) { 59 | map.remove(messageId); 60 | if (map.size() > 0) { 61 | sureDataCache.put(clientId, map); 62 | } else { 63 | sureDataCache.remove(clientId); 64 | } 65 | } 66 | } 67 | } 68 | 69 | @Override 70 | public void removeByClient(String clientId) { 71 | if (sureDataCache.containsKey(clientId)) { 72 | sureDataCache.remove(clientId); 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /ext.opensource.netty-server-example/src/main/java/ext/opensource/netty/server/example/WebSocketApplication.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.server.example; 2 | 3 | import java.util.Map; 4 | 5 | import org.springframework.boot.CommandLineRunner; 6 | import org.springframework.boot.SpringApplication; 7 | import ext.opensource.netty.common.NettyLog; 8 | import ext.opensource.netty.common.api.SocketApplication; 9 | import ext.opensource.netty.server.example.http.HttpResourceThymeleaf; 10 | import ext.opensource.netty.server.example.websocket.WebSocketEventChat; 11 | import ext.opensource.netty.server.httpsocket.BaseHttpResource; 12 | import ext.opensource.netty.server.httpsocket.HttpResourceProcess; 13 | import ext.opensource.netty.server.httpsocket.WebSocketServer; 14 | import ext.opensource.netty.server.httpsocket.WebSocketUtil; 15 | 16 | import io.netty.handler.codec.http.HttpRequest; 17 | 18 | 19 | /** 20 | * @author ben 21 | * @Title: basic 22 | * @Description: 23 | * 24 | **/ 25 | 26 | //@SpringBootApplication 27 | 28 | public class WebSocketApplication implements CommandLineRunner, SocketApplication { 29 | public static void main(String[] args) { 30 | SpringApplication.run(WebSocketApplication.class, args); 31 | } 32 | 33 | private WebSocketServer webScoketServer; 34 | 35 | ///127.0.0.1:8989/ websocket客户端 36 | 37 | @Override 38 | public void run(String... strings) { 39 | String websocketPath = "/wss"; 40 | webScoketServer = new WebSocketServer(); 41 | 42 | BaseHttpResource httpResource = new HttpResourceThymeleaf(); 43 | httpResource.setRootDir("static/websocket/"); 44 | httpResource.setDefaultIndexName("websocket.html"); 45 | httpResource.setHttpResourceProcess(new HttpResourceProcess() { 46 | @Override 47 | public void porcessResPath(HttpRequest req, String reqPath, 48 | Map reqParameter) { 49 | if (httpResource.getDefaultIndexName().equalsIgnoreCase(reqPath) && (reqParameter != null)) { 50 | reqParameter.put("socketurl", WebSocketUtil.getWebSocketLocation(webScoketServer.getSslCtx() != null, req, websocketPath)); 51 | } 52 | } 53 | }); 54 | 55 | 56 | webScoketServer.setHttpResource(httpResource); 57 | webScoketServer.setWebsocketPath(websocketPath); 58 | webScoketServer.setWebSocketEvent(new WebSocketEventChat()); 59 | webScoketServer.bind(8989); 60 | 61 | NettyLog.info("websocket server run end "); 62 | } 63 | 64 | @Override 65 | public void shutdown() { 66 | if (webScoketServer != null) { 67 | webScoketServer.shutdown(); 68 | } 69 | } 70 | } -------------------------------------------------------------------------------- /ext.opensource.netty-server-example/src/main/java/ext/opensource/netty/server/example/http/ThymeleafTest.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.server.example.http; 2 | 3 | import java.io.IOException; 4 | import java.util.HashMap; 5 | import java.util.Map; 6 | 7 | import org.thymeleaf.TemplateEngine; 8 | import org.thymeleaf.context.Context; 9 | import org.thymeleaf.templateresolver.ClassLoaderTemplateResolver; 10 | import org.thymeleaf.templateresolver.StringTemplateResolver; 11 | 12 | /** 13 | * @author ben 14 | * @Title: basic 15 | * @Description: 16 | **/ 17 | 18 | public class ThymeleafTest { 19 | 20 | /** 21 | * 使用 Thymeleaf 渲染 HTML 22 | * @param template HTML模板 23 | * @param params 参数 24 | * @return 渲染后的HTML 25 | */ 26 | public static String render(String template,Map params){ 27 | Context context = new Context(); 28 | context.setVariables(params); 29 | TemplateEngine engine=new TemplateEngine(); 30 | 31 | StringTemplateResolver resolver = new StringTemplateResolver(); 32 | engine.setTemplateResolver(resolver); 33 | return engine.process(template,context); 34 | } 35 | 36 | public static void testA() { 37 | String template = "

"; 38 | HashMap map = new HashMap<>(16); 39 | map.put("title","hello world"); 40 | String render = render(template, map); 41 | System.out.println("渲染之后的字符串是:"+render); 42 | } 43 | 44 | public static void testB() { 45 | ClassLoaderTemplateResolver resolver = new ClassLoaderTemplateResolver(); 46 | //模板所在目录,相对于当前classloader的classpath。 47 | resolver.setPrefix("static/"); 48 | 49 | ///模板文件后缀 50 | // resolver.setSuffix(".html"); 51 | // resolver.setCacheable(false);//设置不缓存 52 | // resolver.setTemplateMode("HTML5"); 53 | 54 | TemplateEngine engine = new TemplateEngine(); 55 | engine.setTemplateResolver(resolver); 56 | Context context = new Context(); 57 | context.setVariable("socketurl", "ws"); 58 | System.out.println(engine.process("websocket.html", context)); 59 | } 60 | 61 | public static void testc() { 62 | HttpResourceThymeleaf aa = new HttpResourceThymeleaf(); 63 | aa.setRootDir("static/"); 64 | aa.buildWebSocketRes("websocket.html", null); 65 | } 66 | 67 | public static void main(String[] args) throws IOException { 68 | testA(); 69 | //testB(); 70 | //testc(); 71 | } 72 | } -------------------------------------------------------------------------------- /ext.opensource.netty-server/src/main/java/ext/opensource/netty/server/mqtt/api/impl/SessionServiceImpl.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.server.mqtt.api.impl; 2 | 3 | import ext.opensource.netty.common.core.CacheList; 4 | import ext.opensource.netty.common.core.CacheListLocalMemory; 5 | import ext.opensource.netty.server.mqtt.MqttSession; 6 | import ext.opensource.netty.server.mqtt.api.MqttSessionService; 7 | import io.netty.handler.codec.mqtt.MqttPublishMessage; 8 | 9 | /** 10 | * @author ben 11 | * @Title: basic 12 | * @Description: 13 | **/ 14 | 15 | public class SessionServiceImpl implements MqttSessionService { 16 | private CacheList localCache = new CacheListLocalMemory(); 17 | 18 | private CacheList remoteCache = null; 19 | 20 | @Override 21 | public void setRemoteSessionCache(CacheList cacheList) { 22 | if (cacheList != null) { 23 | this.remoteCache = cacheList; 24 | } 25 | } 26 | 27 | @Override 28 | public void put(String clientId, MqttSession sessionStore) { 29 | localCache.put(clientId, sessionStore); 30 | if (remoteCache != null) { 31 | remoteCache.put(clientId, sessionStore); 32 | } 33 | } 34 | 35 | @Override 36 | public MqttSession getSession(String clientId) { 37 | return localCache.get(clientId); 38 | } 39 | 40 | @Override 41 | public boolean containsKey(String clientId) { 42 | return localCache.containsKey(clientId); 43 | } 44 | 45 | @Override 46 | public void remove(String clientId) { 47 | if (clientId != null) { 48 | localCache.remove(clientId); 49 | 50 | if (remoteCache != null) { 51 | remoteCache.remove(clientId); 52 | } 53 | } 54 | } 55 | 56 | @Override 57 | public void writeAndFlush(String clientId, Object obj) { 58 | MqttSession session = localCache.get(clientId); 59 | if (null != session) { 60 | session.channel().writeAndFlush(obj); 61 | } 62 | } 63 | 64 | @Override 65 | public boolean isCleanSession(String clientId) { 66 | MqttSession session = localCache.get(clientId); 67 | if (null != session) { 68 | return session.isCleanSession(); 69 | } else { 70 | return false; 71 | } 72 | } 73 | 74 | @Override 75 | public void closeSession(String clientId) { 76 | MqttSession session = localCache.get(clientId); 77 | if (null != session) { 78 | session.close(); 79 | } 80 | } 81 | 82 | @Override 83 | public MqttPublishMessage getWillMessage(String clientId) { 84 | MqttSession session = localCache.get(clientId); 85 | if (null != session) { 86 | return session.getWillMessage(); 87 | } else { 88 | return null; 89 | } 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /ext.opensource.netty-client/src/main/java/ext/opensource/netty/client/httpsocket/WebSocketClient.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.client.httpsocket; 2 | 3 | import java.net.URI; 4 | import java.net.URISyntaxException; 5 | 6 | import ext.opensource.netty.client.core.BaseClient; 7 | import io.netty.channel.ChannelFuture; 8 | import io.netty.channel.ChannelPipeline; 9 | import io.netty.channel.socket.SocketChannel; 10 | import io.netty.handler.codec.http.DefaultHttpHeaders; 11 | import io.netty.handler.codec.http.HttpClientCodec; 12 | import io.netty.handler.codec.http.HttpObjectAggregator; 13 | import io.netty.handler.codec.http.websocketx.TextWebSocketFrame; 14 | import io.netty.handler.codec.http.websocketx.WebSocketClientHandshaker; 15 | import io.netty.handler.codec.http.websocketx.WebSocketClientHandshakerFactory; 16 | import io.netty.handler.codec.http.websocketx.WebSocketVersion; 17 | import io.netty.handler.ssl.SslHandler; 18 | 19 | /** 20 | * @author ben 21 | * @Title: basic 22 | * @Description: 23 | **/ 24 | 25 | public class WebSocketClient extends BaseClient { 26 | private String websocketPath; 27 | private WebSocketClientHandshaker handshaker; 28 | 29 | public WebSocketClient(String websocketPath) { 30 | this.setSyncConnect(true); 31 | this.websocketPath = websocketPath; 32 | } 33 | 34 | @Override 35 | public void sendMessage(String msg) { 36 | this.channel.writeAndFlush(new TextWebSocketFrame(msg)); 37 | } 38 | 39 | @Override 40 | protected void initSocketChannel(SocketChannel ch) { 41 | super.initSocketChannel(ch); 42 | 43 | URI websocketURI = null; 44 | try { 45 | websocketURI = new URI(getWebSocketUrl(ch.pipeline(), websocketPath)); 46 | } catch (URISyntaxException e) { 47 | e.printStackTrace(); 48 | } 49 | 50 | this.handshaker = WebSocketClientHandshakerFactory.newHandshaker(websocketURI, WebSocketVersion.V13, 51 | (String) null, true, new DefaultHttpHeaders(), 5 * 1024 * 1024); 52 | 53 | ch.pipeline().addLast(new HttpClientCodec()); 54 | ch.pipeline().addLast(new HttpObjectAggregator(65535)); 55 | ch.pipeline().addLast(new WebSocketClientHandler(handshaker)); 56 | } 57 | 58 | @Override 59 | protected void finishConnectEvent(ChannelFuture ch) { 60 | super.finishConnectEvent(ch); 61 | if (ch.isSuccess()) { 62 | // start handskake 63 | ChannelFuture handFuture = this.handshaker.handshake(this.getChannel()); 64 | if (this.isSyncConnect()) { 65 | handFuture.syncUninterruptibly(); 66 | } 67 | } 68 | } 69 | 70 | private String getWebSocketUrl(ChannelPipeline cp, String path) { 71 | String protocol = "ws"; 72 | if (cp.get(SslHandler.class) != null) { 73 | // SSL in use so use Secure WebSockets 74 | protocol = "wss"; 75 | } 76 | return protocol + "://" + this.getHost() + path; 77 | } 78 | 79 | } 80 | -------------------------------------------------------------------------------- /ext.opensource.redis/src/main/java/org/infrastructure/redis/config/RedisProperties.java: -------------------------------------------------------------------------------- 1 | package org.infrastructure.redis.config; 2 | 3 | import org.springframework.boot.context.properties.ConfigurationProperties; 4 | import org.springframework.stereotype.Component; 5 | 6 | /** 7 | * @author ben 8 | * @Title: basic 9 | * @Description: 10 | **/ 11 | 12 | @Component 13 | @ConfigurationProperties(prefix = "spring.redis") 14 | public class RedisProperties { 15 | private int database; 16 | private String host; 17 | private String password; 18 | private int port; 19 | private int timeout = 10000; 20 | 21 | private RedisProperties.Pool pool = new Pool(); 22 | 23 | public RedisProperties() { 24 | } 25 | 26 | public String getHost() { 27 | return this.host; 28 | } 29 | 30 | public void setHost(String host) { 31 | this.host = host; 32 | } 33 | 34 | public int getPort() { 35 | return this.port; 36 | } 37 | 38 | public void setPort(int port) { 39 | this.port = port; 40 | } 41 | 42 | public String getPassword() { 43 | return this.password; 44 | } 45 | 46 | public void setPassword(String password) { 47 | this.password = password; 48 | } 49 | 50 | public RedisProperties.Pool getPool() { 51 | return this.pool; 52 | } 53 | 54 | public void setPool(RedisProperties.Pool pool) { 55 | this.pool = pool; 56 | } 57 | 58 | public int getDatabase() { 59 | return this.database; 60 | } 61 | 62 | public void setDatabase(int database) { 63 | this.database = database; 64 | } 65 | 66 | /** 67 | * @return the timeout 68 | */ 69 | public int getTimeout() { 70 | return timeout; 71 | } 72 | 73 | /** 74 | * @param timeout 75 | * the timeout to set 76 | */ 77 | public void setTimeout(int timeout) { 78 | this.timeout = timeout; 79 | } 80 | 81 | public static class Pool { 82 | private int maxIdle = 8; 83 | private int minIdle = 0; 84 | private int maxActive = 8; 85 | private int maxWait = -1; 86 | 87 | public Pool() { 88 | } 89 | 90 | public int getMaxIdle() { 91 | return this.maxIdle; 92 | } 93 | 94 | public void setMaxIdle(int maxIdle) { 95 | this.maxIdle = maxIdle; 96 | } 97 | 98 | public int getMinIdle() { 99 | return this.minIdle; 100 | } 101 | 102 | public void setMinIdle(int minIdle) { 103 | this.minIdle = minIdle; 104 | } 105 | 106 | public int getMaxActive() { 107 | return this.maxActive; 108 | } 109 | 110 | public void setMaxActive(int maxActive) { 111 | this.maxActive = maxActive; 112 | } 113 | 114 | public int getMaxWait() { 115 | return this.maxWait; 116 | } 117 | 118 | public void setMaxWait(int maxWait) { 119 | this.maxWait = maxWait; 120 | } 121 | 122 | } 123 | } -------------------------------------------------------------------------------- /ext.opensource.netty-server/src/main/java/ext/opensource/netty/server/simple/SimpleServerHandler.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.server.simple; 2 | 3 | import ext.opensource.netty.common.NettyLog; 4 | import ext.opensource.netty.common.TranDataProto; 5 | import ext.opensource.netty.common.TranDataProtoUtil; 6 | 7 | import io.netty.channel.ChannelHandlerContext; 8 | import io.netty.channel.ChannelInboundHandlerAdapter; 9 | import lombok.Setter; 10 | 11 | /** 12 | * @author ben 13 | * @Title: basic 14 | * @Description: 15 | **/ 16 | 17 | public class SimpleServerHandler extends ChannelInboundHandlerAdapter { 18 | 19 | @Setter 20 | private SocketCmdEvent socketCmdEvent; 21 | 22 | @Override 23 | public void channelActive(ChannelHandlerContext ctx) throws Exception { 24 | super.channelActive(ctx); 25 | } 26 | 27 | @Override 28 | public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { 29 | super.exceptionCaught(ctx, cause); 30 | } 31 | 32 | @Override 33 | public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { 34 | NettyLog.debug("msg: {0}", (String) msg); 35 | messageRecived(ctx, (String) msg); 36 | } 37 | 38 | private void processMesage(ChannelHandlerContext ctx, TranDataProto reqData) { 39 | if (reqData.getCode() == null) { 40 | NettyLog.error("trandata code is null:" + reqData.toString()); 41 | return; 42 | } 43 | 44 | if (null != socketCmdEvent) { 45 | TranDataProto reponseData = socketCmdEvent.doCmd(String.valueOf(reqData.getCode()), reqData.getContent()); 46 | if (reponseData != null) { 47 | int execTimes = 2; 48 | for (int i = 1; i <= execTimes; i++) { 49 | TranDataProtoUtil.writeTranData(ctx, reponseData); 50 | /// 51 | // ctx.writeAndFlush(Unpooled.copiedBuffer(i + " - " + JSON.toJSONString(data), 52 | // CharsetUtil.UTF_8)); 53 | } 54 | ctx.flush(); 55 | } 56 | } else { 57 | NettyLog.error("error code:" + reqData.getCode()); 58 | } 59 | } 60 | 61 | private void processPing(ChannelHandlerContext ctx, TranDataProto reqData) { 62 | TranDataProtoUtil.writeAndFlushTranData(ctx, TranDataProtoUtil.getPongInstance()); 63 | } 64 | 65 | private void messageRecived(ChannelHandlerContext ctx, String str) { 66 | TranDataProto reqData = TranDataProtoUtil.readTranData(str); 67 | if (reqData == null) { 68 | NettyLog.error("reqData is null"); 69 | return; 70 | } 71 | 72 | if (reqData.getFlag() == TranDataProtoUtil.TranFlag.PING) { 73 | processPing(ctx, reqData); 74 | } else if (reqData.getFlag() == TranDataProtoUtil.TranFlag.PONG) { 75 | 76 | } else if (reqData.getFlag() == TranDataProtoUtil.TranFlag.MESSAGE) { 77 | processMesage(ctx, reqData); 78 | } else if (reqData.getFlag() == TranDataProtoUtil.TranFlag.MONITER) { 79 | 80 | } 81 | } 82 | } -------------------------------------------------------------------------------- /ext.opensource.netty-client/src/main/java/ext/opensource/netty/client/simple/SimpleClient.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.client.simple; 2 | 3 | import java.nio.charset.Charset; 4 | 5 | import ext.opensource.netty.client.core.BaseClient; 6 | import ext.opensource.netty.common.LogDispatchHandler; 7 | import ext.opensource.netty.common.NettyLog; 8 | import ext.opensource.netty.common.TranDataProtoUtil; 9 | import io.netty.channel.ChannelHandlerContext; 10 | import io.netty.channel.ChannelInboundHandlerAdapter; 11 | import io.netty.channel.SimpleChannelInboundHandler; 12 | import io.netty.channel.socket.SocketChannel; 13 | import io.netty.handler.codec.LineBasedFrameDecoder; 14 | import io.netty.handler.codec.string.StringDecoder; 15 | import io.netty.handler.codec.string.StringEncoder; 16 | 17 | /** 18 | * @author ben 19 | * @Title: basic 20 | * @Description: 21 | **/ 22 | 23 | public class SimpleClient extends BaseClient { 24 | @Override 25 | protected void initSocketChannel(SocketChannel ch) { 26 | super.initSocketChannel(ch); 27 | ch.pipeline().addLast(new LineBasedFrameDecoder(1024)); 28 | ch.pipeline().addLast(new StringEncoder(Charset.forName("UTF-8"))); 29 | ch.pipeline().addLast(new StringDecoder(Charset.forName("UTF-8"))); 30 | ///ch.pipeline().addLast(new DelimiterBasedFrameDecoder(1024, Delimiters.lineDelimiter())); 31 | 32 | ch.pipeline().addLast(new LogDispatchHandler()); 33 | ch.pipeline().addLast(new ClientSimpleHandler()); 34 | ///ch.pipeline().addLast(new ClientSimpleHandlerX()); 35 | } 36 | 37 | @Override 38 | public void sendMessage(String msg) { 39 | TranDataProtoUtil.writeAndFlushTranData(this.channel, TranDataProtoUtil.getMsgInstance(10003, msg)); 40 | } 41 | 42 | public class ClientSimpleHandler extends ChannelInboundHandlerAdapter { 43 | 44 | @Override 45 | public void channelActive(ChannelHandlerContext ctx) throws Exception { 46 | int execTimes = 2; 47 | for (int i=0; i { 65 | private ClientSimpleHandlerX() { 66 | super(true); 67 | } 68 | 69 | @Override 70 | protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception { 71 | NettyLog.info("客户端接收到消息XX: " + msg); 72 | } 73 | 74 | } 75 | 76 | } 77 | -------------------------------------------------------------------------------- /ext.opensource.netty-common/src/main/java/ext/opensource/netty/common/NettyLog.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.common; 2 | 3 | import java.text.SimpleDateFormat; 4 | 5 | /** 6 | * @author ben 7 | * @Title: basic 8 | * @Description: 9 | **/ 10 | 11 | public class NettyLog { 12 | private static class LogInfo { 13 | public String name; 14 | public String methodName; 15 | public long lineNumber; 16 | public String threadName; 17 | 18 | @Override 19 | public String toString() { 20 | //return " [" + threadName + "] " + name + " - " + methodName + "- " + lineNumber + ""; 21 | return name; 22 | } 23 | } 24 | 25 | private static String getCurDateTimeStr() { 26 | SimpleDateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS"); 27 | return dateformat.format(System.currentTimeMillis()); 28 | } 29 | 30 | private static LogInfo getEnterClassName() { 31 | Thread cur = Thread.currentThread(); 32 | LogInfo logInfo = new LogInfo(); 33 | int iLevel = 4; 34 | if (cur != null) { 35 | StackTraceElement[] ary = cur.getStackTrace(); 36 | logInfo.threadName = cur.getName(); 37 | if ((ary != null) && (ary.length > iLevel)) { 38 | logInfo.name = ary[iLevel].getClassName(); 39 | logInfo.methodName = ary[iLevel].getMethodName(); 40 | logInfo.lineNumber = ary[iLevel].getLineNumber(); 41 | } 42 | } 43 | return logInfo; 44 | } 45 | 46 | private static void baseinfo(String msg) { 47 | System.err.println(String.format("%s info - %s : %s", getCurDateTimeStr(), getEnterClassName(), msg)); 48 | } 49 | 50 | private static void basedebug(String msg) { 51 | System.err.println(String.format("%s [DEBUG] - %s : %s", getCurDateTimeStr(), getEnterClassName(), msg)); 52 | } 53 | 54 | private static void baseerror(String msg) { 55 | System.err.println(String.format("%s [ERROR] - %s : %s", getCurDateTimeStr(), getEnterClassName(), msg)); 56 | } 57 | 58 | public static void info(String msg) { 59 | baseinfo(msg); 60 | } 61 | 62 | public static void info(String msg, Object... arguments) { 63 | String newMsg = msg.replaceAll("\\{\\}", "\\%s"); 64 | baseinfo(String.format(newMsg, arguments)); 65 | } 66 | 67 | public static void error(String msg) { 68 | baseerror(msg); 69 | 70 | } 71 | 72 | public static void error(String msg, Object... arguments) { 73 | String newMsg = msg.replaceAll("\\{\\}", "\\%s"); 74 | baseerror(String.format(newMsg, arguments)); 75 | } 76 | 77 | public static void error(String msg, Exception exp) { 78 | baseerror(msg); 79 | if (null != exp) { 80 | exp.printStackTrace(); 81 | } 82 | } 83 | 84 | public static void debug(String msg) { 85 | basedebug(msg); 86 | } 87 | 88 | public static void debug(String msg, Object... arguments) { 89 | String newMsg = msg.replaceAll("\\{\\}", "\\%s"); 90 | basedebug(String.format(newMsg, arguments)); 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /ext.opensource.netty-server/src/main/java/ext/opensource/netty/server/mqtt/protocol/process/ProcedureProcess.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.server.mqtt.protocol.process; 2 | 3 | import java.util.List; 4 | 5 | import ext.opensource.netty.common.NettyLog; 6 | import ext.opensource.netty.common.NettyUtil; 7 | import ext.opensource.netty.server.mqtt.api.ProcedureDataService; 8 | import ext.opensource.netty.server.mqtt.common.BorkerMessage; 9 | import ext.opensource.netty.server.mqtt.common.ProcedureMessage; 10 | 11 | import io.netty.channel.Channel; 12 | import io.netty.handler.codec.mqtt.MqttQoS; 13 | 14 | /** 15 | * @author ben 16 | * @Title: basic 17 | * @Description: 18 | **/ 19 | 20 | public class ProcedureProcess { 21 | private final SendMessageProcess sendProcess; 22 | private ProcedureDataService procedureData; 23 | 24 | public ProcedureProcess(SendMessageProcess sendProcess, ProcedureDataService procedureData) { 25 | this.sendProcess = sendProcess; 26 | this.procedureData = procedureData; 27 | } 28 | 29 | private boolean getMustStoreRelMessage(MqttQoS qosLevel) { 30 | boolean bSaveMsg = false; 31 | if (qosLevel == MqttQoS.AT_MOST_ONCE) { 32 | bSaveMsg = false; 33 | } else if (qosLevel == MqttQoS.AT_LEAST_ONCE) { 34 | bSaveMsg = false; 35 | } else if (qosLevel == MqttQoS.EXACTLY_ONCE) { 36 | bSaveMsg = true; 37 | } 38 | return bSaveMsg; 39 | } 40 | 41 | 42 | 43 | public void removeByCleanSession(String clientId) { 44 | procedureData.removeByClient(clientId); 45 | } 46 | 47 | public ProcedureMessage processPubRel(Channel channel, int messageId) { 48 | String clientId = NettyUtil.getClientId(channel); 49 | NettyLog.debug("PUBREL - clientId: {}, messageId: {}", clientId, messageId); 50 | // 51 | ProcedureMessage relInfo = procedureData.removePubRelMessage(clientId, messageId); 52 | return relInfo; 53 | } 54 | 55 | public void processHistoryPubRel(Channel channel) { 56 | String clientId = NettyUtil.getClientId(channel); 57 | 58 | List dupPubRelMessageStoreList = procedureData.getPubRelMessageForClient(clientId); 59 | dupPubRelMessageStoreList.forEach(relInfo -> { 60 | this.sendProcess.sendPubRecMessage(channel, relInfo.getSourceMsgId()); 61 | }); 62 | } 63 | 64 | public void processPublish(Channel channel, BorkerMessage bMsgInfo) { 65 | MqttQoS qosLevel = MqttQoS.valueOf(bMsgInfo.getIQosLevel()); 66 | String clientId = NettyUtil.getClientId(channel); 67 | int packetId = bMsgInfo.getSourceMsgId(); 68 | String topicName = bMsgInfo.getTopicName(); 69 | byte[] msgBytes = bMsgInfo.getMsgBytes(); 70 | 71 | boolean bSaveRelMsg = getMustStoreRelMessage(qosLevel); 72 | if (bSaveRelMsg) { 73 | ProcedureMessage relMsgObj = ProcedureMessage.builder().sourceClientId(clientId) 74 | .sourceMsgId(packetId).topicName(topicName).iQosLevel(qosLevel.value()).msgBytes(msgBytes) 75 | //.borkerMsgId(bMsgInfo.getBorkerMsgId()) 76 | .build(); 77 | procedureData.putPubRelMessage(clientId, relMsgObj); 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /ext.opensource.netty-server/src/main/java/ext/opensource/netty/server/mqtt/api/impl/ProcedureDataServiceImpl.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.server.mqtt.api.impl; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Collection; 5 | import java.util.List; 6 | import ext.opensource.netty.common.core.CacheList; 7 | import ext.opensource.netty.common.core.CacheListLocalMemory; 8 | import ext.opensource.netty.server.mqtt.api.ProcedureDataService; 9 | import ext.opensource.netty.server.mqtt.common.ProcedureMessage; 10 | import ext.opensource.netty.server.mqtt.protocol.data.ProcedureClientData; 11 | 12 | /** 13 | * @author ben 14 | * @Title: basic 15 | * @Description: 16 | **/ 17 | 18 | public class ProcedureDataServiceImpl implements ProcedureDataService { 19 | private CacheList procedureSureCache; 20 | public ProcedureDataServiceImpl() { 21 | procedureSureCache = new CacheListLocalMemory(); 22 | } 23 | 24 | @Override 25 | public void setProcedureCacheList(CacheList cacheList) { 26 | if (cacheList != null) { 27 | procedureSureCache = cacheList; 28 | } 29 | } 30 | 31 | @Override 32 | public void removeByClient(String clientId) { 33 | if (procedureSureCache.containsKey(clientId)) { 34 | procedureSureCache.remove(clientId); 35 | } 36 | } 37 | 38 | @Override 39 | public List getPubRelMessageForClient(String clientId) { 40 | if (procedureSureCache.containsKey(clientId)) { 41 | ProcedureClientData map = procedureSureCache.get(clientId); 42 | Collection collection = map.values(); 43 | return new ArrayList(collection); 44 | } 45 | return new ArrayList(); 46 | } 47 | 48 | @Override 49 | public ProcedureMessage getPubRelMessage(String clientId, int packId) { 50 | if (procedureSureCache.containsKey(clientId)) { 51 | ProcedureClientData map = procedureSureCache.get(clientId); 52 | if (map.containsKey(packId)) { 53 | return map.get(packId); 54 | } 55 | } 56 | return null; 57 | } 58 | 59 | @Override 60 | public ProcedureMessage removePubRelMessage(String clientId, int packId) { 61 | ProcedureMessage info = null; 62 | if (procedureSureCache.containsKey(clientId)) { 63 | ProcedureClientData map = procedureSureCache.get(clientId); 64 | if (map.containsKey(packId)) { 65 | info = map.get(packId); 66 | map.remove(packId); 67 | if (map.size() > 0) { 68 | procedureSureCache.put(clientId, map); 69 | } else { 70 | procedureSureCache.remove(clientId); 71 | } 72 | } 73 | } 74 | return info; 75 | } 76 | 77 | @Override 78 | public void putPubRelMessage(String clientId, ProcedureMessage info) { 79 | ProcedureClientData map = procedureSureCache.containsKey(clientId) ? procedureSureCache.get(clientId) 80 | : null; 81 | if (map == null) { 82 | map = new ProcedureClientData(clientId); 83 | } 84 | map.put(info.getSourceMsgId(), info); 85 | procedureSureCache.put(clientId, map); 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /ext.opensource.netty-common/src/main/java/ext/opensource/netty/common/utils/StringsUtil.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.common.utils; 2 | 3 | import java.util.UUID; 4 | 5 | /** 6 | * @author ben 7 | * @Title: basic 8 | * @Description: 9 | **/ 10 | 11 | public class StringsUtil { 12 | public static final String EMPTY = ""; 13 | 14 | /** 15 | * 首字母转小写 16 | * 17 | * @param s 18 | * @return 19 | */ 20 | public static String toLowerCaseFirstOne(String s) { 21 | if (null == s) { 22 | return s; 23 | } 24 | if (Character.isLowerCase(s.charAt(0))) { 25 | return s; 26 | } else { 27 | return (new StringBuilder()).append(Character.toLowerCase(s.charAt(0))).append(s.substring(1)).toString(); 28 | } 29 | } 30 | 31 | /** 32 | * 首字母转大写 33 | * 34 | * @param s 35 | * @return 36 | */ 37 | public static String toUpperCaseFirstOne(String s) { 38 | if (null == s) { 39 | return s; 40 | } 41 | if (Character.isUpperCase(s.charAt(0))) { 42 | return s; 43 | } else { 44 | return (new StringBuilder()).append(Character.toUpperCase(s.charAt(0))).append(s.substring(1)).toString(); 45 | } 46 | } 47 | 48 | public static boolean isEmpty(CharSequence str) { 49 | return str == null || str.length() == 0; 50 | } 51 | 52 | public static String str(CharSequence cs) { 53 | return null == cs ? null : cs.toString(); 54 | } 55 | 56 | public static String removeSuffix(CharSequence str, CharSequence suffix) { 57 | if (isEmpty(str) || isEmpty(suffix)) { 58 | return str(str); 59 | } 60 | 61 | final String str2 = str.toString(); 62 | if (str2.endsWith(suffix.toString())) { 63 | // 截取前半段 64 | return subPre(str2, str2.length() - suffix.length()); 65 | } 66 | return str2; 67 | } 68 | 69 | public static String subPre(CharSequence string, int toIndex) { 70 | return sub(string, 0, toIndex); 71 | } 72 | 73 | public static String sub(CharSequence str, int fromIndex, int toIndex) { 74 | if (isEmpty(str)) { 75 | return str(str); 76 | } 77 | int len = str.length(); 78 | 79 | if (fromIndex < 0) { 80 | fromIndex = len + fromIndex; 81 | if (fromIndex < 0) { 82 | fromIndex = 0; 83 | } 84 | } else if (fromIndex > len) { 85 | fromIndex = len; 86 | } 87 | 88 | if (toIndex < 0) { 89 | toIndex = len + toIndex; 90 | if (toIndex < 0) { 91 | toIndex = len; 92 | } 93 | } else if (toIndex > len) { 94 | toIndex = len; 95 | } 96 | 97 | if (toIndex < fromIndex) { 98 | int tmp = fromIndex; 99 | fromIndex = toIndex; 100 | toIndex = tmp; 101 | } 102 | 103 | if (fromIndex == toIndex) { 104 | return EMPTY; 105 | } 106 | 107 | return str.toString().substring(fromIndex, toIndex); 108 | } 109 | 110 | 111 | 112 | public static int count(String str, String subStr) { 113 | String[] strary = str.split(subStr); 114 | return strary.length; 115 | } 116 | 117 | public static String getUuid() { 118 | return UUID.randomUUID().toString().replace("-", "").toLowerCase(); 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /ext.opensource.netty-server/src/main/java/ext/opensource/netty/server/httpsocket/HttpResourceHander.java: -------------------------------------------------------------------------------- 1 | 2 | package ext.opensource.netty.server.httpsocket; 3 | 4 | import static io.netty.handler.codec.http.HttpHeaderNames.CONNECTION; 5 | import static io.netty.handler.codec.http.HttpHeaderValues.CLOSE; 6 | import io.netty.buffer.ByteBuf; 7 | import io.netty.buffer.Unpooled; 8 | import io.netty.channel.ChannelFutureListener; 9 | import io.netty.channel.ChannelHandlerContext; 10 | import io.netty.channel.SimpleChannelInboundHandler; 11 | import io.netty.handler.codec.http.DefaultFullHttpResponse; 12 | import io.netty.handler.codec.http.FullHttpRequest; 13 | import io.netty.handler.codec.http.FullHttpResponse; 14 | import io.netty.handler.codec.http.HttpResponseStatus; 15 | import io.netty.handler.codec.http.HttpUtil; 16 | import io.netty.handler.codec.http.HttpVersion; 17 | import io.netty.util.CharsetUtil; 18 | 19 | /** 20 | * @author ben 21 | * @Title: basic 22 | * @Description: 23 | **/ 24 | 25 | public class HttpResourceHander 26 | extends 27 | SimpleChannelInboundHandler { 28 | private BaseHttpResource httpResource; 29 | 30 | public HttpResourceHander(BaseHttpResource httpResource) { 31 | this.httpResource = httpResource; 32 | } 33 | 34 | @Override 35 | protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest req) 36 | throws Exception { 37 | 38 | String uri = req.uri(); 39 | int index = uri.indexOf("?"); 40 | String path = null; 41 | if (index == -1) { 42 | path = uri; 43 | } else { 44 | path = uri.substring(0, index); 45 | } 46 | 47 | if (httpResource != null) { 48 | String resFileName = path; 49 | 50 | ByteBuf res = httpResource.buildWebSocketRes(req, resFileName); 51 | if (null == res) { 52 | sendHttpResponse(ctx, req, new DefaultFullHttpResponse( 53 | HttpVersion.HTTP_1_1, HttpResponseStatus.NOT_FOUND)); 54 | return; 55 | } else { 56 | sendHttpResponse(ctx, req, new DefaultFullHttpResponse( 57 | HttpVersion.HTTP_1_1, HttpResponseStatus.OK, res)); 58 | } 59 | } 60 | } 61 | 62 | private static void sendHttpResponse(ChannelHandlerContext ctx, 63 | FullHttpRequest req, FullHttpResponse res) { 64 | // Generate an error page if response getStatus code is not OK (200). 65 | int statusCode = res.status().code(); 66 | if (statusCode != HttpResponseStatus.OK.code() 67 | && res.content().readableBytes() == 0) { 68 | ByteBuf buf = Unpooled.copiedBuffer(res.status().toString(), 69 | CharsetUtil.UTF_8); 70 | res.content().writeBytes(buf); 71 | buf.release(); 72 | } 73 | HttpUtil.setContentLength(res, res.content().readableBytes()); 74 | 75 | // Send the response and close the connection if necessary. 76 | if (!HttpUtil.isKeepAlive(req) 77 | || statusCode != HttpResponseStatus.OK.code()) { 78 | res.headers().set(CONNECTION, CLOSE); 79 | ctx.writeAndFlush(res).addListener(ChannelFutureListener.CLOSE); 80 | } else { 81 | res.headers().set(CONNECTION, CLOSE); 82 | ctx.writeAndFlush(res).addListener(ChannelFutureListener.CLOSE); 83 | } 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /ext.opensource.netty-client-example/src/main/java/ext/opensource/netty/client/example/MqttClientApplication.java: -------------------------------------------------------------------------------- 1 | package ext.opensource.netty.client.example; 2 | 3 | import java.net.URISyntaxException; 4 | import java.util.Map; 5 | import java.util.Map.Entry; 6 | 7 | import org.springframework.boot.CommandLineRunner; 8 | import org.springframework.boot.SpringApplication; 9 | import org.springframework.boot.autoconfigure.SpringBootApplication; 10 | 11 | import ext.opensource.netty.client.example.listen.SpringBeanUtil; 12 | import ext.opensource.netty.client.example.mqtt.MqttClientCustomInit; 13 | import ext.opensource.netty.client.mqtt.MqttClient; 14 | import ext.opensource.netty.client.mqtt.api.MqttConsumerListener; 15 | import ext.opensource.netty.client.mqtt.common.ClientEvent; 16 | import ext.opensource.netty.common.NettyLog; 17 | import ext.opensource.netty.common.api.SocketApplication; 18 | 19 | /** 20 | * @author ben 21 | * @Title: basic 22 | * @Description: 23 | **/ 24 | 25 | @SpringBootApplication 26 | public class MqttClientApplication implements CommandLineRunner, SocketApplication { 27 | private MqttClient nettyClient; 28 | 29 | public static void main(String[] args) { 30 | SpringApplication.run(MqttClientApplication.class, args); 31 | } 32 | 33 | @Override 34 | public void run(String... strings) throws URISyntaxException { 35 | String clientId = "JavaClient"; 36 | nettyClient = new MqttClient(); 37 | 38 | ///ssl 39 | //nettyClient.setSslCtx(SslContextUtil.createSSLClientContextForJKS("cert/ssl_client.jks", "client")); 40 | 41 | nettyClient.mqttOptions().setClientIdentifier(clientId); 42 | initCustom(nettyClient); 43 | 44 | nettyClient.setLoginSuccess(new ClientEvent() { 45 | @Override 46 | public void process() { 47 | nettyClient.consumer().subscribe("/a", 2); 48 | /// 49 | nettyClient.producer().sendPubishMessage("/a", "demo", 2, false); 50 | } 51 | }); 52 | 53 | nettyClient.consumer().setConsumerListener(new MqttConsumerListener(){ 54 | @Override 55 | public void receiveMessage(int msgId, String topic, String msg) { 56 | // TODO Auto-generated method stub 57 | System.err.println(String.format("msgid:%s, topic: %s, msg: %s", msgId, topic, msg)); 58 | } 59 | 60 | @Override 61 | public void receiveMessageByAny(int msgId, String topic, String msg) { 62 | // TODO Auto-generated method stub 63 | } 64 | }); 65 | 66 | ///nettyClient.setCharsetName("GB2312"); 67 | ///nettyClient.setCheckConnectFlag(true); 68 | ///nettyClient.connect("192.168.136.148", 1883); 69 | /// 70 | nettyClient.connect(8989); 71 | // nettyClient.requireSync(); 72 | System.err.println("mqtt client run end"); 73 | } 74 | 75 | private void initCustom(MqttClient client) { 76 | Map result = SpringBeanUtil.getApplicationContext().getBeansOfType(MqttClientCustomInit.class); 77 | for (Entry app : result.entrySet()) { 78 | NettyLog.info("init custom - " + app.getKey()); 79 | app.getValue().init(client);; 80 | } 81 | } 82 | 83 | @Override 84 | public void shutdown() { 85 | if (nettyClient != null) { 86 | nettyClient.shutdown(); 87 | nettyClient = null; 88 | } 89 | } 90 | } 91 | --------------------------------------------------------------------------------