├── src ├── test │ ├── resources │ │ ├── stomp │ │ │ └── application.yaml │ │ ├── websocket │ │ │ ├── application.yaml │ │ │ └── index.html │ │ ├── springmyprotocol │ │ │ └── application.yaml │ │ ├── mqtt │ │ │ └── application.yaml │ │ ├── nrpc │ │ │ ├── server │ │ │ │ └── application.yaml │ │ │ └── client │ │ │ │ └── application.yaml │ │ ├── mysql │ │ │ └── application.yaml │ │ ├── springdubbo │ │ │ ├── application.yaml │ │ │ ├── dubbo-client.xml │ │ │ └── dubbo-server.xml │ │ ├── http │ │ │ ├── application.yaml │ │ │ └── index.html │ │ └── javadubbo │ │ │ ├── dubbo-client.xml │ │ │ └── dubbo-server.xml │ └── java │ │ └── com │ │ └── github │ │ └── netty │ │ ├── javadubbo │ │ ├── example │ │ │ ├── DemoAPI.java │ │ │ └── DemoAPIImpl.java │ │ ├── ClientFilter.java │ │ ├── Server.java │ │ └── Client.java │ │ ├── springdubbo │ │ ├── example │ │ │ ├── DemoAPI.java │ │ │ └── DemoAPIImpl.java │ │ ├── Server.java │ │ ├── DubboBootstrap.java │ │ └── Client.java │ │ ├── nrpc │ │ ├── client │ │ │ ├── HelloClient.java │ │ │ ├── HelloRxjava3AsyncClient.java │ │ │ ├── HelloAsyncClient.java │ │ │ ├── example │ │ │ │ ├── HelloNettyRpcLoadBalanced.java │ │ │ │ ├── HelloNettyRpcFilter1.java │ │ │ │ ├── HelloNettyRpcFilter2.java │ │ │ │ └── HelloRpcClientAop.java │ │ │ └── NRpcClientBootstrap.java │ │ ├── api │ │ │ ├── HelloService.java │ │ │ ├── HelloData.java │ │ │ └── HelloDTO.java │ │ └── server │ │ │ ├── NRpcServerBootstrap.java │ │ │ ├── HelloServiceImpl.java │ │ │ └── example │ │ │ └── RpcServerAop.java │ │ ├── javaxservlet │ │ ├── example │ │ │ └── MyHttpServlet.java │ │ └── HttpBootstrap.java │ │ ├── mysql │ │ ├── MysqlBootstrap.java │ │ ├── example │ │ │ ├── MysqlBackendHandler.java │ │ │ └── MysqlFrontendHandler.java │ │ └── MysqlTests.java │ │ ├── http │ │ ├── example │ │ │ ├── CommonsMultipartResolverForProgress.java │ │ │ └── IndexController.java │ │ ├── HttpTests.java │ │ ├── HttpTests2.java │ │ └── HttpBootstrap.java │ │ ├── mqtt │ │ ├── MqttBrokerBootstrap.java │ │ └── MqttConsumerBootstrap.java │ │ ├── stomp │ │ ├── WebsocketStompBootstrap.java │ │ └── example │ │ │ └── HelloController.java │ │ ├── websocket │ │ ├── WebsocketBootstrap.java │ │ └── example │ │ │ └── IndexController.java │ │ ├── file │ │ └── FileApplication.java │ │ ├── myprotocol │ │ ├── MyClient.java │ │ └── MyServer.java │ │ ├── springmyprotocol │ │ └── MyClient.java │ │ └── http2 │ │ ├── HttpBootstrap.java │ │ └── Http2Tests.java └── main │ ├── java │ ├── org │ │ ├── reactivestreams │ │ │ ├── Publisher.java │ │ │ ├── Subscription.java │ │ │ └── Subscriber.java │ │ ├── apache │ │ │ └── tomcat │ │ │ │ └── websocket │ │ │ │ └── server │ │ │ │ └── WsHttpUpgradeHandler.java │ │ └── springframework │ │ │ └── web │ │ │ └── socket │ │ │ └── server │ │ │ └── standard │ │ │ └── TomcatRequestUpgradeStrategy.java │ ├── com │ │ └── github │ │ │ └── netty │ │ │ ├── protocol │ │ │ ├── nrpc │ │ │ │ ├── State.java │ │ │ │ ├── service │ │ │ │ │ ├── RpcCommandServiceImpl.java │ │ │ │ │ ├── RpcCommandAsyncService.java │ │ │ │ │ └── RpcCommandService.java │ │ │ │ ├── Emitter.java │ │ │ │ ├── exception │ │ │ │ │ ├── RpcWriteException.java │ │ │ │ │ ├── RpcDecodeException.java │ │ │ │ │ ├── RpcEncodeException.java │ │ │ │ │ ├── RpcConnectException.java │ │ │ │ │ ├── RpcResponseException.java │ │ │ │ │ ├── RpcException.java │ │ │ │ │ └── RpcTimeoutException.java │ │ │ │ ├── RpcClientRxjava3Flowable.java │ │ │ │ ├── ChunkAck.java │ │ │ │ ├── RpcClientAop.java │ │ │ │ ├── RpcServerAop.java │ │ │ │ ├── RpcDone.java │ │ │ │ ├── RpcClientCompletableFuture.java │ │ │ │ └── RpcClientRxjava3Observable.java │ │ │ ├── mqtt │ │ │ │ ├── package-info.java │ │ │ │ ├── IQueueRepository.java │ │ │ │ ├── MemoryQueueRepository.java │ │ │ │ ├── MqttRetainedMessage.java │ │ │ │ ├── exception │ │ │ │ │ ├── MqttException.java │ │ │ │ │ └── MqttSessionCorruptedException.java │ │ │ │ ├── interception │ │ │ │ │ ├── InterceptMessage.java │ │ │ │ │ ├── InterceptDisconnectMessage.java │ │ │ │ │ ├── InterceptConnectionLostMessage.java │ │ │ │ │ ├── InterceptAbstractMessage.java │ │ │ │ │ ├── InterceptUnsubscribeMessage.java │ │ │ │ │ ├── InterceptSubscribeMessage.java │ │ │ │ │ ├── InterceptPublishMessage.java │ │ │ │ │ ├── AbstractInterceptHandler.java │ │ │ │ │ └── Interceptor.java │ │ │ │ ├── security │ │ │ │ │ ├── IAuthenticator.java │ │ │ │ │ ├── AcceptAllAuthenticator.java │ │ │ │ │ ├── DenyAllAuthorizatorPolicy.java │ │ │ │ │ ├── PermitAllAuthorizatorPolicy.java │ │ │ │ │ ├── IAuthorizatorPolicy.java │ │ │ │ │ └── Authorization.java │ │ │ │ ├── ISubscriptionsRepository.java │ │ │ │ ├── IRetainedRepository.java │ │ │ │ ├── subscriptions │ │ │ │ │ ├── ISubscriptionsDirectory.java │ │ │ │ │ ├── SubscriptionCounterVisitor.java │ │ │ │ │ ├── INode.java │ │ │ │ │ ├── TNode.java │ │ │ │ │ └── Token.java │ │ │ │ ├── config │ │ │ │ │ ├── IResourceLoader.java │ │ │ │ │ ├── BrokerConfiguration.java │ │ │ │ │ └── ClasspathResourceLoader.java │ │ │ │ ├── MqttClientDescriptor.java │ │ │ │ ├── MqttIdleTimeoutChannelHandler.java │ │ │ │ └── MemorySubscriptionsRepository.java │ │ │ ├── rtsp │ │ │ │ └── package-info.java │ │ │ ├── mysql │ │ │ │ ├── client │ │ │ │ │ ├── ClientDecoder.java │ │ │ │ │ ├── ClientPacket.java │ │ │ │ │ ├── ClientQueryPacket.java │ │ │ │ │ ├── ClientCommandPacket.java │ │ │ │ │ └── ClientCommandDecoder.java │ │ │ │ ├── server │ │ │ │ │ ├── ServerDecoder.java │ │ │ │ │ ├── ServerPacket.java │ │ │ │ │ ├── ServerColumnCountPacket.java │ │ │ │ │ ├── ServerErrorPacket.java │ │ │ │ │ ├── ServerResultsetRowPacket.java │ │ │ │ │ └── ServerEofPacket.java │ │ │ │ ├── listener │ │ │ │ │ └── MysqlPacketListener.java │ │ │ │ ├── MysqlPacket.java │ │ │ │ ├── EventHandshakeSuccessful.java │ │ │ │ ├── ColumnFlag.java │ │ │ │ ├── AbstractMySqlPacket.java │ │ │ │ ├── ServerStatusFlag.java │ │ │ │ ├── Constants.java │ │ │ │ ├── AbstractPacketEncoder.java │ │ │ │ ├── exception │ │ │ │ │ └── ProxyException.java │ │ │ │ ├── AbstractAuthPluginDataBuilder.java │ │ │ │ └── CapabilityFlags.java │ │ │ ├── servlet │ │ │ │ ├── ServletResetBufferIOException.java │ │ │ │ ├── ServletClientAbortException.java │ │ │ │ ├── util │ │ │ │ │ ├── InstanceFactory.java │ │ │ │ │ ├── ByteBufToHttpContentChannelHandler.java │ │ │ │ │ ├── HttpLazyThreadPool.java │ │ │ │ │ ├── HttpConstants.java │ │ │ │ │ └── HttpAbortPolicyWithReport.java │ │ │ │ ├── websocket │ │ │ │ │ ├── WebSocketNotFoundHandlerEndpoint.java │ │ │ │ │ └── WebSocketHandler.java │ │ │ │ └── SessionService.java │ │ │ ├── dubbo │ │ │ │ ├── packet │ │ │ │ │ ├── BodyEvent.java │ │ │ │ │ ├── BodyFail.java │ │ │ │ │ ├── BodyResponse.java │ │ │ │ │ └── BodyRequest.java │ │ │ │ └── serialization │ │ │ │ │ ├── AllowClassNotifyListener.java │ │ │ │ │ ├── SerializeCheckStatus.java │ │ │ │ │ └── CompactedJavaSerialization.java │ │ │ └── DubboProtocol.java │ │ │ ├── core │ │ │ ├── util │ │ │ │ ├── LoggerFactoryX.java │ │ │ │ ├── Wrapper.java │ │ │ │ ├── AsmMethodToParameterNamesFunction.java │ │ │ │ ├── Recyclable.java │ │ │ │ ├── StringUtil.java │ │ │ │ ├── NettyThreadPoolExecutor.java │ │ │ │ ├── ThreadFactoryX.java │ │ │ │ ├── NettyThreadX.java │ │ │ │ └── ThreadPoolX.java │ │ │ ├── ServerListener.java │ │ │ ├── MessageToRunnable.java │ │ │ ├── Ordered.java │ │ │ ├── AbstractProtocol.java │ │ │ └── ProtocolHandler.java │ │ │ ├── annotation │ │ │ ├── NRpcParam.java │ │ │ ├── NRpcMethod.java │ │ │ └── NRpcService.java │ │ │ └── springboot │ │ │ ├── client │ │ │ ├── NettyRpcLoadBalanced.java │ │ │ ├── NettyRpcFullRequest.java │ │ │ └── NettyRpcFilter.java │ │ │ ├── NettyRpcClient.java │ │ │ ├── EnableNettyRpcClients.java │ │ │ └── server │ │ │ └── ApplicationInstanceFactory.java │ └── io │ │ └── netty │ │ └── channel │ │ ├── epoll │ │ ├── EpollUtils.java │ │ └── EpollChannelReportRunnable.java │ │ ├── kqueue │ │ └── KqueueUtils.java │ │ ├── ChannelUtils.java │ │ └── nio │ │ └── NioChannelReportRunnable.java │ └── resources │ └── server.properties └── .gitignore /src/test/resources/stomp/application.yaml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8080 3 | -------------------------------------------------------------------------------- /src/test/resources/websocket/application.yaml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8080 3 | -------------------------------------------------------------------------------- /src/test/resources/springmyprotocol/application.yaml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8080 3 | -------------------------------------------------------------------------------- /src/test/resources/mqtt/application.yaml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8080 3 | netty: 4 | mqtt: 5 | enabled: true 6 | auto-flush-idle-time: 0 -------------------------------------------------------------------------------- /src/main/java/org/reactivestreams/Publisher.java: -------------------------------------------------------------------------------- 1 | package org.reactivestreams; 2 | 3 | public interface Publisher { 4 | void subscribe(Subscriber s); 5 | } 6 | -------------------------------------------------------------------------------- /src/main/java/org/reactivestreams/Subscription.java: -------------------------------------------------------------------------------- 1 | package org.reactivestreams; 2 | 3 | public interface Subscription { 4 | void request(long n); 5 | 6 | void cancel(); 7 | } 8 | -------------------------------------------------------------------------------- /src/test/java/com/github/netty/javadubbo/example/DemoAPI.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.javadubbo.example; 2 | 3 | public interface DemoAPI { 4 | String hello(String name,int w); 5 | } 6 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/protocol/nrpc/State.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.protocol.nrpc; 2 | 3 | public interface State { 4 | String name(); 5 | 6 | boolean isComplete(); 7 | } 8 | -------------------------------------------------------------------------------- /src/test/java/com/github/netty/springdubbo/example/DemoAPI.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.springdubbo.example; 2 | 3 | public interface DemoAPI { 4 | String hello(String name,int w); 5 | } 6 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/protocol/mqtt/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Reference for https://github.com/andsel/moquette 3 | * thank you 4 | */ 5 | package com.github.netty.protocol.mqtt; 6 | 7 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/protocol/rtsp/package-info.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Reference for https://github.com/fyhertz/libstreaming 3 | * thank you 554 4 | */ 5 | package com.github.netty.protocol.rtsp; -------------------------------------------------------------------------------- /src/test/resources/nrpc/server/application.yaml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8080 3 | netty: 4 | nrpc: 5 | server-default-version: my1.0 6 | codec: fastjson 7 | spring: 8 | application: 9 | name: nrpc-server -------------------------------------------------------------------------------- /src/main/java/com/github/netty/protocol/mysql/client/ClientDecoder.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.protocol.mysql.client; 2 | 3 | import io.netty.channel.ChannelHandler; 4 | 5 | 6 | public interface ClientDecoder extends ChannelHandler { 7 | } 8 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/protocol/mysql/server/ServerDecoder.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.protocol.mysql.server; 2 | 3 | import io.netty.channel.ChannelHandler; 4 | 5 | 6 | public interface ServerDecoder extends ChannelHandler { 7 | } 8 | -------------------------------------------------------------------------------- /src/main/java/org/reactivestreams/Subscriber.java: -------------------------------------------------------------------------------- 1 | package org.reactivestreams; 2 | 3 | public interface Subscriber { 4 | void onSubscribe(Subscription s); 5 | 6 | void onNext(T n); 7 | 8 | void onError(Throwable t); 9 | 10 | void onComplete(); 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/protocol/mqtt/IQueueRepository.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.protocol.mqtt; 2 | 3 | import java.util.Queue; 4 | 5 | public interface IQueueRepository { 6 | 7 | Queue createQueue(String clientId, boolean clean); 8 | } 9 | -------------------------------------------------------------------------------- /src/main/java/org/apache/tomcat/websocket/server/WsHttpUpgradeHandler.java: -------------------------------------------------------------------------------- 1 | package org.apache.tomcat.websocket.server; 2 | 3 | /** 4 | * springboot @EnableWebSocket support 5 | * org.springframework.web.socket.server.support.AbstractHandshakeHandler#tomcatWsPresent 6 | */ 7 | public class WsHttpUpgradeHandler { 8 | } 9 | -------------------------------------------------------------------------------- /src/test/java/com/github/netty/nrpc/client/HelloClient.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.nrpc.client; 2 | 3 | import com.github.netty.nrpc.api.HelloService; 4 | import com.github.netty.springboot.NettyRpcClient; 5 | 6 | @NettyRpcClient(serviceName = "nrpc-server",timeout = 300) 7 | public interface HelloClient extends HelloService { 8 | 9 | } 10 | -------------------------------------------------------------------------------- /src/test/java/com/github/netty/javadubbo/example/DemoAPIImpl.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.javadubbo.example; 2 | 3 | public class DemoAPIImpl implements DemoAPI { 4 | @Override 5 | public String hello(String name, int w) { 6 | System.out.println("name = " + name + "w" + w); 7 | return name + "service response hello!!"; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/test/java/com/github/netty/nrpc/api/HelloService.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.nrpc.api; 2 | 3 | import org.springframework.web.bind.annotation.RequestMapping; 4 | 5 | @RequestMapping("/hello") 6 | public interface HelloService { 7 | HelloData sayHello(String name, Integer id, Boolean name3, HelloDTO request); 8 | HelloData sayHello1(String name); 9 | } 10 | -------------------------------------------------------------------------------- /src/test/java/com/github/netty/springdubbo/example/DemoAPIImpl.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.springdubbo.example; 2 | 3 | public class DemoAPIImpl implements DemoAPI { 4 | @Override 5 | public String hello(String name, int w) { 6 | System.out.println("name = " + name + "w" + w); 7 | return name + "service response hello!!"; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled class file 2 | *.class 3 | 4 | # Log file 5 | *.log 6 | 7 | # BlueJ files 8 | *.ctxt 9 | 10 | # Mobile Tools for Java (J2ME) 11 | .mtj.tmp/ 12 | 13 | # Package Files # 14 | *.jar 15 | *.war 16 | *.nar 17 | *.ear 18 | *.zip 19 | *.tar.gz 20 | *.rar 21 | 22 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 23 | hs_err_pid* 24 | -------------------------------------------------------------------------------- /src/test/resources/mysql/application.yaml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8080 3 | netty: 4 | mysql: 5 | enabled: true 6 | mysql-host: 192.168.101.189 7 | mysql-port: 3306 8 | backend-business-handler: com.github.netty.mysql.example.MysqlBackendHandler 9 | frontend-business-handler: com.github.netty.mysql.example.MysqlFrontendHandler 10 | proxy-log: 11 | enable: true 12 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/protocol/nrpc/service/RpcCommandServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.protocol.nrpc.service; 2 | 3 | /** 4 | * RpcCommandServiceImpl 5 | * 6 | * @author wangzihao 7 | * 2018/8/20/020 8 | */ 9 | public class RpcCommandServiceImpl implements RpcCommandService { 10 | 11 | @Override 12 | public byte[] ping() { 13 | return "ok".getBytes(); 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/protocol/servlet/ServletResetBufferIOException.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.protocol.servlet; 2 | 3 | import jakarta.servlet.http.HttpServletResponse; 4 | 5 | import java.io.IOException; 6 | 7 | /** 8 | * @author wangzihaogithub 9 | * 2020-06-07 00:07:16 10 | * @see HttpServletResponse#resetBuffer() 11 | */ 12 | public class ServletResetBufferIOException extends IOException { 13 | } 14 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/core/util/LoggerFactoryX.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.core.util; 2 | 3 | /** 4 | * @author wangzihao 5 | * 2018/8/25/025 6 | */ 7 | public class LoggerFactoryX { 8 | 9 | public static LoggerX getLogger(Class clazz) { 10 | return new LoggerX(clazz); 11 | } 12 | 13 | public static LoggerX getLogger(String clazz) { 14 | return new LoggerX(clazz); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/annotation/NRpcParam.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.annotation; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * RPC parameter note :(used on the client interface, not required on the server) 7 | */ 8 | @Target({ElementType.PARAMETER, ElementType.ANNOTATION_TYPE}) 9 | @Retention(RetentionPolicy.RUNTIME) 10 | @Documented 11 | public @interface NRpcParam { 12 | String value() default ""; 13 | } -------------------------------------------------------------------------------- /src/main/java/org/springframework/web/socket/server/standard/TomcatRequestUpgradeStrategy.java: -------------------------------------------------------------------------------- 1 | package org.springframework.web.socket.server.standard; 2 | 3 | import com.github.netty.springboot.server.NettyRequestUpgradeStrategy; 4 | 5 | public class TomcatRequestUpgradeStrategy extends NettyRequestUpgradeStrategy { 6 | @Override 7 | public String toString() { 8 | return "NettyRequestUpgradeStrategy"; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/test/java/com/github/netty/javadubbo/ClientFilter.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.javadubbo; 2 | 3 | import org.apache.dubbo.rpc.*; 4 | 5 | public class ClientFilter implements org.apache.dubbo.rpc.Filter { 6 | @Override 7 | public Result invoke(Invoker invoker, Invocation invocation) throws RpcException { 8 | invoker.getUrl().addParameter("proxy-app", "order-service"); 9 | return invoker.invoke(invocation); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/protocol/mqtt/MemoryQueueRepository.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.protocol.mqtt; 2 | 3 | import java.util.Queue; 4 | import java.util.concurrent.ConcurrentLinkedQueue; 5 | 6 | public class MemoryQueueRepository implements IQueueRepository { 7 | 8 | @Override 9 | public Queue createQueue(String clientId, boolean clean) { 10 | return new ConcurrentLinkedQueue<>(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/core/util/Wrapper.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.core.util; 2 | 3 | /** 4 | * Wrapper 5 | * 6 | * @author wangzihao 7 | * 2018/7/31/031 8 | */ 9 | public interface Wrapper { 10 | 11 | /** 12 | * wrap 13 | * 14 | * @param source source object 15 | */ 16 | void wrap(T source); 17 | 18 | /** 19 | * get source object 20 | * 21 | * @return source object 22 | */ 23 | T unwrap(); 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/protocol/nrpc/service/RpcCommandAsyncService.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.protocol.nrpc.service; 2 | 3 | import com.github.netty.annotation.NRpcService; 4 | import org.reactivestreams.Publisher; 5 | 6 | /** 7 | * RpcCommandAsyncService 8 | * 9 | * @author wangzihao 10 | * 2020/4/23/020 11 | */ 12 | @NRpcService(value = "/_nrpc/command", timeout = 600) 13 | public interface RpcCommandAsyncService { 14 | 15 | Publisher ping(); 16 | } 17 | -------------------------------------------------------------------------------- /src/test/resources/nrpc/client/application.yaml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8081 3 | netty: 4 | nrpc: 5 | client-default-version: my1.0 6 | client-enable-heart-log: true 7 | client-heart-interval-time-ms: -1 8 | client-connect-timeout: 1000 9 | client-server-response-timeout: 1000 10 | client-reconnect-scheduled-task-enable: false 11 | client-reconnect-scheduled-interval-ms: 5000 12 | codec: fastjson 13 | spring: 14 | application: 15 | name: nrpc-client -------------------------------------------------------------------------------- /src/main/java/com/github/netty/protocol/nrpc/service/RpcCommandService.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.protocol.nrpc.service; 2 | 3 | import com.github.netty.annotation.NRpcService; 4 | 5 | /** 6 | * RpcCommandService 7 | * 8 | * @author wangzihao 9 | * 2018/8/20/020 10 | */ 11 | @NRpcService(value = "/_nrpc/command", timeout = 600) 12 | public interface RpcCommandService { 13 | 14 | /** 15 | * ping 16 | * 17 | * @return byte[] 18 | */ 19 | byte[] ping(); 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/protocol/nrpc/Emitter.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.protocol.nrpc; 2 | 3 | import java.util.concurrent.CompletableFuture; 4 | 5 | public interface Emitter { 6 | CompletableFuture send(CHUNK chunk, Class responseType, int responseTimeout); 7 | 8 | void send(CHUNK chunk); 9 | 10 | boolean complete(RESULT completeResult); 11 | 12 | boolean complete(Throwable throwable); 13 | 14 | boolean isComplete(); 15 | 16 | int getSendCount(); 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/springboot/client/NettyRpcLoadBalanced.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.springboot.client; 2 | 3 | import java.net.InetSocketAddress; 4 | 5 | /** 6 | * Load balancing 7 | * 8 | * @author wangzihao 9 | */ 10 | @FunctionalInterface 11 | public interface NettyRpcLoadBalanced { 12 | 13 | /** 14 | * Pick an IP address 15 | * 16 | * @param request request 17 | * @return The IP address 18 | */ 19 | InetSocketAddress chooseAddress(NettyRpcRequest request); 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/test/java/com/github/netty/nrpc/api/HelloData.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.nrpc.api; 2 | 3 | import java.io.Serializable; 4 | 5 | public class HelloData implements Serializable { 6 | private String say; 7 | 8 | public String getSay() { 9 | return say; 10 | } 11 | 12 | public void setSay(String say) { 13 | this.say = say; 14 | } 15 | 16 | @Override 17 | public String toString() { 18 | return "Response{" + 19 | "say='" + say + '\'' + 20 | '}'; 21 | } 22 | } -------------------------------------------------------------------------------- /src/main/java/com/github/netty/protocol/mysql/listener/MysqlPacketListener.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.protocol.mysql.listener; 2 | 3 | import com.github.netty.protocol.mysql.MysqlPacket; 4 | import com.github.netty.protocol.mysql.Session; 5 | import io.netty.channel.ChannelHandlerContext; 6 | 7 | @FunctionalInterface 8 | public interface MysqlPacketListener { 9 | 10 | void onMysqlPacket(MysqlPacket packet, 11 | ChannelHandlerContext currentContext, 12 | Session session, 13 | String handlerType); 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/io/netty/channel/epoll/EpollUtils.java: -------------------------------------------------------------------------------- 1 | package io.netty.channel.epoll; 2 | 3 | import io.netty.channel.Channel; 4 | 5 | public class EpollUtils { 6 | 7 | public static boolean forceFlush(Channel.Unsafe unsafe) { 8 | if (unsafe instanceof AbstractEpollChannel.AbstractEpollUnsafe) { 9 | AbstractEpollChannel.AbstractEpollUnsafe epollUnsafe = (AbstractEpollChannel.AbstractEpollUnsafe) unsafe; 10 | epollUnsafe.epollOutReady(); 11 | return true; 12 | } else { 13 | return false; 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/io/netty/channel/kqueue/KqueueUtils.java: -------------------------------------------------------------------------------- 1 | package io.netty.channel.kqueue; 2 | 3 | import io.netty.channel.Channel; 4 | 5 | public class KqueueUtils { 6 | 7 | public static boolean forceFlush(Channel.Unsafe unsafe) { 8 | if (unsafe instanceof AbstractKQueueChannel.AbstractKQueueUnsafe) { 9 | AbstractKQueueChannel.AbstractKQueueUnsafe epollUnsafe = (AbstractKQueueChannel.AbstractKQueueUnsafe) unsafe; 10 | epollUnsafe.flush0(); 11 | return true; 12 | } else { 13 | return false; 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/protocol/dubbo/packet/BodyEvent.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.protocol.dubbo.packet; 2 | 3 | import com.github.netty.protocol.dubbo.Body; 4 | 5 | public class BodyEvent extends Body { 6 | 7 | private final Object event; 8 | 9 | public BodyEvent(Object event) { 10 | this.event = event; 11 | } 12 | 13 | public Object getEvent() { 14 | return event; 15 | } 16 | 17 | @Override 18 | public String toString() { 19 | return "BodyEvent{" + 20 | "\n\tevent=" + event + 21 | "\n}"; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/test/java/com/github/netty/javaxservlet/example/MyHttpServlet.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.javaxservlet.example; 2 | 3 | import jakarta.servlet.ServletException; 4 | import jakarta.servlet.http.HttpServlet; 5 | import jakarta.servlet.http.HttpServletRequest; 6 | import jakarta.servlet.http.HttpServletResponse; 7 | 8 | import java.io.IOException; 9 | 10 | public class MyHttpServlet extends HttpServlet { 11 | @Override 12 | protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 13 | resp.getWriter().write("hi! doGet"); 14 | } 15 | } -------------------------------------------------------------------------------- /src/main/java/com/github/netty/protocol/dubbo/serialization/AllowClassNotifyListener.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.protocol.dubbo.serialization; 2 | 3 | import java.util.Set; 4 | 5 | public interface AllowClassNotifyListener { 6 | 7 | // SerializeCheckStatus DEFAULT_STATUS = SerializeCheckStatus.STRICT; 8 | SerializeCheckStatus DEFAULT_STATUS = SerializeCheckStatus.DISABLE; 9 | 10 | void notifyPrefix(Set allowedList, Set disAllowedList); 11 | 12 | void notifyCheckStatus(SerializeCheckStatus status); 13 | 14 | void notifyCheckSerializable(boolean checkSerializable); 15 | 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/protocol/nrpc/exception/RpcWriteException.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.protocol.nrpc.exception; 2 | 3 | /** 4 | * RpcWriteException 5 | * 6 | * @author wangzihao 7 | * 2019/11/03/022 8 | */ 9 | public class RpcWriteException extends RpcException { 10 | 11 | public RpcWriteException(String message) { 12 | this(message, null); 13 | } 14 | 15 | public RpcWriteException(String message, Throwable cause) { 16 | super(message, cause, false, false); 17 | if (cause != null) { 18 | setStackTrace(cause.getStackTrace()); 19 | } 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/test/java/com/github/netty/nrpc/client/HelloRxjava3AsyncClient.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.nrpc.client; 2 | 3 | import com.github.netty.nrpc.api.HelloData; 4 | import com.github.netty.springboot.NettyRpcClient; 5 | import io.reactivex.rxjava3.core.Flowable; 6 | import io.reactivex.rxjava3.core.Observable; 7 | import org.springframework.web.bind.annotation.RequestMapping; 8 | 9 | @NettyRpcClient(serviceName = "nrpc-server",timeout = 100) 10 | @RequestMapping("/hello") 11 | public interface HelloRxjava3AsyncClient { 12 | Observable sayHello(String name, int id); 13 | Flowable sayHello1(String name); 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/protocol/nrpc/exception/RpcDecodeException.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.protocol.nrpc.exception; 2 | 3 | /** 4 | * RpcDecodeException 5 | * 6 | * @author wangzihao 7 | * 2018/8/20/020 8 | */ 9 | public class RpcDecodeException extends RpcException { 10 | 11 | public RpcDecodeException(String message) { 12 | this(message, null); 13 | } 14 | 15 | public RpcDecodeException(String message, Throwable cause) { 16 | super(message, cause, false, false); 17 | if (cause != null) { 18 | setStackTrace(cause.getStackTrace()); 19 | } 20 | } 21 | 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/protocol/nrpc/exception/RpcEncodeException.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.protocol.nrpc.exception; 2 | 3 | /** 4 | * RpcEncodeException 5 | * 6 | * @author wangzihao 7 | * 2018/8/20/020 8 | */ 9 | public class RpcEncodeException extends RpcException { 10 | 11 | public RpcEncodeException(String message) { 12 | this(message, null); 13 | } 14 | 15 | public RpcEncodeException(String message, Throwable cause) { 16 | super(message, cause, false, false); 17 | if (cause != null) { 18 | setStackTrace(cause.getStackTrace()); 19 | } 20 | } 21 | 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/protocol/nrpc/exception/RpcConnectException.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.protocol.nrpc.exception; 2 | 3 | /** 4 | * RpcConnectException 5 | * 6 | * @author wangzihao 7 | * 2018/8/21/021 8 | */ 9 | public class RpcConnectException extends RpcException { 10 | 11 | public RpcConnectException(String message) { 12 | super(message, null, false, false); 13 | } 14 | 15 | public RpcConnectException(String message, Throwable cause) { 16 | super(message, cause, false, false); 17 | if (cause != null) { 18 | setStackTrace(cause.getStackTrace()); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/test/resources/springdubbo/application.yaml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8080 3 | servlet: 4 | context-path: '/test' 5 | netty: 6 | enable-tcp-package-log: false 7 | max-connections: 1000000 8 | #内存泄露追踪。 调试用, 默认关闭 9 | resource-leak-detector-level: PARANOID 10 | dubbo: 11 | enabled: true 12 | routes: 13 | - path-patterns: 'com.github.netty.springdubbo.example.**' 14 | address: '127.0.0.1:8002' 15 | - application-name: 'order-service' 16 | address: '127.0.0.1:8002' 17 | - application-name: 'pay-service' 18 | address: '127.0.0.1:8002' 19 | default-application: true -------------------------------------------------------------------------------- /src/main/java/com/github/netty/protocol/dubbo/packet/BodyFail.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.protocol.dubbo.packet; 2 | 3 | import com.github.netty.protocol.dubbo.Body; 4 | 5 | public class BodyFail extends Body { 6 | private final String errorMessage; 7 | 8 | public BodyFail(String errorMessage) { 9 | this.errorMessage = errorMessage; 10 | } 11 | 12 | public String getErrorMessage() { 13 | return errorMessage; 14 | } 15 | 16 | @Override 17 | public String toString() { 18 | return "BodyFail{" + 19 | "\n\terrorMessage='" + errorMessage + '\'' + 20 | "\n}"; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/protocol/mqtt/MqttRetainedMessage.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.protocol.mqtt; 2 | 3 | import io.netty.handler.codec.mqtt.MqttQoS; 4 | 5 | import java.io.Serializable; 6 | 7 | public class MqttRetainedMessage implements Serializable { 8 | 9 | private final MqttQoS qos; 10 | private final byte[] payload; 11 | 12 | public MqttRetainedMessage(MqttQoS qos, byte[] payload) { 13 | this.qos = qos; 14 | this.payload = payload; 15 | } 16 | 17 | public MqttQoS qosLevel() { 18 | return qos; 19 | } 20 | 21 | public byte[] getPayload() { 22 | return payload; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/core/util/AsmMethodToParameterNamesFunction.java: -------------------------------------------------------------------------------- 1 | //package com.github.netty.core.util; 2 | // 3 | //import java.lang.reflect.Method; 4 | //import java.util.function.Function; 5 | // 6 | ///** 7 | // * ASM - based method variable parameter name function 8 | // * @author wangzihao 9 | // */ 10 | //public class AsmMethodToParameterNamesFunction implements Function { 11 | // private ParameterNameDiscoverer parameterNameDiscoverer = new ParameterNameDiscoverer(); 12 | // @Override 13 | // public String[] apply(Method method) { 14 | // return parameterNameDiscoverer.getParameterNames(method); 15 | // } 16 | //} 17 | -------------------------------------------------------------------------------- /src/test/java/com/github/netty/javadubbo/Server.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.javadubbo; 2 | 3 | import org.springframework.context.support.ClassPathXmlApplicationContext; 4 | 5 | import java.net.URL; 6 | 7 | public class Server { 8 | private static final URL CONFIG_URL = Server.class.getResource( 9 | "/javadubbo/dubbo-server.xml"); 10 | 11 | public static void main(String[] args) throws Exception { 12 | ClassPathXmlApplicationContext classPathXmlApplicationContext = new 13 | ClassPathXmlApplicationContext(CONFIG_URL.toString()); 14 | classPathXmlApplicationContext.start(); 15 | System.in.read(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/test/java/com/github/netty/springdubbo/Server.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.springdubbo; 2 | 3 | import org.springframework.context.support.ClassPathXmlApplicationContext; 4 | 5 | import java.net.URL; 6 | 7 | public class Server { 8 | private static final URL CONFIG_URL = Server.class.getResource( 9 | "/springdubbo/dubbo-server.xml"); 10 | 11 | public static void main(String[] args) throws Exception { 12 | ClassPathXmlApplicationContext classPathXmlApplicationContext = new 13 | ClassPathXmlApplicationContext(CONFIG_URL.toString()); 14 | classPathXmlApplicationContext.start(); 15 | System.in.read(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/test/java/com/github/netty/nrpc/client/HelloAsyncClient.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.nrpc.client; 2 | 3 | import com.github.netty.nrpc.api.HelloData; 4 | import com.github.netty.springboot.NettyRpcClient; 5 | import org.reactivestreams.Publisher; 6 | import org.springframework.web.bind.annotation.RequestMapping; 7 | 8 | import java.util.concurrent.CompletableFuture; 9 | 10 | @NettyRpcClient(serviceName = "nrpc-server",timeout = 100) 11 | @RequestMapping("/hello") 12 | public interface HelloAsyncClient{ 13 | @RequestMapping("sayHello") 14 | Publisher sayHelloByTest(String name, int id); 15 | 16 | CompletableFuture sayHello1(String name, int id); 17 | 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/core/util/Recyclable.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.core.util; 2 | 3 | import java.util.function.Consumer; 4 | 5 | /** 6 | * recycled 7 | * 8 | * @author wangzihao 9 | */ 10 | public interface Recyclable { 11 | 12 | /** 13 | * recycle 14 | */ 15 | default void recycle() { 16 | } 17 | 18 | /** 19 | * async recycle 20 | * 21 | * @param consumer callback 22 | * @param last recycle object 23 | */ 24 | default void recycle(Consumer consumer) { 25 | if (consumer == null) { 26 | recycle(); 27 | } else { 28 | consumer.accept(null); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/protocol/servlet/ServletClientAbortException.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.protocol.servlet; 2 | 3 | import java.io.IOException; 4 | 5 | public final class ServletClientAbortException extends IOException { 6 | private static final long serialVersionUID = 1L; 7 | 8 | public ServletClientAbortException() { 9 | } 10 | 11 | public ServletClientAbortException(String message) { 12 | super(message); 13 | } 14 | 15 | public ServletClientAbortException(Throwable throwable) { 16 | super(throwable); 17 | } 18 | 19 | public ServletClientAbortException(String message, Throwable throwable) { 20 | super(message, throwable); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/io/netty/channel/ChannelUtils.java: -------------------------------------------------------------------------------- 1 | package io.netty.channel; 2 | 3 | import io.netty.channel.epoll.EpollUtils; 4 | import io.netty.channel.kqueue.KqueueUtils; 5 | import io.netty.channel.nio.AbstractNioChannel; 6 | 7 | public class ChannelUtils { 8 | 9 | public static void forceFlush(Channel channel) { 10 | Channel.Unsafe unsafe = channel.unsafe(); 11 | if (EpollUtils.forceFlush(unsafe)) { 12 | return; 13 | } 14 | if (KqueueUtils.forceFlush(unsafe)) { 15 | return; 16 | } 17 | if (unsafe instanceof AbstractNioChannel.NioUnsafe) { 18 | ((AbstractNioChannel.NioUnsafe) unsafe).forceFlush(); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/test/java/com/github/netty/mysql/MysqlBootstrap.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.mysql; 2 | 3 | import com.github.netty.springboot.EnableNettyEmbedded; 4 | import org.springframework.boot.SpringApplication; 5 | import org.springframework.boot.autoconfigure.SpringBootApplication; 6 | 7 | import java.net.URL; 8 | 9 | @EnableNettyEmbedded 10 | @SpringBootApplication 11 | public class MysqlBootstrap { 12 | private static final URL CONFIG_URL = MysqlBootstrap.class.getResource( 13 | "/mysql/application.yaml"); 14 | 15 | public static void main(String[] args) { 16 | System.getProperties().put("spring.config.location",CONFIG_URL.toString()); 17 | SpringApplication.run(MysqlBootstrap.class,args); 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/protocol/dubbo/serialization/SerializeCheckStatus.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.protocol.dubbo.serialization; 2 | 3 | public enum SerializeCheckStatus { 4 | /** 5 | * Disable serialize check for all classes 6 | */ 7 | DISABLE(0), 8 | 9 | /** 10 | * Only deny danger classes, warn if other classes are not in allow list 11 | */ 12 | WARN(1), 13 | 14 | /** 15 | * Only allow classes in allow list, deny if other classes are not in allow list 16 | */ 17 | STRICT(2); 18 | 19 | private final int level; 20 | 21 | SerializeCheckStatus(int level) { 22 | this.level = level; 23 | } 24 | 25 | public int level() { 26 | return level; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/test/java/com/github/netty/nrpc/api/HelloDTO.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.nrpc.api; 2 | 3 | import java.io.Serializable; 4 | 5 | public class HelloDTO implements Serializable { 6 | private String name; 7 | private Integer id; 8 | 9 | public String getName() { 10 | return name; 11 | } 12 | 13 | public void setName(String name) { 14 | this.name = name; 15 | } 16 | 17 | public Integer getId() { 18 | return id; 19 | } 20 | 21 | public void setId(Integer id) { 22 | this.id = id; 23 | } 24 | @Override 25 | public String toString() { 26 | return "Request{" + 27 | "name='" + name + '\'' + 28 | ", id=" + id + 29 | '}'; 30 | } 31 | } -------------------------------------------------------------------------------- /src/test/java/com/github/netty/springdubbo/DubboBootstrap.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.springdubbo; 2 | 3 | import com.github.netty.springboot.EnableNettyEmbedded; 4 | import org.springframework.boot.SpringApplication; 5 | import org.springframework.boot.autoconfigure.SpringBootApplication; 6 | 7 | import java.net.URL; 8 | 9 | @EnableNettyEmbedded 10 | @SpringBootApplication 11 | public class DubboBootstrap { 12 | private static final URL CONFIG_URL = DubboBootstrap.class.getResource( 13 | "/springdubbo/application.yaml"); 14 | 15 | public static void main(String[] args) { 16 | System.getProperties().put("spring.config.location",CONFIG_URL.toString()); 17 | SpringApplication.run(DubboBootstrap.class,args); 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/springboot/client/NettyRpcFullRequest.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.springboot.client; 2 | 3 | import com.github.netty.protocol.nrpc.RpcClient; 4 | import com.github.netty.protocol.nrpc.RpcMethod; 5 | 6 | import java.net.InetSocketAddress; 7 | import java.util.Map; 8 | 9 | /** 10 | * Information about the RPC full request 11 | * 12 | * @author wangzihao 2020/4/26 13 | */ 14 | public interface NettyRpcFullRequest extends NettyRpcRequest { 15 | RpcClient getRpcClient(); 16 | 17 | RpcClient.Sender getSender(); 18 | 19 | RpcMethod getRpcMethod(); 20 | 21 | Map> getRpcMethodMap(); 22 | 23 | InetSocketAddress getRemoteAddress(); 24 | 25 | Object getResponse() throws Throwable; 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/springboot/NettyRpcClient.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.springboot; 2 | 3 | import org.springframework.stereotype.Component; 4 | 5 | import java.lang.annotation.*; 6 | 7 | @Retention(RetentionPolicy.RUNTIME) 8 | @Target(ElementType.TYPE) 9 | @Documented 10 | @Component 11 | public @interface NettyRpcClient { 12 | /** 13 | * The serviceName is the same as serviceName 14 | * example value "service-provider" 15 | * 16 | * @return serviceName 17 | */ 18 | String serviceName(); 19 | 20 | // Class fallback() default void.class; 21 | 22 | /** 23 | * Timeout time (milliseconds) 24 | * 25 | * @return timeout 26 | */ 27 | int timeout() default -1; 28 | 29 | // int retry() default -1; 30 | 31 | } 32 | -------------------------------------------------------------------------------- /src/test/java/com/github/netty/nrpc/server/NRpcServerBootstrap.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.nrpc.server; 2 | 3 | import com.github.netty.springboot.EnableNettyEmbedded; 4 | import org.springframework.boot.SpringApplication; 5 | import org.springframework.boot.autoconfigure.SpringBootApplication; 6 | 7 | import java.net.URL; 8 | 9 | @EnableNettyEmbedded 10 | @SpringBootApplication 11 | public class NRpcServerBootstrap { 12 | private static final URL CONFIG_URL = NRpcServerBootstrap.class.getResource( 13 | "/nrpc/server/application.yaml"); 14 | 15 | public static void main(String[] args) { 16 | System.getProperties().put("spring.config.location",CONFIG_URL.toString()); 17 | SpringApplication.run(NRpcServerBootstrap.class,args); 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/springboot/client/NettyRpcFilter.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.springboot.client; 2 | 3 | import java.util.Collections; 4 | import java.util.List; 5 | 6 | /** 7 | * Information about the RPC request 8 | * 9 | * @author wangzihao 10 | */ 11 | @FunctionalInterface 12 | public interface NettyRpcFilter { 13 | 14 | void doFilter(NettyRpcFullRequest request, FilterChain chain) throws Throwable; 15 | 16 | interface FilterChain { 17 | void doFilter(NettyRpcFullRequest request) throws Throwable; 18 | 19 | /** 20 | * get a unmodifiable NettyRpcFilterList {@link Collections#unmodifiableList(List)} 21 | * 22 | * @return NettyRpcFilter 23 | */ 24 | List getNettyRpcFilterList(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/protocol/nrpc/RpcClientRxjava3Flowable.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.protocol.nrpc; 2 | 3 | import io.reactivex.rxjava3.annotations.NonNull; 4 | import io.reactivex.rxjava3.core.Flowable; 5 | import org.reactivestreams.Subscriber; 6 | 7 | /** 8 | * support rxjava3 Flowable async response. 9 | * 10 | * @author wangzihao 11 | * 2020/05/17/019 12 | */ 13 | public class RpcClientRxjava3Flowable extends Flowable { 14 | private final RpcClientReactivePublisher source; 15 | 16 | RpcClientRxjava3Flowable(RpcClientReactivePublisher source) { 17 | this.source = source; 18 | } 19 | 20 | @Override 21 | protected void subscribeActual(@NonNull Subscriber subscriber) { 22 | source.subscribe(subscriber); 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/test/java/com/github/netty/http/example/CommonsMultipartResolverForProgress.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.http.example; 2 | 3 | import jakarta.servlet.http.HttpServletRequest; 4 | import org.springframework.stereotype.Component; 5 | import org.springframework.web.multipart.support.StandardServletMultipartResolver; 6 | 7 | /** 8 | * 防止spring触发body解析 9 | * https://github.com/wangzihaogithub/spring-boot-protocol/issues/12 10 | */ 11 | @Component 12 | public class CommonsMultipartResolverForProgress extends StandardServletMultipartResolver { 13 | @Override 14 | public boolean isMultipart(HttpServletRequest request) { 15 | if (request.getRequestURI().startsWith("/test/uploadForApache")) { 16 | return false; 17 | } 18 | return super.isMultipart(request); 19 | } 20 | } -------------------------------------------------------------------------------- /src/test/java/com/github/netty/mqtt/MqttBrokerBootstrap.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.mqtt; 2 | 3 | import com.github.netty.springboot.EnableNettyEmbedded; 4 | import org.springframework.boot.SpringApplication; 5 | import org.springframework.boot.autoconfigure.SpringBootApplication; 6 | 7 | import java.net.URL; 8 | 9 | @EnableNettyEmbedded 10 | @SpringBootApplication 11 | public class MqttBrokerBootstrap { 12 | private static final URL CONFIG_URL = MqttBrokerBootstrap.class.getResource( 13 | "/mqtt/application.yaml"); 14 | public static final int PORT = 8080; 15 | 16 | public static void main(String[] args) { 17 | System.getProperties().put("spring.config.location", CONFIG_URL.toString()); 18 | SpringApplication.run(MqttBrokerBootstrap.class, args); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/protocol/servlet/util/InstanceFactory.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.protocol.servlet.util; 2 | 3 | public interface InstanceFactory { 4 | InstanceFactory DEFAULT = new InstanceFactory() { 5 | @Override 6 | public Object newInstance(String className) throws ReflectiveOperationException { 7 | Class clazz = Class.forName(className); 8 | return newInstance(clazz); 9 | } 10 | 11 | @Override 12 | public T newInstance(Class clazz) throws ReflectiveOperationException { 13 | return clazz.getDeclaredConstructor().newInstance(); 14 | } 15 | }; 16 | 17 | Object newInstance(String className) throws ReflectiveOperationException; 18 | 19 | T newInstance(Class clazz) throws ReflectiveOperationException; 20 | } -------------------------------------------------------------------------------- /src/main/java/com/github/netty/protocol/mqtt/exception/MqttException.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.protocol.mqtt.exception; 2 | 3 | public class MqttException extends RuntimeException { 4 | private static final long serialVersionUID = 5848069213104389412L; 5 | 6 | public MqttException() { 7 | super(); 8 | } 9 | 10 | public MqttException(String message) { 11 | super(message); 12 | } 13 | 14 | public MqttException(String message, Throwable cause) { 15 | super(message, cause); 16 | } 17 | 18 | public MqttException(Throwable cause) { 19 | super(cause); 20 | } 21 | 22 | public MqttException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { 23 | super(message, cause, enableSuppression, writableStackTrace); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/protocol/nrpc/exception/RpcResponseException.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.protocol.nrpc.exception; 2 | 3 | /** 4 | * RpcResponseException 5 | * 6 | * @author wangzihao 7 | * 2018/8/21/021 8 | */ 9 | public class RpcResponseException extends RpcException { 10 | /** 11 | * Error status code 12 | */ 13 | private Integer status; 14 | 15 | public RpcResponseException(Integer status, String message) { 16 | super(message, null, false, false); 17 | this.status = status; 18 | } 19 | 20 | public RpcResponseException(Integer status, String message, boolean writableStackTrace) { 21 | super(message, null, false, writableStackTrace); 22 | this.status = status; 23 | } 24 | 25 | public Integer getStatus() { 26 | return status; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/test/java/com/github/netty/http/HttpTests.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.http; 2 | 3 | import com.github.netty.core.util.IOUtil; 4 | import org.junit.jupiter.api.Test; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.util.Assert; 7 | 8 | import java.io.IOException; 9 | import java.io.InputStream; 10 | import java.net.URL; 11 | import java.util.Objects; 12 | 13 | @SpringBootTest(classes = HttpTests.class) 14 | public class HttpTests { 15 | @Test 16 | public void test() throws IOException { 17 | URL url = new URL("http://localhost:8080/hello?name=xiaowang"); 18 | InputStream inputStream = url.openStream(); 19 | String responseBody = IOUtil.readInput(inputStream); 20 | Assert.isTrue(Objects.equals("hi! xiaowang", responseBody),"no hi! xiaowang"); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/protocol/nrpc/exception/RpcException.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.protocol.nrpc.exception; 2 | 3 | /** 4 | * RpcException 5 | * 6 | * @author wangzihao 7 | * 2018/8/20/020 8 | */ 9 | public class RpcException extends RuntimeException { 10 | 11 | public RpcException() { 12 | super(); 13 | } 14 | 15 | public RpcException(String message) { 16 | super(message); 17 | } 18 | 19 | public RpcException(String message, Throwable cause) { 20 | super(message, cause); 21 | } 22 | 23 | public RpcException(Throwable cause) { 24 | super(cause); 25 | } 26 | 27 | public RpcException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { 28 | super(message, cause, enableSuppression, writableStackTrace); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/test/java/com/github/netty/stomp/WebsocketStompBootstrap.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.stomp; 2 | 3 | import com.github.netty.springboot.EnableNettyEmbedded; 4 | import org.springframework.boot.SpringApplication; 5 | import org.springframework.boot.autoconfigure.SpringBootApplication; 6 | 7 | import java.net.URL; 8 | 9 | /** 10 | * Websocket server 11 | * @author wangzihao 12 | */ 13 | @EnableNettyEmbedded 14 | @SpringBootApplication 15 | public class WebsocketStompBootstrap { 16 | private static final URL CONFIG_URL = WebsocketStompBootstrap.class.getResource( 17 | "/stomp/application.yaml"); 18 | 19 | public static void main(String[] args) { 20 | System.getProperties().put("spring.config.location",CONFIG_URL.toString()); 21 | SpringApplication.run(WebsocketStompBootstrap.class,args); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/core/ServerListener.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.core; 2 | 3 | import io.netty.bootstrap.ServerBootstrap; 4 | 5 | /** 6 | * Server listening 7 | * Created by wangzihao on 2018/11/12/012. 8 | */ 9 | public interface ServerListener extends Ordered { 10 | 11 | default void onServerStart(T server) throws Exception { 12 | } 13 | 14 | default void onServerStop(T server) throws Exception { 15 | } 16 | 17 | default void config(ServerBootstrap bootstrap) throws Exception { 18 | } 19 | 20 | /** 21 | * default Priority order 0 22 | * 23 | * @return The smaller the value of order, the more likely it is to be executed first 24 | */ 25 | @Override 26 | default int getOrder() { 27 | return 0; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/test/resources/http/application.yaml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8080 3 | # port: 443 4 | # servlet: 5 | # context-path: '/test' 6 | # http2: 7 | # enabled: true 8 | # ssl: 9 | # key-store: 'classpath:http/mydomain.com.jks' 10 | # key-store-password: 'classpath:http/jks-password.txt' 11 | # key-store-type: 'JKS' 12 | 13 | netty: 14 | enable-tcp-package-log: false 15 | max-connections: 1000000 16 | #内存泄露追踪。 调试用, 默认关闭 17 | # resource-leak-detector-level: PARANOID 18 | # file static 静态文件资源文件夹 19 | http-servlet: 20 | basedir: '/Users/edy/Desktop/webapp' 21 | tomcat: 22 | max-http-form-post-size: -1 23 | 24 | spring: 25 | servlet: 26 | multipart: 27 | #请求头的上限 28 | max-request-size: 10GB 29 | #请求体的上限 30 | max-file-size: 10GB 31 | #超过多少大小,就把请求体放在文件存储。 32 | file-size-threshold: 2MB -------------------------------------------------------------------------------- /src/test/java/com/github/netty/http/HttpTests2.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.http; 2 | 3 | import cn.hutool.http.HttpUtil; 4 | import org.junit.jupiter.api.Test; 5 | import org.springframework.util.Assert; 6 | 7 | import java.io.IOException; 8 | import java.util.Objects; 9 | 10 | //@SpringBootTest(classes = HttpTests2.class) 11 | public class HttpTests2 { 12 | @Test 13 | public void test() throws IOException { 14 | String responseBody = HttpUtil.get("http://localhost:8080/hello?name=xiaowang"); 15 | System.out.println(responseBody); 16 | // URL url = new URL("http://localhost:8080/hello?name=xiaowang"); 17 | // InputStream inputStream = url.openStream(); 18 | // String responseBody = IOUtil.readInput(inputStream); 19 | Assert.isTrue(Objects.equals("hi! xiaowang", responseBody),"no hi! xiaowang"); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/protocol/nrpc/ChunkAck.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.protocol.nrpc; 2 | 3 | import io.netty.util.concurrent.GlobalEventExecutor; 4 | import io.netty.util.concurrent.Promise; 5 | 6 | public interface ChunkAck { 7 | ChunkAck DONT_NEED_ACK = new ChunkAck() { 8 | @Override 9 | public Promise ack(Object ack) { 10 | Promise promise = GlobalEventExecutor.INSTANCE.newPromise(); 11 | promise.setSuccess(null); 12 | return promise; 13 | } 14 | 15 | @Override 16 | public void ack() { 17 | 18 | } 19 | 20 | @Override 21 | public boolean isAck() { 22 | return true; 23 | } 24 | }; 25 | 26 | Promise ack(Object ack); 27 | 28 | boolean isAck(); 29 | 30 | default void ack() { 31 | ack(null); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/test/java/com/github/netty/nrpc/client/example/HelloNettyRpcLoadBalanced.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.nrpc.client.example; 2 | 3 | import com.github.netty.springboot.client.NettyRpcLoadBalanced; 4 | import com.github.netty.springboot.client.NettyRpcRequest; 5 | 6 | import java.net.InetSocketAddress; 7 | import java.util.List; 8 | import java.util.Random; 9 | 10 | public class HelloNettyRpcLoadBalanced implements NettyRpcLoadBalanced { 11 | private final List remoteAddressList; 12 | private final Random random = new Random(); 13 | public HelloNettyRpcLoadBalanced(List remoteAddressList) { 14 | this.remoteAddressList = remoteAddressList; 15 | } 16 | 17 | @Override 18 | public InetSocketAddress chooseAddress(NettyRpcRequest request) { 19 | return remoteAddressList.get(random.nextInt(remoteAddressList.size())); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/protocol/servlet/websocket/WebSocketNotFoundHandlerEndpoint.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.protocol.servlet.websocket; 2 | 3 | import jakarta.websocket.CloseReason; 4 | import jakarta.websocket.Endpoint; 5 | import jakarta.websocket.EndpointConfig; 6 | import jakarta.websocket.Session; 7 | 8 | import java.io.IOException; 9 | 10 | public class WebSocketNotFoundHandlerEndpoint extends Endpoint { 11 | public static final WebSocketNotFoundHandlerEndpoint INSTANCE = new WebSocketNotFoundHandlerEndpoint(); 12 | 13 | @Override 14 | public void onOpen(Session session, EndpointConfig config) { 15 | session.getAsyncRemote().sendText("close! cause not found endpoint! "); 16 | try { 17 | session.close(new CloseReason(CloseReason.CloseCodes.UNEXPECTED_CONDITION, null)); 18 | } catch (IOException ignored) { 19 | 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/protocol/mysql/MysqlPacket.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 The Netty Project 3 | * 4 | * The Netty Project licenses this file to you under the Apache License, 5 | * version 2.0 (the "License"); you may not use this file except in compliance 6 | * with the License. You may obtain a copy of the License at: 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | 17 | package com.github.netty.protocol.mysql; 18 | 19 | public interface MysqlPacket { 20 | long getTimestamp(); 21 | 22 | int getSequenceId(); 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/annotation/NRpcMethod.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.annotation; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * RPC method 7 | */ 8 | @Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE}) 9 | @Retention(RetentionPolicy.RUNTIME) 10 | @Documented 11 | public @interface NRpcMethod { 12 | /** 13 | * method name. if empty then java method name 14 | * 15 | * @return method name. 16 | */ 17 | String value() default ""; 18 | 19 | /** 20 | * onTimeoutMayInterruptIfRunning 21 | * 22 | * @return true= Interrupt, false=no Interrupt 23 | */ 24 | boolean timeoutInterrupt() default false; 25 | 26 | /** 27 | * timeout is -1 then never timeout 28 | * timeout is 0 then use client timeout 29 | * timeout other then use server timeout 30 | * 31 | * @return method timeout 32 | */ 33 | int timeout() default -1; 34 | } -------------------------------------------------------------------------------- /src/main/java/com/github/netty/protocol/mqtt/interception/InterceptMessage.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012-2018 The original author or authors 3 | * ------------------------------------------------------ 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Apache License v2.0 which accompanies this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * 11 | * The Apache License v2.0 is available at 12 | * http://www.opensource.org/licenses/apache2.0.php 13 | * 14 | * You may elect to redistribute this code under either of these licenses. 15 | */ 16 | 17 | package com.github.netty.protocol.mqtt.interception; 18 | 19 | /** 20 | * An interface that sets the root of the interceptor messages type hierarchy. 21 | */ 22 | public interface InterceptMessage { 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/protocol/mysql/client/ClientPacket.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 The Netty Project 3 | * 4 | * The Netty Project licenses this file to you under the Apache License, 5 | * version 2.0 (the "License"); you may not use this file except in compliance 6 | * with the License. You may obtain a copy of the License at: 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | 17 | package com.github.netty.protocol.mysql.client; 18 | 19 | import com.github.netty.protocol.mysql.MysqlPacket; 20 | 21 | 22 | public interface ClientPacket extends MysqlPacket { 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/protocol/mysql/server/ServerPacket.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 The Netty Project 3 | * 4 | * The Netty Project licenses this file to you under the Apache License, 5 | * version 2.0 (the "License"); you may not use this file except in compliance 6 | * with the License. You may obtain a copy of the License at: 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | 17 | package com.github.netty.protocol.mysql.server; 18 | 19 | import com.github.netty.protocol.mysql.MysqlPacket; 20 | 21 | 22 | public interface ServerPacket extends MysqlPacket { 23 | } 24 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/protocol/mqtt/security/IAuthenticator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012-2018 The original author or authors 3 | * ------------------------------------------------------ 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Apache License v2.0 which accompanies this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * 11 | * The Apache License v2.0 is available at 12 | * http://www.opensource.org/licenses/apache2.0.php 13 | * 14 | * You may elect to redistribute this code under either of these licenses. 15 | */ 16 | 17 | package com.github.netty.protocol.mqtt.security; 18 | 19 | /** 20 | * username and password checker 21 | */ 22 | public interface IAuthenticator { 23 | 24 | boolean checkValid(String clientId, String username, byte[] password); 25 | } 26 | -------------------------------------------------------------------------------- /src/main/resources/server.properties: -------------------------------------------------------------------------------- 1 | # Licensed to the Apache Software Foundation (ASF) under one or more 2 | # contributor license agreements. See the NOTICE file distributed with 3 | # this work for additional information regarding copyright ownership. 4 | # The ASF licenses this file to You under the Apache License, Version 2.0 5 | # (the "License"); you may not use this file except in compliance with 6 | # the License. You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | server.info=Github Spring-boot3-protocol/3.3.34 17 | server.number=3.3.34 18 | server.built=Nov 28 2025 10:31:20 UTC+8 -------------------------------------------------------------------------------- /src/test/java/com/github/netty/javaxservlet/HttpBootstrap.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.javaxservlet; 2 | 3 | import com.github.netty.StartupServer; 4 | import com.github.netty.javaxservlet.example.MyHttpServlet; 5 | import com.github.netty.protocol.HttpServletProtocol; 6 | import com.github.netty.protocol.servlet.ServletContext; 7 | 8 | public class HttpBootstrap { 9 | 10 | public static void main(String[] args) { 11 | StartupServer server = new StartupServer(80); 12 | server.addProtocol(newHttpProtocol()); 13 | server.start(); 14 | } 15 | 16 | private static HttpServletProtocol newHttpProtocol() { 17 | ServletContext servletContext = new ServletContext(); 18 | servletContext.setDocBase(System.getProperty("user.dir"), "/webapp"); 19 | servletContext.addServlet("myHttpServlet", new MyHttpServlet()) 20 | .addMapping("/test"); 21 | return new HttpServletProtocol(servletContext); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/test/java/com/github/netty/websocket/WebsocketBootstrap.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.websocket; 2 | 3 | import com.github.netty.springboot.EnableNettyEmbedded; 4 | import org.springframework.boot.SpringApplication; 5 | import org.springframework.boot.autoconfigure.SpringBootApplication; 6 | import org.springframework.web.socket.config.annotation.EnableWebSocket; 7 | 8 | import java.net.URL; 9 | 10 | /** 11 | * Websocket server 12 | * 访问 http://localhost:8080/index.html 可以看效果 13 | * 14 | * @author wangzihao 15 | */ 16 | @EnableWebSocket 17 | @EnableNettyEmbedded 18 | @SpringBootApplication 19 | public class WebsocketBootstrap { 20 | private static final URL CONFIG_URL = WebsocketBootstrap.class.getResource( 21 | "/websocket/application.yaml"); 22 | 23 | public static void main(String[] args) { 24 | System.getProperties().put("spring.config.location", CONFIG_URL.toString()); 25 | SpringApplication.run(WebsocketBootstrap.class, args); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/test/java/com/github/netty/websocket/example/IndexController.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.websocket.example; 2 | 3 | import com.github.netty.websocket.WebsocketBootstrap; 4 | import org.springframework.core.io.InputStreamResource; 5 | import org.springframework.http.HttpHeaders; 6 | import org.springframework.http.HttpStatus; 7 | import org.springframework.http.ResponseEntity; 8 | import org.springframework.stereotype.Controller; 9 | import org.springframework.web.bind.annotation.RequestMapping; 10 | 11 | /** 12 | * test前端静态页面 13 | */ 14 | @Controller 15 | @RequestMapping("/") 16 | public class IndexController { 17 | 18 | @RequestMapping("/index.html") 19 | public ResponseEntity index() { 20 | HttpHeaders headers = new HttpHeaders(); 21 | headers.set("Content-Type", "text/html;charset=utf-8"); 22 | return new ResponseEntity<>(new InputStreamResource(WebsocketBootstrap.class.getResourceAsStream("/websocket/index.html")), headers, HttpStatus.OK); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/protocol/mysql/EventHandshakeSuccessful.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.protocol.mysql; 2 | 3 | import com.github.netty.protocol.mysql.server.ServerHandshakePacket; 4 | import com.github.netty.protocol.mysql.server.ServerOkPacket; 5 | 6 | public class EventHandshakeSuccessful { 7 | private final long timestamp = System.currentTimeMillis(); 8 | private ServerHandshakePacket handshakePacket; 9 | private ServerOkPacket serverOkPacket; 10 | 11 | public EventHandshakeSuccessful(ServerHandshakePacket handshakePacket, ServerOkPacket serverOkPacket) { 12 | this.handshakePacket = handshakePacket; 13 | this.serverOkPacket = serverOkPacket; 14 | } 15 | 16 | public ServerHandshakePacket getHandshakePacket() { 17 | return handshakePacket; 18 | } 19 | 20 | public ServerOkPacket getServerOkPacket() { 21 | return serverOkPacket; 22 | } 23 | 24 | public long getTimestamp() { 25 | return timestamp; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/protocol/mqtt/security/AcceptAllAuthenticator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012-2018 The original author or authors 3 | * ------------------------------------------------------ 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Apache License v2.0 which accompanies this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * 11 | * The Apache License v2.0 is available at 12 | * http://www.opensource.org/licenses/apache2.0.php 13 | * 14 | * You may elect to redistribute this code under either of these licenses. 15 | */ 16 | 17 | package com.github.netty.protocol.mqtt.security; 18 | 19 | public class AcceptAllAuthenticator implements IAuthenticator { 20 | 21 | @Override 22 | public boolean checkValid(String clientId, String username, byte[] password) { 23 | return true; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/test/java/com/github/netty/nrpc/client/example/HelloNettyRpcFilter1.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.nrpc.client.example; 2 | 3 | import com.github.netty.springboot.client.NettyRpcFilter; 4 | import com.github.netty.springboot.client.NettyRpcFullRequest; 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | import org.springframework.core.annotation.Order; 8 | import org.springframework.stereotype.Component; 9 | 10 | @Order(1) 11 | @Component 12 | public class HelloNettyRpcFilter1 implements NettyRpcFilter { 13 | private final Logger logger = LoggerFactory.getLogger(getClass()); 14 | 15 | @Override 16 | public void doFilter(NettyRpcFullRequest request, FilterChain chain) throws Throwable { 17 | logger.info("Filter1 begin."); 18 | Object response = null; 19 | try { 20 | response = request.getResponse(); 21 | chain.doFilter(request); 22 | }finally { 23 | logger.info("Filter1 end. response = " + response); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/test/java/com/github/netty/nrpc/client/example/HelloNettyRpcFilter2.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.nrpc.client.example; 2 | 3 | import com.github.netty.springboot.client.NettyRpcFilter; 4 | import com.github.netty.springboot.client.NettyRpcFullRequest; 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | import org.springframework.core.annotation.Order; 8 | import org.springframework.stereotype.Component; 9 | 10 | @Order(2) 11 | @Component 12 | public class HelloNettyRpcFilter2 implements NettyRpcFilter { 13 | private final Logger logger = LoggerFactory.getLogger(getClass()); 14 | 15 | @Override 16 | public void doFilter(NettyRpcFullRequest request, FilterChain chain) throws Throwable { 17 | logger.info("Filter2 begin."); 18 | Object response = null; 19 | try { 20 | response = request.getResponse(); 21 | chain.doFilter(request); 22 | }finally { 23 | logger.info("Filter2 end. response = " + response); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/protocol/dubbo/serialization/CompactedJavaSerialization.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.protocol.dubbo.serialization; 2 | 3 | import com.github.netty.protocol.dubbo.Serialization; 4 | 5 | import java.io.IOException; 6 | import java.io.InputStream; 7 | import java.io.OutputStream; 8 | 9 | public class CompactedJavaSerialization implements Serialization { 10 | private final byte contentTypeId; 11 | 12 | public CompactedJavaSerialization(byte contentTypeId) { 13 | this.contentTypeId = contentTypeId; 14 | } 15 | 16 | @Override 17 | public byte getContentTypeId() { 18 | return contentTypeId; 19 | } 20 | 21 | @Override 22 | public ObjectOutput serialize(OutputStream output) throws IOException { 23 | return new JavaSerialization.JavaObjectOutput(output, true); 24 | } 25 | 26 | @Override 27 | public ObjectInput deserialize(InputStream input) throws IOException { 28 | return new JavaSerialization.JavaObjectInput(input, true); 29 | } 30 | 31 | } -------------------------------------------------------------------------------- /src/main/java/com/github/netty/protocol/mqtt/exception/MqttSessionCorruptedException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012-2018 The original author or authors 3 | * ------------------------------------------------------ 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Apache License v2.0 which accompanies this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * 11 | * The Apache License v2.0 is available at 12 | * http://www.opensource.org/licenses/apache2.0.php 13 | * 14 | * You may elect to redistribute this code under either of these licenses. 15 | */ 16 | package com.github.netty.protocol.mqtt.exception; 17 | 18 | public class MqttSessionCorruptedException extends MqttException { 19 | 20 | private static final long serialVersionUID = 5848069213104389410L; 21 | 22 | public MqttSessionCorruptedException(String msg) { 23 | super(msg); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/protocol/servlet/websocket/WebSocketHandler.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.protocol.servlet.websocket; 2 | 3 | import jakarta.websocket.CloseReason; 4 | import jakarta.websocket.PongMessage; 5 | import jakarta.websocket.Session; 6 | 7 | import java.nio.ByteBuffer; 8 | 9 | public interface WebSocketHandler { 10 | 11 | default void afterConnectionEstablished(Session session) throws Exception { 12 | } 13 | 14 | default void handleTextMessage(Session session, String message, boolean isLast) throws Exception { 15 | } 16 | 17 | default void handleBinaryMessage(Session session, ByteBuffer message, boolean isLast) throws Exception { 18 | } 19 | 20 | default void handlePongMessage(Session session, PongMessage message, boolean isLast) throws Exception { 21 | } 22 | 23 | default void handleTransportError(Session session, Throwable exception) throws Exception { 24 | } 25 | 26 | default void afterConnectionClosed(Session session, CloseReason closeStatus) throws Exception { 27 | } 28 | 29 | } 30 | 31 | -------------------------------------------------------------------------------- /src/test/java/com/github/netty/file/FileApplication.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.file; 2 | 3 | import com.github.netty.StartupServer; 4 | import com.github.netty.protocol.HttpServletProtocol; 5 | import com.github.netty.protocol.servlet.DefaultServlet; 6 | import com.github.netty.protocol.servlet.ServletContext; 7 | 8 | public class FileApplication { 9 | public static void main(String[] args) { 10 | StartupServer server = new StartupServer(80); 11 | server.addProtocol(newHttpProtocol()); 12 | server.start(); 13 | // http://localhost/myfile.html 14 | // http://localhost/a/myfile.html 15 | } 16 | 17 | private static HttpServletProtocol newHttpProtocol() { 18 | ServletContext servletContext = new ServletContext(); 19 | // servletContext.setDocBase("D://demo", "/webapp"); 20 | servletContext.setDocBase(System.getProperty("user.dir"), "/webapp"); 21 | servletContext.addServlet("myServlet", new DefaultServlet()).addMapping("/"); 22 | return new HttpServletProtocol(servletContext); 23 | } 24 | } -------------------------------------------------------------------------------- /src/main/java/com/github/netty/core/util/StringUtil.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.core.util; 2 | 3 | /** 4 | * Created by wangzihao on 2018/7/31/031. 5 | */ 6 | public class StringUtil { 7 | 8 | public static boolean isNotEmpty(CharSequence str) { 9 | return !isEmpty(str); 10 | } 11 | 12 | public static boolean isEmpty(Object str) { 13 | return str == null || "".equals(str); 14 | } 15 | 16 | public static String firstUpperCase(String str) { 17 | if (str == null || str.isEmpty() || Character.isUpperCase(str.charAt(0))) { 18 | return str; 19 | } 20 | 21 | char[] cs = str.toCharArray(); 22 | cs[0] -= 32; 23 | return new String(cs); 24 | } 25 | 26 | public static String firstLowerCase(String str) { 27 | if (str == null || str.isEmpty() || Character.isLowerCase(str.charAt(0))) { 28 | return str; 29 | } 30 | 31 | char[] cs = str.toCharArray(); 32 | cs[0] = Character.toLowerCase(cs[0]); 33 | return new String(cs); 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/test/java/com/github/netty/http/example/IndexController.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.http.example; 2 | 3 | import com.github.netty.websocket.WebsocketBootstrap; 4 | import org.springframework.core.io.InputStreamResource; 5 | import org.springframework.http.HttpHeaders; 6 | import org.springframework.http.HttpStatus; 7 | import org.springframework.http.ResponseEntity; 8 | import org.springframework.stereotype.Controller; 9 | import org.springframework.web.bind.annotation.RequestMapping; 10 | 11 | /** 12 | * test前端静态页面 13 | */ 14 | @Controller 15 | @RequestMapping("") 16 | public class IndexController { 17 | 18 | @RequestMapping("") 19 | public ResponseEntity home() { 20 | return index(); 21 | } 22 | 23 | @RequestMapping("/index.html") 24 | public ResponseEntity index() { 25 | HttpHeaders headers = new HttpHeaders(); 26 | headers.set("Content-Type", "text/html;charset=utf-8"); 27 | return new ResponseEntity<>(new InputStreamResource(WebsocketBootstrap.class.getResourceAsStream("/http/index.html")), headers, HttpStatus.OK); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/protocol/mqtt/ISubscriptionsRepository.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012-2018 The original author or authors 3 | * ------------------------------------------------------ 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Apache License v2.0 which accompanies this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * 11 | * The Apache License v2.0 is available at 12 | * http://www.opensource.org/licenses/apache2.0.php 13 | * 14 | * You may elect to redistribute this code under either of these licenses. 15 | */ 16 | package com.github.netty.protocol.mqtt; 17 | 18 | import com.github.netty.protocol.mqtt.subscriptions.Subscription; 19 | 20 | import java.util.List; 21 | 22 | public interface ISubscriptionsRepository { 23 | 24 | List listAllSubscriptions(); 25 | 26 | void addNewSubscription(Subscription subscription); 27 | 28 | void removeSubscription(String topic, String clientID); 29 | } 30 | -------------------------------------------------------------------------------- /src/test/java/com/github/netty/springdubbo/Client.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.springdubbo; 2 | 3 | import com.github.netty.springdubbo.example.DemoAPI; 4 | import org.springframework.context.support.ClassPathXmlApplicationContext; 5 | 6 | import java.net.URL; 7 | 8 | public class Client { 9 | 10 | private static final URL CONFIG_URL = Client.class.getResource( 11 | "/springdubbo/dubbo-client.xml"); 12 | 13 | public static void main(String[] args) throws Exception { 14 | ClassPathXmlApplicationContext classPathXmlApplicationContext = new 15 | ClassPathXmlApplicationContext(CONFIG_URL.toString()); 16 | classPathXmlApplicationContext.start(); 17 | DemoAPI gphelloservice = (DemoAPI) classPathXmlApplicationContext.getBean("gphelloservice"); 18 | while (true) { 19 | try { 20 | String response = gphelloservice.hello("测试",2); 21 | System.out.println(response); 22 | Thread.sleep(1000); 23 | } catch (Exception e) { 24 | e.printStackTrace(); 25 | } 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/test/resources/springdubbo/dubbo-client.xml: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 | 14 | 15 | 16 | 20 | 21 | -------------------------------------------------------------------------------- /src/test/java/com/github/netty/myprotocol/MyClient.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.myprotocol; 2 | 3 | import java.io.IOException; 4 | import java.net.InetSocketAddress; 5 | import java.net.Socket; 6 | import java.nio.charset.Charset; 7 | 8 | public class MyClient { 9 | public static void main(String[] args) throws IOException { 10 | Socket socket = new Socket(); 11 | socket.connect(new InetSocketAddress("localhost", 8080)); 12 | 13 | socket.getOutputStream().write(MyServer.MyProtocol.HANDSHAKE_KEY.getBytes(Charset.forName("utf-8"))); 14 | socket.getOutputStream().flush(); 15 | 16 | byte[] serverMsg = new byte[4096]; 17 | socket.getInputStream().read(serverMsg); 18 | System.out.println("read = " + new String(serverMsg)); 19 | 20 | for (int i = 0; i < 100; i++) { 21 | String msg = "你好啊" + i + "先生."; 22 | socket.getOutputStream().write(msg.getBytes(Charset.forName("utf-8"))); 23 | socket.getOutputStream().flush(); 24 | } 25 | socket.getOutputStream().write("拜拜~".getBytes(Charset.forName("utf-8"))); 26 | socket.close(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/protocol/dubbo/packet/BodyResponse.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.protocol.dubbo.packet; 2 | 3 | import com.github.netty.protocol.dubbo.Body; 4 | 5 | import java.util.Map; 6 | 7 | public class BodyResponse extends Body { 8 | private final Object value; 9 | private final Object throwable; 10 | private final Map attachments; 11 | 12 | public BodyResponse(Object value, Object throwable, Map attachments) { 13 | this.value = value; 14 | this.throwable = throwable; 15 | this.attachments = attachments; 16 | } 17 | 18 | public Map getAttachments() { 19 | return attachments; 20 | } 21 | 22 | public Object getValue() { 23 | return value; 24 | } 25 | 26 | public Object getThrowable() { 27 | return throwable; 28 | } 29 | 30 | @Override 31 | public String toString() { 32 | return "BodyResponse{" + 33 | "\n\tvalue=" + value + 34 | ",\n\tthrowable=" + throwable + 35 | ",\n\tattachments=" + attachments + 36 | "\n}"; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/test/java/com/github/netty/mysql/example/MysqlBackendHandler.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.mysql.example; 2 | 3 | import com.github.netty.protocol.mysql.EventHandshakeSuccessful; 4 | import com.github.netty.protocol.mysql.server.MysqlBackendBusinessHandler; 5 | import com.github.netty.protocol.mysql.server.ServerHandshakePacket; 6 | import com.github.netty.protocol.mysql.server.ServerPacket; 7 | import io.netty.channel.ChannelHandlerContext; 8 | import org.springframework.context.annotation.Scope; 9 | import org.springframework.stereotype.Component; 10 | 11 | @Scope("prototype") 12 | @Component 13 | public class MysqlBackendHandler extends MysqlBackendBusinessHandler { 14 | @Override 15 | protected void onMysqlPacket(ChannelHandlerContext ctx, ServerPacket packet) { 16 | // 17 | } 18 | 19 | @Override 20 | protected void onHandshakeSuccessful(ChannelHandlerContext ctx, EventHandshakeSuccessful event) { 21 | super.onHandshakeSuccessful(ctx, event); 22 | } 23 | 24 | @Override 25 | protected void onHandshake(ChannelHandlerContext ctx, ServerHandshakePacket packet) { 26 | super.onHandshake(ctx, packet); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/test/java/com/github/netty/mysql/example/MysqlFrontendHandler.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.mysql.example; 2 | 3 | import com.github.netty.protocol.mysql.EventHandshakeSuccessful; 4 | import com.github.netty.protocol.mysql.client.ClientHandshakePacket; 5 | import com.github.netty.protocol.mysql.client.ClientPacket; 6 | import com.github.netty.protocol.mysql.client.MysqlFrontendBusinessHandler; 7 | import io.netty.channel.ChannelHandlerContext; 8 | import org.springframework.context.annotation.Scope; 9 | import org.springframework.stereotype.Component; 10 | 11 | @Scope("prototype") 12 | @Component 13 | public class MysqlFrontendHandler extends MysqlFrontendBusinessHandler { 14 | @Override 15 | protected void onMysqlPacket(ChannelHandlerContext ctx, ClientPacket packet) { 16 | // 17 | } 18 | 19 | @Override 20 | protected void onHandshakeSuccessful(ChannelHandlerContext ctx, EventHandshakeSuccessful event) { 21 | super.onHandshakeSuccessful(ctx, event); 22 | } 23 | 24 | @Override 25 | protected void onHandshake(ChannelHandlerContext ctx, ClientHandshakePacket packet) { 26 | super.onHandshake(ctx, packet); 27 | } 28 | } -------------------------------------------------------------------------------- /src/test/resources/javadubbo/dubbo-client.xml: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 | 14 | 15 | 16 | 21 | 22 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/protocol/mqtt/IRetainedRepository.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012-2018 The original author or authors 3 | * ------------------------------------------------------ 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Apache License v2.0 which accompanies this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * 11 | * The Apache License v2.0 is available at 12 | * http://www.opensource.org/licenses/apache2.0.php 13 | * 14 | * You may elect to redistribute this code under either of these licenses. 15 | */ 16 | package com.github.netty.protocol.mqtt; 17 | 18 | import com.github.netty.protocol.mqtt.subscriptions.Topic; 19 | import io.netty.handler.codec.mqtt.MqttPublishMessage; 20 | 21 | import java.util.List; 22 | 23 | public interface IRetainedRepository { 24 | 25 | void cleanRetained(Topic topic); 26 | 27 | void retain(Topic topic, MqttPublishMessage msg); 28 | 29 | boolean isEmpty(); 30 | 31 | List retainedOnTopic(String topic); 32 | } 33 | -------------------------------------------------------------------------------- /src/test/java/com/github/netty/springmyprotocol/MyClient.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.springmyprotocol; 2 | 3 | import java.io.IOException; 4 | import java.net.InetSocketAddress; 5 | import java.net.Socket; 6 | import java.nio.charset.Charset; 7 | 8 | public class MyClient { 9 | public static void main(String[] args) throws IOException { 10 | Socket socket = new Socket(); 11 | socket.connect(new InetSocketAddress("localhost", 8080)); 12 | 13 | socket.getOutputStream().write(SpringMyProtocolBootstrap.MyProtocol.HANDSHAKE_KEY.getBytes(Charset.forName("utf-8"))); 14 | socket.getOutputStream().flush(); 15 | 16 | byte[] serverMsg = new byte[4096]; 17 | socket.getInputStream().read(serverMsg); 18 | System.out.println("read = " + new String(serverMsg)); 19 | 20 | for (int i = 0; i < 100; i++) { 21 | String msg = "你好啊" + i + "先生."; 22 | socket.getOutputStream().write(msg.getBytes(Charset.forName("utf-8"))); 23 | socket.getOutputStream().flush(); 24 | } 25 | socket.getOutputStream().write("拜拜~".getBytes(Charset.forName("utf-8"))); 26 | socket.close(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/test/resources/javadubbo/dubbo-server.xml: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/test/resources/springdubbo/dubbo-server.xml: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 | 14 | 15 | 16 | 17 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/protocol/mqtt/subscriptions/ISubscriptionsDirectory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012-2018 The original author or authors 3 | * ------------------------------------------------------ 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Apache License v2.0 which accompanies this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * 11 | * The Apache License v2.0 is available at 12 | * http://www.opensource.org/licenses/apache2.0.php 13 | * 14 | * You may elect to redistribute this code under either of these licenses. 15 | */ 16 | package com.github.netty.protocol.mqtt.subscriptions; 17 | 18 | import java.util.Set; 19 | 20 | public interface ISubscriptionsDirectory { 21 | 22 | Set matchWithoutQosSharpening(Topic topic); 23 | 24 | Set matchQosSharpening(Topic topic); 25 | 26 | void add(Subscription newSubscription); 27 | 28 | void removeSubscription(Topic topic, String clientID); 29 | 30 | int size(); 31 | 32 | String dumpTree(); 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/protocol/mqtt/security/DenyAllAuthorizatorPolicy.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012-2018 The original author or authors 3 | * ------------------------------------------------------ 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Apache License v2.0 which accompanies this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * 11 | * The Apache License v2.0 is available at 12 | * http://www.opensource.org/licenses/apache2.0.php 13 | * 14 | * You may elect to redistribute this code under either of these licenses. 15 | */ 16 | 17 | package com.github.netty.protocol.mqtt.security; 18 | 19 | import com.github.netty.protocol.mqtt.subscriptions.Topic; 20 | 21 | public class DenyAllAuthorizatorPolicy implements IAuthorizatorPolicy { 22 | 23 | @Override 24 | public boolean canWrite(Topic topic, String user, String client) { 25 | return true; 26 | } 27 | 28 | @Override 29 | public boolean canRead(Topic topic, String user, String client) { 30 | return true; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/protocol/mqtt/security/PermitAllAuthorizatorPolicy.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012-2018 The original author or authors 3 | * ------------------------------------------------------ 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Apache License v2.0 which accompanies this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * 11 | * The Apache License v2.0 is available at 12 | * http://www.opensource.org/licenses/apache2.0.php 13 | * 14 | * You may elect to redistribute this code under either of these licenses. 15 | */ 16 | 17 | package com.github.netty.protocol.mqtt.security; 18 | 19 | import com.github.netty.protocol.mqtt.subscriptions.Topic; 20 | 21 | public class PermitAllAuthorizatorPolicy implements IAuthorizatorPolicy { 22 | 23 | @Override 24 | public boolean canWrite(Topic topic, String user, String client) { 25 | return true; 26 | } 27 | 28 | @Override 29 | public boolean canRead(Topic topic, String user, String client) { 30 | return true; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/protocol/nrpc/RpcClientAop.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.protocol.nrpc; 2 | 3 | import io.netty.util.concurrent.FastThreadLocal; 4 | 5 | import java.util.Map; 6 | import java.util.function.Supplier; 7 | 8 | /** 9 | * event aop 10 | * 11 | * @author wangzihao 12 | */ 13 | public interface RpcClientAop { 14 | 15 | FastThreadLocal> CONTEXT_LOCAL = new FastThreadLocal<>(); 16 | 17 | default void onInitAfter(RpcClient rpcClient) { 18 | } 19 | 20 | default void onConnectAfter(RpcClient rpcClient) { 21 | } 22 | 23 | default void onDisconnectAfter(RpcClient rpcClient) { 24 | } 25 | 26 | default void onEncodeRequestBefore(RpcContext rpcContext, Map params) { 27 | } 28 | 29 | default void onTimeout(RpcContext rpcContext) { 30 | } 31 | 32 | default void onChunkAfter(RpcContext rpcContext, Supplier chunk, int chunkIndex, int chunkId, ChunkAck ack) { 33 | } 34 | 35 | default void onResponseAfter(RpcContext rpcContext) { 36 | } 37 | 38 | default void onStateUpdate(RpcContext rpcContext, State formState, State toState) { 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/core/MessageToRunnable.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.core; 2 | 3 | import io.netty.channel.ChannelHandlerContext; 4 | 5 | /** 6 | * Convert the IO message to Runnable 7 | * Life cycle connection 8 | * 9 | * @author wangzihao 10 | */ 11 | @FunctionalInterface 12 | public interface MessageToRunnable { 13 | 14 | /** 15 | * Create a message handler IO task 16 | * 17 | * @param context The connection 18 | * @param msg IO messages (attention! : no automatic release, manual release is required) 19 | * @return Runnable 20 | */ 21 | Runnable onMessage(ChannelHandlerContext context, Object msg); 22 | 23 | /** 24 | * Create a error handler IO task 25 | * 26 | * @param context The connection 27 | * @param throwable Throwable 28 | * @return Runnable 29 | */ 30 | default Runnable onError(ChannelHandlerContext context, Throwable throwable) { 31 | return null; 32 | } 33 | 34 | /** 35 | * Create a close handler IO task 36 | * 37 | * @param context The connection 38 | * @return Runnable 39 | */ 40 | default Runnable onClose(ChannelHandlerContext context) { 41 | return null; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/protocol/mysql/ColumnFlag.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 The Netty Project 3 | * 4 | * The Netty Project licenses this file to you under the Apache License, 5 | * version 2.0 (the "License"); you may not use this file except in compliance 6 | * with the License. You may obtain a copy of the License at: 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | 17 | package com.github.netty.protocol.mysql; 18 | 19 | /** 20 | * Field flags. 21 | * 22 | * http://dev.mysql.com/doc/refman/5.7/en/c-api-data-structures.html 23 | */ 24 | public enum ColumnFlag { 25 | NOT_NULL, 26 | PRI_KEY, 27 | UNIQUE_KEY, 28 | MULTIPLE_KEY, 29 | UNSIGNED, 30 | ZEROFILL, 31 | BINARY, 32 | AUTO_INCREMENT, 33 | ENUM, 34 | SET, 35 | BLOB, 36 | TIMESTAMP, 37 | NUM, 38 | NO_DEFAULT_VALUE, 39 | UNKNOWN14, 40 | UNKNOWN15 41 | } -------------------------------------------------------------------------------- /src/main/java/com/github/netty/protocol/mqtt/subscriptions/SubscriptionCounterVisitor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012-2018 The original author or authors 3 | * ------------------------------------------------------ 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Apache License v2.0 which accompanies this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * 11 | * The Apache License v2.0 is available at 12 | * http://www.opensource.org/licenses/apache2.0.php 13 | * 14 | * You may elect to redistribute this code under either of these licenses. 15 | */ 16 | package com.github.netty.protocol.mqtt.subscriptions; 17 | 18 | import java.util.concurrent.atomic.AtomicInteger; 19 | 20 | class SubscriptionCounterVisitor implements CTrie.IVisitor { 21 | 22 | private AtomicInteger accumulator = new AtomicInteger(0); 23 | 24 | @Override 25 | public void visit(CNode node, int deep) { 26 | accumulator.addAndGet(node.subscriptions.size()); 27 | } 28 | 29 | @Override 30 | public Integer getResult() { 31 | return accumulator.get(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/test/resources/http/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Title 6 | 7 | 8 |     9 | 10 | 11 | 42 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/protocol/mqtt/interception/InterceptDisconnectMessage.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012-2018 The original author or authors 3 | * ------------------------------------------------------ 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Apache License v2.0 which accompanies this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * 11 | * The Apache License v2.0 is available at 12 | * http://www.opensource.org/licenses/apache2.0.php 13 | * 14 | * You may elect to redistribute this code under either of these licenses. 15 | */ 16 | 17 | package com.github.netty.protocol.mqtt.interception; 18 | 19 | public class InterceptDisconnectMessage implements InterceptMessage { 20 | 21 | private final String clientID; 22 | private final String username; 23 | 24 | public InterceptDisconnectMessage(String clientID, String username) { 25 | this.clientID = clientID; 26 | this.username = username; 27 | } 28 | 29 | public String getClientID() { 30 | return clientID; 31 | } 32 | 33 | public String getUsername() { 34 | return username; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/protocol/nrpc/RpcServerAop.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.protocol.nrpc; 2 | 3 | import com.github.netty.protocol.NRpcProtocol; 4 | import io.netty.util.concurrent.FastThreadLocal; 5 | 6 | import java.util.Map; 7 | 8 | /** 9 | * event aop 10 | * 11 | * @author wangzihao 12 | */ 13 | public interface RpcServerAop { 14 | 15 | FastThreadLocal> CONTEXT_LOCAL = new FastThreadLocal<>(); 16 | 17 | default void onInitAfter(NRpcProtocol protocol) { 18 | } 19 | 20 | default void onConnectAfter(RpcServerChannelHandler channel) { 21 | } 22 | 23 | default void onDisconnectAfter(RpcServerChannelHandler channel) { 24 | } 25 | 26 | default void onDecodeRequestBefore(RpcContext rpcContext, Map params) { 27 | } 28 | 29 | default void onChunkAfter(RpcContext rpcContext, Object chunk, int chunkIndex, int chunkId, RpcEmitter emitter) { 30 | } 31 | 32 | default void onResponseAfter(RpcContext rpcContext) { 33 | } 34 | 35 | default void onTimeout(RpcContext rpcContext) { 36 | } 37 | 38 | default void onStateUpdate(RpcContext rpcContext, State formState, State toState) { 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/protocol/mqtt/interception/InterceptConnectionLostMessage.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012-2018 The original author or authors 3 | * ------------------------------------------------------ 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Apache License v2.0 which accompanies this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * 11 | * The Apache License v2.0 is available at 12 | * http://www.opensource.org/licenses/apache2.0.php 13 | * 14 | * You may elect to redistribute this code under either of these licenses. 15 | */ 16 | 17 | package com.github.netty.protocol.mqtt.interception; 18 | 19 | public class InterceptConnectionLostMessage implements InterceptMessage { 20 | 21 | private final String clientID; 22 | private final String username; 23 | 24 | public InterceptConnectionLostMessage(String clientID, String username) { 25 | this.clientID = clientID; 26 | this.username = username; 27 | } 28 | 29 | public String getClientID() { 30 | return clientID; 31 | } 32 | 33 | public String getUsername() { 34 | return username; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/test/java/com/github/netty/javadubbo/Client.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.javadubbo; 2 | 3 | import com.github.netty.javadubbo.example.DemoAPI; 4 | import org.apache.dubbo.common.extension.ExtensionLoader; 5 | import org.apache.dubbo.rpc.Filter; 6 | import org.springframework.context.support.ClassPathXmlApplicationContext; 7 | 8 | import java.net.URL; 9 | 10 | public class Client { 11 | 12 | private static final URL CONFIG_URL = Client.class.getResource( 13 | "/javadubbo/dubbo-client.xml"); 14 | 15 | public static void main(String[] args) throws Exception { 16 | ExtensionLoader.getExtensionLoader(Filter.class).addExtension("clientFilter", ClientFilter.class); 17 | ClassPathXmlApplicationContext classPathXmlApplicationContext = new 18 | ClassPathXmlApplicationContext(CONFIG_URL.toString()); 19 | classPathXmlApplicationContext.start(); 20 | DemoAPI gphelloservice = (DemoAPI) classPathXmlApplicationContext.getBean("gphelloservice"); 21 | while (true) { 22 | try { 23 | String response = gphelloservice.hello("测试", 2); 24 | System.out.println(response); 25 | } catch (Exception e) { 26 | e.printStackTrace(); 27 | } 28 | Thread.sleep(1000); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/protocol/DubboProtocol.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.protocol; 2 | 3 | import com.github.netty.core.AbstractProtocol; 4 | import com.github.netty.protocol.dubbo.DubboDecoder; 5 | import com.github.netty.protocol.dubbo.ProxyFrontendHandler; 6 | import io.netty.buffer.ByteBuf; 7 | import io.netty.channel.Channel; 8 | 9 | import java.util.function.Supplier; 10 | 11 | public class DubboProtocol extends AbstractProtocol { 12 | private Supplier proxySupplier; 13 | 14 | public DubboProtocol() { 15 | } 16 | 17 | public DubboProtocol(Supplier proxySupplier) { 18 | this.proxySupplier = proxySupplier; 19 | } 20 | 21 | public void setProxySupplier(Supplier proxySupplier) { 22 | this.proxySupplier = proxySupplier; 23 | } 24 | 25 | @Override 26 | public String getProtocolName() { 27 | return "dubbo-proxy"; 28 | } 29 | 30 | @Override 31 | public boolean canSupport(ByteBuf buffer) { 32 | return DubboDecoder.isDubboProtocol(buffer); 33 | } 34 | 35 | @Override 36 | public void addPipeline(Channel channel, ByteBuf clientFirstMsg) throws Exception { 37 | channel.pipeline().addLast(new DubboDecoder()); 38 | channel.pipeline().addLast(proxySupplier.get()); 39 | } 40 | } -------------------------------------------------------------------------------- /src/main/java/com/github/netty/protocol/mysql/client/ClientQueryPacket.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 The Netty Project 3 | * 4 | * The Netty Project licenses this file to you under the Apache License, 5 | * version 2.0 (the "License"); you may not use this file except in compliance 6 | * with the License. You may obtain a copy of the License at: 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | 17 | package com.github.netty.protocol.mysql.client; 18 | 19 | import com.github.netty.protocol.mysql.Command; 20 | 21 | 22 | public class ClientQueryPacket extends ClientCommandPacket { 23 | private final String query; 24 | 25 | public ClientQueryPacket(int sequenceId, String query) { 26 | super(sequenceId, Command.COM_QUERY); 27 | this.query = query; 28 | } 29 | 30 | public String getQuery() { 31 | return query; 32 | } 33 | 34 | @Override 35 | public String toString() { 36 | return super.toString() + "," + query; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/springboot/EnableNettyRpcClients.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.springboot; 2 | 3 | import com.github.netty.springboot.client.NettyRpcClientBeanDefinitionRegistrar; 4 | import com.github.netty.springboot.client.NettyRpcLoadBalanced; 5 | import com.github.netty.springboot.client.NettyRpcRequest; 6 | import org.springframework.boot.context.properties.EnableConfigurationProperties; 7 | import org.springframework.context.annotation.Import; 8 | 9 | import java.lang.annotation.*; 10 | 11 | 12 | /** 13 | * Enable embedded Rpc client protocol 14 | * It will enable. 15 | * 1. rpc client protocol. {@link NettyRpcClientBeanDefinitionRegistrar} 16 | * 17 | * You must implement the interface. Returns ip address of the server. {@link NettyRpcLoadBalanced#chooseAddress(NettyRpcRequest)} 18 | * 19 | * @author wangzihao 2019-11-2 00:58:38 20 | * @see NettyProperties 21 | * @see NettyRpcLoadBalanced#chooseAddress(NettyRpcRequest) 22 | * @see NettyRpcClientBeanDefinitionRegistrar 23 | */ 24 | @Retention(RetentionPolicy.RUNTIME) 25 | @Target(ElementType.TYPE) 26 | @Documented 27 | @EnableConfigurationProperties(NettyProperties.class) 28 | @Import({NettyRpcClientBeanDefinitionRegistrar.class}) 29 | public @interface EnableNettyRpcClients { 30 | String[] value() default {}; 31 | 32 | String[] basePackages() default {}; 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/protocol/mqtt/config/IResourceLoader.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012-2018 The original author or authors 3 | * ------------------------------------------------------ 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Apache License v2.0 which accompanies this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * 11 | * The Apache License v2.0 is available at 12 | * http://www.opensource.org/licenses/apache2.0.php 13 | * 14 | * You may elect to redistribute this code under either of these licenses. 15 | */ 16 | 17 | package com.github.netty.protocol.mqtt.config; 18 | 19 | import com.github.netty.protocol.mqtt.exception.MqttException; 20 | 21 | import java.io.Reader; 22 | 23 | public interface IResourceLoader { 24 | 25 | Reader loadDefaultResource(); 26 | 27 | Reader loadResource(String relativePath); 28 | 29 | String getName(); 30 | 31 | class ResourceIsDirectoryException extends MqttException { 32 | 33 | private static final long serialVersionUID = -6969292229582764176L; 34 | 35 | public ResourceIsDirectoryException(String message) { 36 | super(message); 37 | } 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/springboot/server/ApplicationInstanceFactory.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.springboot.server; 2 | 3 | import com.github.netty.core.util.ApplicationX; 4 | import com.github.netty.protocol.servlet.util.InstanceFactory; 5 | 6 | public class ApplicationInstanceFactory implements InstanceFactory { 7 | private final ClassLoader classLoader; 8 | private final ApplicationX application; 9 | 10 | public ApplicationInstanceFactory(ClassLoader classLoader, ApplicationX application) { 11 | this.classLoader = classLoader; 12 | this.application = application; 13 | } 14 | 15 | @Override 16 | public Object newInstance(String className) throws ReflectiveOperationException { 17 | Class loadClass = classLoader.loadClass(className); 18 | return newInstance(loadClass); 19 | } 20 | 21 | @Override 22 | public T newInstance(Class clazz) throws ReflectiveOperationException { 23 | ApplicationX.BeanDefinition[] definitions = application.getBeanDefinitions(clazz); 24 | if (definitions.length == 0) { 25 | ApplicationX.BeanDefinition def = new ApplicationX.BeanDefinition(); 26 | def.setBeanClass(clazz); 27 | application.addBeanDefinition(clazz.getName(), def); 28 | } 29 | return application.getBean(clazz); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/test/java/com/github/netty/nrpc/client/example/HelloRpcClientAop.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.nrpc.client.example; 2 | 3 | import com.github.netty.protocol.nrpc.RpcClient; 4 | import com.github.netty.protocol.nrpc.RpcContext; 5 | import com.github.netty.protocol.nrpc.State; 6 | import org.springframework.stereotype.Component; 7 | 8 | import java.util.Map; 9 | 10 | /** 11 | * rpc call Lifecycle Management 12 | * @author wangzihao 2020-04-24 13 | */ 14 | @Component 15 | public class HelloRpcClientAop implements com.github.netty.protocol.nrpc.RpcClientAop { 16 | 17 | @Override 18 | public void onInitAfter(RpcClient rpcClient) { 19 | 20 | } 21 | 22 | @Override 23 | public void onConnectAfter(RpcClient rpcClient) { 24 | 25 | } 26 | 27 | @Override 28 | public void onDisconnectAfter(RpcClient rpcClient) { 29 | 30 | } 31 | 32 | @Override 33 | public void onEncodeRequestBefore(RpcContext rpcContext, Map params) { 34 | 35 | } 36 | 37 | @Override 38 | public void onResponseAfter(RpcContext rpcContext) { 39 | 40 | } 41 | 42 | @Override 43 | public void onTimeout(RpcContext rpcContext) { 44 | 45 | } 46 | 47 | @Override 48 | public void onStateUpdate(RpcContext rpcContext, State formState, State toState) { 49 | 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/test/java/com/github/netty/nrpc/server/HelloServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.nrpc.server; 2 | 3 | import com.github.netty.annotation.NRpcMethod; 4 | import com.github.netty.annotation.NRpcService; 5 | import com.github.netty.nrpc.api.HelloDTO; 6 | import com.github.netty.nrpc.api.HelloData; 7 | import com.github.netty.nrpc.api.HelloService; 8 | 9 | @NRpcService 10 | public class HelloServiceImpl implements HelloService { 11 | 12 | @NRpcMethod(timeoutInterrupt = true, timeout = 0) 13 | @Override 14 | public HelloData sayHello(String name, Integer id, Boolean bool, HelloDTO request) { 15 | int i = 0; 16 | while (i++ < 10) { 17 | // try { 18 | // Thread.sleep(10000); 19 | // } catch (InterruptedException e) { 20 | // } 21 | } 22 | System.out.printf("sayHello name=%s,id=%d,bool=%s,request=%s\n", 23 | name, id, bool, request); 24 | HelloData response = new HelloData(); 25 | response.setSay("hi! " + name); 26 | return response; 27 | } 28 | 29 | @Override 30 | public HelloData sayHello1(String name) { 31 | System.out.printf("sayHello1 name=%s\n", 32 | name); 33 | HelloData response = new HelloData(); 34 | response.setSay("hi! " + name); 35 | return response; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/protocol/nrpc/exception/RpcTimeoutException.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.protocol.nrpc.exception; 2 | 3 | /** 4 | * RpcTimeoutException 5 | * 6 | * @author wangzihao 7 | * 2018/8/20/020 8 | */ 9 | public class RpcTimeoutException extends RpcException { 10 | private long createTimestamp; 11 | private long expiryTimestamp; 12 | private long timestamp = System.currentTimeMillis(); 13 | 14 | public RpcTimeoutException(String message, boolean writableStackTrace, long createTimestamp, long expiryTimestamp) { 15 | super(message, null, false, writableStackTrace); 16 | this.createTimestamp = createTimestamp; 17 | this.expiryTimestamp = expiryTimestamp; 18 | } 19 | 20 | public long getCreateTimestamp() { 21 | return createTimestamp; 22 | } 23 | 24 | public void setCreateTimestamp(long createTimestamp) { 25 | this.createTimestamp = createTimestamp; 26 | } 27 | 28 | public long getExpiryTimestamp() { 29 | return expiryTimestamp; 30 | } 31 | 32 | public void setExpiryTimestamp(long expiryTimestamp) { 33 | this.expiryTimestamp = expiryTimestamp; 34 | } 35 | 36 | public long getTimestamp() { 37 | return timestamp; 38 | } 39 | 40 | public void setTimestamp(long timestamp) { 41 | this.timestamp = timestamp; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/protocol/mysql/server/ServerColumnCountPacket.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 The Netty Project 3 | * 4 | * The Netty Project licenses this file to you under the Apache License, 5 | * version 2.0 (the "License"); you may not use this file except in compliance 6 | * with the License. You may obtain a copy of the License at: 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | 17 | package com.github.netty.protocol.mysql.server; 18 | 19 | import com.github.netty.protocol.mysql.AbstractMySqlPacket; 20 | 21 | 22 | public class ServerColumnCountPacket extends AbstractMySqlPacket implements ServerPacket { 23 | 24 | private final int fieldCount; 25 | 26 | public ServerColumnCountPacket(int sequenceId, int fieldCount) { 27 | super(sequenceId); 28 | this.fieldCount = fieldCount; 29 | } 30 | 31 | public int getFieldCount() { 32 | return fieldCount; 33 | } 34 | 35 | @Override 36 | public String toString() { 37 | return super.toString() + "," + fieldCount; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/protocol/mysql/AbstractMySqlPacket.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 The Netty Project 3 | * 4 | * The Netty Project licenses this file to you under the Apache License, 5 | * version 2.0 (the "License"); you may not use this file except in compliance 6 | * with the License. You may obtain a copy of the License at: 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | 17 | package com.github.netty.protocol.mysql; 18 | 19 | 20 | public abstract class AbstractMySqlPacket implements MysqlPacket { 21 | private final long timestamp = System.currentTimeMillis(); 22 | private final int sequenceId; 23 | 24 | public AbstractMySqlPacket(int sequenceId) { 25 | this.sequenceId = sequenceId; 26 | } 27 | 28 | @Override 29 | public long getTimestamp() { 30 | return timestamp; 31 | } 32 | 33 | @Override 34 | public int getSequenceId() { 35 | return sequenceId; 36 | } 37 | 38 | @Override 39 | public String toString() { 40 | return getClass().getSimpleName(); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/protocol/mqtt/interception/InterceptAbstractMessage.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012-2018 The original author or authors 3 | * ------------------------------------------------------ 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Apache License v2.0 which accompanies this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * 11 | * The Apache License v2.0 is available at 12 | * http://www.opensource.org/licenses/apache2.0.php 13 | * 14 | * You may elect to redistribute this code under either of these licenses. 15 | */ 16 | 17 | package com.github.netty.protocol.mqtt.interception; 18 | 19 | import io.netty.handler.codec.mqtt.MqttMessage; 20 | import io.netty.handler.codec.mqtt.MqttQoS; 21 | 22 | public abstract class InterceptAbstractMessage implements InterceptMessage { 23 | 24 | private final MqttMessage msg; 25 | 26 | InterceptAbstractMessage(MqttMessage msg) { 27 | this.msg = msg; 28 | } 29 | 30 | public boolean isRetainFlag() { 31 | return msg.fixedHeader().isRetain(); 32 | } 33 | 34 | public boolean isDupFlag() { 35 | return msg.fixedHeader().isDup(); 36 | } 37 | 38 | public MqttQoS getQos() { 39 | return msg.fixedHeader().qosLevel(); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/core/Ordered.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.core; 2 | 3 | import java.util.Comparator; 4 | import java.util.TreeSet; 5 | import java.util.function.Function; 6 | 7 | /** 8 | * Ordered 9 | * 10 | * @author wangzihao 11 | * 2019/8/31/022 12 | */ 13 | public interface Ordered { 14 | /** 15 | * Avoid TreeSet overwrites data 16 | * return -1 or 1. not return 0 17 | */ 18 | Comparator COMPARATOR = (c1, c2) -> 19 | c1 == c2 ? 0 : c1.getOrder() < c2.getOrder() ? -1 : 1; 20 | 21 | /** 22 | * test comparator 23 | * 24 | * @param args args 25 | */ 26 | static void main(String[] args) { 27 | /** no overwrites by {{@link COMPARATOR}} */ 28 | TreeSet set1 = new TreeSet<>(COMPARATOR); 29 | set1.add(() -> 1); 30 | set1.add(() -> 1); 31 | System.out.println("no overwrites. set1 = " + set1.size()); 32 | 33 | /** overwrites by jdk method {{@link Comparator#comparing(Function)}} */ 34 | TreeSet set2 = new TreeSet<>(Comparator.comparing(Ordered::getOrder)); 35 | set2.add(() -> 1); 36 | set2.add(() -> 1); 37 | System.out.println("overwrites. set2 = " + set2.size()); 38 | } 39 | 40 | /** 41 | * Priority order 42 | * 43 | * @return The smaller the value of order, the more likely it is to be executed first 44 | */ 45 | int getOrder(); 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/annotation/NRpcService.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.annotation; 2 | 3 | import com.github.netty.core.util.ApplicationX; 4 | import org.springframework.core.annotation.AliasFor; 5 | import org.springframework.stereotype.Controller; 6 | import org.springframework.web.bind.annotation.ResponseBody; 7 | 8 | import java.lang.annotation.*; 9 | 10 | /** 11 | * RPC service note :(to use RPC, the interface or class can be configured with or without annotations, the default is the class name of the interface) 12 | */ 13 | @Target({ElementType.TYPE, ElementType.ANNOTATION_TYPE}) 14 | @Retention(RetentionPolicy.RUNTIME) 15 | @Documented 16 | @ApplicationX.Component 17 | @Controller 18 | @ResponseBody 19 | public @interface NRpcService { 20 | /** 21 | * Default timeout 22 | */ 23 | int DEFAULT_TIME_OUT = 1000; 24 | 25 | /** 26 | * Address of the interface 27 | * 28 | * @return value 29 | */ 30 | @AliasFor(annotation = Controller.class) 31 | String value() default ""; 32 | 33 | /** 34 | * service version 35 | * 36 | * @return any str 37 | */ 38 | String version() default ""; 39 | 40 | /** 41 | * timeout is -1 then never timeout 42 | * timeout is 0 then use client timeout 43 | * timeout other then use server timeout 44 | * 45 | * @return method timeout (milliseconds) 46 | */ 47 | int timeout() default DEFAULT_TIME_OUT; 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/core/util/NettyThreadPoolExecutor.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.core.util; 2 | 3 | import io.netty.util.concurrent.DefaultThreadFactory; 4 | 5 | import java.util.concurrent.BlockingQueue; 6 | import java.util.concurrent.RejectedExecutionHandler; 7 | import java.util.concurrent.ThreadPoolExecutor; 8 | import java.util.concurrent.TimeUnit; 9 | 10 | /** 11 | * Use netty thread 12 | * 13 | * @author wangzihaogithub 2020-11-21 14 | * @see io.netty.util.concurrent.DefaultThreadFactory 15 | * @see io.netty.util.concurrent.FastThreadLocalThread 16 | * @see io.netty.util.internal.InternalThreadLocalMap#handlerSharableCache() 17 | */ 18 | public class NettyThreadPoolExecutor extends ThreadPoolExecutor { 19 | 20 | public NettyThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, 21 | BlockingQueue workQueue, String poolName, int priority, boolean daemon, 22 | RejectedExecutionHandler handler) { 23 | super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, new DefaultThreadFactory(poolName, daemon, priority, 24 | Thread.currentThread().getThreadGroup()) { 25 | @Override 26 | protected Thread newThread(Runnable r, String name) { 27 | return new NettyThreadX(threadGroup, r, name); 28 | } 29 | }, handler); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/protocol/mysql/client/ClientCommandPacket.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 The Netty Project 3 | * 4 | * The Netty Project licenses this file to you under the Apache License, 5 | * version 2.0 (the "License"); you may not use this file except in compliance 6 | * with the License. You may obtain a copy of the License at: 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | 17 | package com.github.netty.protocol.mysql.client; 18 | 19 | import com.github.netty.protocol.mysql.AbstractMySqlPacket; 20 | import com.github.netty.protocol.mysql.Command; 21 | 22 | 23 | public class ClientCommandPacket extends AbstractMySqlPacket implements ClientPacket { 24 | 25 | private final Command command; 26 | 27 | public ClientCommandPacket(int sequenceId, Command command) { 28 | super(sequenceId); 29 | this.command = command; 30 | } 31 | 32 | public Command getCommand() { 33 | return command; 34 | } 35 | 36 | @Override 37 | public String toString() { 38 | return super.toString() + "," + command.name(); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/test/java/com/github/netty/http2/HttpBootstrap.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.http2; 2 | 3 | import com.github.netty.StartupServer; 4 | import com.github.netty.javaxservlet.example.MyHttpServlet; 5 | import com.github.netty.protocol.HttpServletProtocol; 6 | import com.github.netty.protocol.servlet.ServletContext; 7 | 8 | public class HttpBootstrap { 9 | 10 | public static void main(String[] args) throws Exception { 11 | StartupServer server = new StartupServer(80); 12 | // StartupServer server = new StartupServer(443); 13 | server.addProtocol(newHttpProtocol()); 14 | server.start(); 15 | } 16 | 17 | private static HttpServletProtocol newHttpProtocol() throws Exception { 18 | ServletContext servletContext = new ServletContext(); 19 | servletContext.setDocBase(System.getProperty("user.dir"), "/webapp"); 20 | servletContext.addServlet("myHttpServlet", new MyHttpServlet()) 21 | .addMapping("/test"); 22 | HttpServletProtocol protocol = new HttpServletProtocol(servletContext); 23 | protocol.setEnableH2c(true); 24 | 25 | // protocol.setSslFileJks( 26 | // new File("G:\\githubs\\spring-boot-protocol\\webapp\\mydomain.com.jks"), 27 | // new File("G:\\githubs\\spring-boot-protocol\\webapp\\jks-password.txt") 28 | // ); 29 | // protocol.setSslFileCrtPem(crtFile, pemFile); 30 | return protocol; 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/protocol/mysql/ServerStatusFlag.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 The Netty Project 3 | * 4 | * The Netty Project licenses this file to you under the Apache License, 5 | * version 2.0 (the "License"); you may not use this file except in compliance 6 | * with the License. You may obtain a copy of the License at: 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | 17 | package com.github.netty.protocol.mysql; 18 | 19 | /** 20 | * The MySQL client/server capability flags. 21 | * 22 | * @see Server Status Flags Reference 23 | * Documentation 24 | */ 25 | public enum ServerStatusFlag { 26 | IN_TRANSACTION, 27 | AUTO_COMMIT, 28 | MORE_RESULTS_EXIST, 29 | NO_GOOD_INDEX_USED, 30 | CURSOR_EXISTS, 31 | LAST_ROW_SENT, 32 | DATABASE_DROPPED, 33 | NO_BACKSLASH_ESCAPES, 34 | METADATA_CHANGED, 35 | QUERY_WAS_SLOW, 36 | PREPARED_STATEMENT_OUT_PARAMS, 37 | IN_READONLY_TRANSACTION, 38 | SESSION_STATE_CHANGED, 39 | UNKNOWN_13, 40 | UNKNOWN_14, 41 | UNKNOWN_15 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/protocol/mysql/client/ClientCommandDecoder.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.protocol.mysql.client; 2 | 3 | import com.github.netty.protocol.mysql.*; 4 | import io.netty.buffer.ByteBuf; 5 | import io.netty.channel.ChannelHandlerContext; 6 | import io.netty.handler.codec.DecoderException; 7 | 8 | import java.util.List; 9 | 10 | 11 | public class ClientCommandDecoder extends AbstractPacketDecoder implements ClientDecoder { 12 | private Session session; 13 | 14 | public ClientCommandDecoder(Session session, int maxPacketSize) { 15 | super(maxPacketSize); 16 | this.session = session; 17 | } 18 | 19 | @Override 20 | protected void decodePacket(ChannelHandlerContext ctx, int sequenceId, ByteBuf packet, List out) { 21 | MysqlCharacterSet clientCharset = session.getClientCharset(); 22 | 23 | byte commandCode = packet.readByte(); 24 | Command command = Command.findByCommandCode(commandCode); 25 | if (command == null) { 26 | throw new DecoderException("Unknown command " + commandCode); 27 | } 28 | switch (command) { 29 | case COM_QUERY: 30 | out.add(new ClientQueryPacket(sequenceId, CodecUtils.readFixedLengthString(packet, packet.readableBytes(), clientCharset.getCharset()))); 31 | break; 32 | default: 33 | out.add(new ClientCommandPacket(sequenceId, command)); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/protocol/mqtt/interception/InterceptUnsubscribeMessage.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012-2018 The original author or authors 3 | * ------------------------------------------------------ 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Apache License v2.0 which accompanies this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * 11 | * The Apache License v2.0 is available at 12 | * http://www.opensource.org/licenses/apache2.0.php 13 | * 14 | * You may elect to redistribute this code under either of these licenses. 15 | */ 16 | 17 | package com.github.netty.protocol.mqtt.interception; 18 | 19 | public class InterceptUnsubscribeMessage implements InterceptMessage { 20 | 21 | private final String topicFilter; 22 | private final String clientID; 23 | private final String username; 24 | 25 | public InterceptUnsubscribeMessage(String topicFilter, String clientID, String username) { 26 | this.topicFilter = topicFilter; 27 | this.clientID = clientID; 28 | this.username = username; 29 | } 30 | 31 | public String getTopicFilter() { 32 | return topicFilter; 33 | } 34 | 35 | public String getClientID() { 36 | return clientID; 37 | } 38 | 39 | public String getUsername() { 40 | return username; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/protocol/servlet/util/ByteBufToHttpContentChannelHandler.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.protocol.servlet.util; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import io.netty.channel.ChannelHandler; 5 | import io.netty.channel.ChannelHandlerContext; 6 | import io.netty.channel.ChannelOutboundHandlerAdapter; 7 | import io.netty.channel.ChannelPromise; 8 | import io.netty.handler.codec.http.DefaultHttpContent; 9 | 10 | @ChannelHandler.Sharable 11 | public class ByteBufToHttpContentChannelHandler extends ChannelOutboundHandlerAdapter { 12 | public static final ByteBufToHttpContentChannelHandler INSTANCE = new ByteBufToHttpContentChannelHandler(); 13 | 14 | @Override 15 | public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception { 16 | if (msg instanceof ByteBuf) { 17 | // convert ByteBuf to HttpContent to make it work with compression. This is needed as we use the 18 | // ChunkedWriteHandler to send files when compression is enabled. 19 | ByteBuf buff = (ByteBuf) msg; 20 | if (buff.isReadable()) { 21 | // We only encode non empty buffers, as empty buffers can be used for determining when 22 | // the content has been flushed and it confuses the HttpContentCompressor 23 | // if we let it go 24 | msg = new DefaultHttpContent(buff); 25 | } 26 | } 27 | super.write(ctx, msg, promise); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/core/AbstractProtocol.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.core; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import io.netty.channel.Channel; 5 | 6 | import java.util.concurrent.TimeUnit; 7 | 8 | /** 9 | * An abstract Protocols Register 10 | * 11 | * @author wangzihao 12 | */ 13 | public abstract class AbstractProtocol implements ProtocolHandler, ServerListener { 14 | /** 15 | * Refresh buffer data interval (milliseconds), 16 | * the benefits of open time to send is sent in bulk to bring high-throughput, 17 | * but there will be a delay. 18 | * (If the timer is greater than 0 seconds to transmit buffer data is less than 0 seconds to transmit the data in real time) 19 | */ 20 | private int autoFlushIdleMs; 21 | 22 | public int getAutoFlushIdleMs() { 23 | return autoFlushIdleMs; 24 | } 25 | 26 | public void setAutoFlushIdleMs(int autoFlushIdleMs) { 27 | this.autoFlushIdleMs = autoFlushIdleMs; 28 | } 29 | 30 | @Override 31 | public void addPipeline(Channel channel, ByteBuf clientFirstMsg) throws Exception { 32 | int autoFlushIdleTime = getAutoFlushIdleMs(); 33 | if (autoFlushIdleTime > 0) { 34 | channel.pipeline().addLast("autoflush", new AutoFlushChannelHandler(autoFlushIdleTime, TimeUnit.MILLISECONDS)); 35 | } 36 | } 37 | 38 | @Override 39 | public String toString() { 40 | return getProtocolName(); 41 | } 42 | 43 | @Override 44 | public int getOrder() { 45 | return 0; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/protocol/mqtt/MqttClientDescriptor.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.protocol.mqtt; 2 | 3 | import java.util.Objects; 4 | 5 | public class MqttClientDescriptor { 6 | 7 | private final String clientID; 8 | private final String address; 9 | private final int port; 10 | 11 | MqttClientDescriptor(String clientID, String address, int port) { 12 | this.clientID = clientID; 13 | this.address = address; 14 | this.port = port; 15 | } 16 | 17 | public String getClientID() { 18 | return clientID; 19 | } 20 | 21 | public String getAddress() { 22 | return address; 23 | } 24 | 25 | public int getPort() { 26 | return port; 27 | } 28 | 29 | @Override 30 | public boolean equals(Object o) { 31 | if (this == o) return true; 32 | if (o == null || getClass() != o.getClass()) return false; 33 | MqttClientDescriptor that = (MqttClientDescriptor) o; 34 | return port == that.port && 35 | Objects.equals(clientID, that.clientID) && 36 | Objects.equals(address, that.address); 37 | } 38 | 39 | @Override 40 | public int hashCode() { 41 | return Objects.hash(clientID, address, port); 42 | } 43 | 44 | @Override 45 | public String toString() { 46 | return "MqttClientDescriptor{" + 47 | "clientID='" + clientID + '\'' + 48 | ", address='" + address + '\'' + 49 | ", port=" + port + 50 | '}'; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/protocol/mqtt/MqttIdleTimeoutChannelHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012-2018 The original author or authors 3 | * ------------------------------------------------------ 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Apache License v2.0 which accompanies this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * 11 | * The Apache License v2.0 is available at 12 | * http://www.opensource.org/licenses/apache2.0.php 13 | * 14 | * You may elect to redistribute this code under either of these licenses. 15 | */ 16 | 17 | package com.github.netty.protocol.mqtt; 18 | 19 | import com.github.netty.core.AbstractChannelHandler; 20 | import io.netty.channel.ChannelHandler.Sharable; 21 | import io.netty.channel.ChannelHandlerContext; 22 | 23 | import static io.netty.channel.ChannelFutureListener.CLOSE_ON_FAILURE; 24 | 25 | @Sharable 26 | public class MqttIdleTimeoutChannelHandler extends AbstractChannelHandler { 27 | public MqttIdleTimeoutChannelHandler() { 28 | super(false); 29 | } 30 | 31 | @Override 32 | protected void onReaderIdle(ChannelHandlerContext ctx) { 33 | logger.trace("Firing channel inactive event. MqttClientId = {}.", MqttUtil.clientID(ctx.channel())); 34 | // fire a close that then fire channelInactive to trigger publish of Will 35 | ctx.close().addListener(CLOSE_ON_FAILURE); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/test/java/com/github/netty/nrpc/client/NRpcClientBootstrap.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.nrpc.client; 2 | 3 | import com.github.netty.nrpc.client.example.HelloNettyRpcLoadBalanced; 4 | import com.github.netty.springboot.EnableNettyRpcClients; 5 | import com.github.netty.springboot.client.NettyRpcLoadBalanced; 6 | import org.springframework.boot.SpringApplication; 7 | import org.springframework.boot.autoconfigure.SpringBootApplication; 8 | import org.springframework.context.annotation.Bean; 9 | 10 | import java.net.InetSocketAddress; 11 | import java.net.URL; 12 | import java.util.ArrayList; 13 | import java.util.List; 14 | 15 | //@EnableNettyEmbedded 16 | @EnableNettyRpcClients 17 | @SpringBootApplication 18 | public class NRpcClientBootstrap { 19 | private static final URL CONFIG_URL = NRpcClientBootstrap.class.getResource( 20 | "/nrpc/client/application.yaml"); 21 | 22 | public static void main(String[] args) { 23 | System.getProperties().put("spring.config.location",CONFIG_URL.toString()); 24 | SpringApplication.run(NRpcClientBootstrap.class,args); 25 | } 26 | 27 | /** 28 | * 必须实现这个类, 不然 RPC客户端无法运作 29 | * @return 返回一个IP地址 30 | */ 31 | @Bean 32 | public NettyRpcLoadBalanced nettyRpcLoadBalanced(){ 33 | List list = new ArrayList<>(); 34 | list.add(new InetSocketAddress("localhost", 8080)); 35 | list.add(new InetSocketAddress("localhost", 8080)); 36 | list.add(new InetSocketAddress("localhost", 8080)); 37 | return new HelloNettyRpcLoadBalanced(list); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/test/java/com/github/netty/http/HttpBootstrap.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.http; 2 | 3 | import com.github.netty.springboot.EnableNettyEmbedded; 4 | import org.springframework.boot.SpringApplication; 5 | import org.springframework.boot.autoconfigure.SpringBootApplication; 6 | 7 | import java.net.URL; 8 | 9 | @EnableNettyEmbedded 10 | @SpringBootApplication 11 | public class HttpBootstrap { 12 | private static final URL CONFIG_URL = HttpBootstrap.class.getResource( 13 | "/http/application.yaml"); 14 | 15 | public static void main(String[] args) { 16 | System.getProperties().put("spring.config.location", CONFIG_URL.toString()); 17 | SpringApplication.run(HttpBootstrap.class, args); 18 | } 19 | 20 | // @Bean 21 | // public ServletContextAware servletContextAware(){ 22 | // return new ServletContextAware() { 23 | // @Override 24 | // public void setServletContext(ServletContext servletContext) { 25 | // String string = servletContext.getRealPath("/"); 26 | // System.out.println("string = " + string); 27 | // } 28 | // }; 29 | // } 30 | // 31 | // @Bean 32 | // public ServletConfigAware servletConfigAware(){ 33 | // return new ServletConfigAware() { 34 | // @Override 35 | // public void setServletConfig(ServletConfig servletConfig) { 36 | // String servletName = servletConfig.getServletName(); 37 | // System.out.println("servletName = " + servletName); 38 | // } 39 | // }; 40 | // } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/core/util/ThreadFactoryX.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.core.util; 2 | 3 | import io.netty.util.concurrent.DefaultThreadFactory; 4 | 5 | /** 6 | * Created by wangzihao on 2018/8/25/025. 7 | */ 8 | public class ThreadFactoryX extends DefaultThreadFactory implements java.util.concurrent.ThreadFactory { 9 | 10 | private final String preName; 11 | private final boolean daemon; 12 | private final ThreadGroup threadGroup; 13 | 14 | public ThreadFactoryX(String preName, Class poolType) { 15 | this(preName, poolType, Thread.MAX_PRIORITY, false); 16 | } 17 | 18 | public ThreadFactoryX(String preName, Class poolType, int priority, boolean daemon) { 19 | super(NamespaceUtil.newIdName(poolType), priority); 20 | this.preName = preName; 21 | this.daemon = daemon; 22 | this.threadGroup = Thread.currentThread().getThreadGroup(); 23 | } 24 | 25 | public ThreadFactoryX(String poolName, String preName, boolean daemon) { 26 | super(poolName); 27 | this.preName = preName; 28 | this.threadGroup = Thread.currentThread().getThreadGroup(); 29 | this.daemon = daemon; 30 | } 31 | 32 | @Override 33 | protected Thread newThread(Runnable r, String name) { 34 | Thread thread = new NettyThreadX(threadGroup, r, name); 35 | if (preName != null && !preName.isEmpty()) { 36 | thread.setName("NettyX-" + preName + "-" + thread.getName()); 37 | } 38 | if (daemon) { 39 | thread.setDaemon(true); 40 | } 41 | return thread; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/protocol/mqtt/security/IAuthorizatorPolicy.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012-2018 The original author or authors 3 | * ------------------------------------------------------ 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Apache License v2.0 which accompanies this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * 11 | * The Apache License v2.0 is available at 12 | * http://www.opensource.org/licenses/apache2.0.php 13 | * 14 | * You may elect to redistribute this code under either of these licenses. 15 | */ 16 | 17 | package com.github.netty.protocol.mqtt.security; 18 | 19 | import com.github.netty.protocol.mqtt.subscriptions.Topic; 20 | 21 | /** 22 | * ACL checker. 23 | * 24 | * Create an authorizator that matches topic names with same grammar of subscriptions. The # is 25 | * always a terminator and its the multilevel matcher. The + sign is the single level matcher. 26 | */ 27 | public interface IAuthorizatorPolicy { 28 | 29 | /** 30 | * Ask the implementation of the authorizator if the topic can be used in a publish. 31 | * 32 | * @param topic the topic to write to. 33 | * @param user the user 34 | * @param client the client 35 | * @return true if the user from client can publish data on topic. 36 | */ 37 | boolean canWrite(Topic topic, String user, String client); 38 | 39 | boolean canRead(Topic topic, String user, String client); 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/protocol/servlet/util/HttpLazyThreadPool.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.protocol.servlet.util; 2 | 3 | import com.github.netty.core.util.NettyThreadPoolExecutor; 4 | 5 | import java.util.concurrent.Executor; 6 | import java.util.concurrent.RejectedExecutionHandler; 7 | import java.util.concurrent.SynchronousQueue; 8 | import java.util.concurrent.TimeUnit; 9 | import java.util.function.Supplier; 10 | 11 | public class HttpLazyThreadPool implements Supplier { 12 | private final String poolName; 13 | private volatile NettyThreadPoolExecutor executor; 14 | 15 | public HttpLazyThreadPool(String poolName) { 16 | this.poolName = poolName; 17 | } 18 | 19 | @Override 20 | public NettyThreadPoolExecutor get() { 21 | if (executor == null) { 22 | synchronized (this) { 23 | if (executor == null) { 24 | int coreThreads = 2; 25 | int maxThreads = 200; 26 | int keepAliveSeconds = 180; 27 | int priority = Thread.NORM_PRIORITY; 28 | boolean daemon = false; 29 | RejectedExecutionHandler handler = new HttpAbortPolicyWithReport(poolName, System.getProperty("user.home"), "Http Servlet"); 30 | executor = new NettyThreadPoolExecutor( 31 | coreThreads, maxThreads, keepAliveSeconds, TimeUnit.SECONDS, 32 | new SynchronousQueue<>(), poolName, priority, daemon, handler); 33 | } 34 | } 35 | } 36 | return executor; 37 | } 38 | } -------------------------------------------------------------------------------- /src/main/java/com/github/netty/protocol/servlet/SessionService.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.protocol.servlet; 2 | 3 | import com.github.netty.annotation.NRpcParam; 4 | import com.github.netty.annotation.NRpcService; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * Session service 10 | * 11 | * @author wangzihao 12 | * 2018/8/19/019 13 | */ 14 | @NRpcService(value = "/_nrpc/sessionService", timeout = 1000) 15 | public interface SessionService { 16 | 17 | /** 18 | * Get session (by id) 19 | * 20 | * @param sessionId sessionId 21 | * @return Session 22 | */ 23 | Session getSession(@NRpcParam("sessionId") String sessionId); 24 | 25 | /** 26 | * Save the session 27 | * 28 | * @param session session 29 | */ 30 | void saveSession(@NRpcParam("session") Session session); 31 | 32 | /** 33 | * Delete session 34 | * 35 | * @param sessionId sessionId 36 | */ 37 | void removeSession(@NRpcParam("sessionId") String sessionId); 38 | 39 | /** 40 | * Delete session (batch) 41 | * 42 | * @param sessionIdList sessionIdList 43 | */ 44 | void removeSessionBatch(@NRpcParam("sessionIdList") List sessionIdList); 45 | 46 | /** 47 | * Change the sessionId 48 | * 49 | * @param oldSessionId oldSessionId 50 | * @param newSessionId newSessionId 51 | */ 52 | void changeSessionId(@NRpcParam("oldSessionId") String oldSessionId, @NRpcParam("newSessionId") String newSessionId); 53 | 54 | /** 55 | * Get the number of sessions 56 | * 57 | * @return count 58 | */ 59 | int count(); 60 | 61 | } 62 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/protocol/mqtt/subscriptions/INode.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012-2018 The original author or authors 3 | * ------------------------------------------------------ 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Apache License v2.0 which accompanies this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * 11 | * The Apache License v2.0 is available at 12 | * http://www.opensource.org/licenses/apache2.0.php 13 | * 14 | * You may elect to redistribute this code under either of these licenses. 15 | */ 16 | package com.github.netty.protocol.mqtt.subscriptions; 17 | 18 | import java.util.concurrent.atomic.AtomicReference; 19 | 20 | class INode { 21 | private AtomicReference mainNode = new AtomicReference<>(); 22 | 23 | INode(CNode mainNode) { 24 | this.mainNode.set(mainNode); 25 | if (mainNode instanceof TNode) { // this should never happen 26 | throw new IllegalStateException("TNode should not be set on mainNnode"); 27 | } 28 | } 29 | 30 | boolean compareAndSet(CNode old, CNode newNode) { 31 | return mainNode.compareAndSet(old, newNode); 32 | } 33 | 34 | boolean compareAndSet(CNode old, TNode newNode) { 35 | return mainNode.compareAndSet(old, newNode); 36 | } 37 | 38 | CNode mainNode() { 39 | return this.mainNode.get(); 40 | } 41 | 42 | boolean isTombed() { 43 | return this.mainNode() instanceof TNode; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/protocol/mysql/Constants.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 The Netty Project 3 | * 4 | * The Netty Project licenses this file to you under the Apache License, 5 | * version 2.0 (the "License"); you may not use this file except in compliance 6 | * with the License. You may obtain a copy of the License at: 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | 17 | package com.github.netty.protocol.mysql; 18 | 19 | 20 | public interface Constants { 21 | 22 | int NUL_BYTE = 0x00; 23 | 24 | int RESPONSE_ERROR = 0xFF; 25 | int RESPONSE_EOF = 0xFE; 26 | int RESPONSE_LOCAL_INFILE = 0xFB; 27 | int RESPONSE_OK = 0; 28 | 29 | int MINIMUM_SUPPORTED_PROTOCOL_VERSION = 10; 30 | 31 | int SQL_STATE_SIZE = 6; 32 | 33 | // Handshake constants 34 | int AUTH_PLUGIN_DATA_PART1_LEN = 8; 35 | int AUTH_PLUGIN_DATA_PART2_MIN_LEN = 13; 36 | int AUTH_PLUGIN_DATA_MIN_LEN = AUTH_PLUGIN_DATA_PART1_LEN + AUTH_PLUGIN_DATA_PART2_MIN_LEN; 37 | int HANDSHAKE_RESERVED_BYTES = 10; 38 | 39 | // Auth plugins 40 | String MYSQL_NATIVE_PASSWORD = "mysql_native_password"; 41 | 42 | int DEFAULT_MAX_PACKET_SIZE = 0xFFFFFF;//1048576 43 | 44 | String HANDLER_TYPE_FRONTEND = "frontend"; 45 | String HANDLER_TYPE_BACKEND = "backend"; 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/protocol/mqtt/interception/InterceptSubscribeMessage.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012-2018 The original author or authors 3 | * ------------------------------------------------------ 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Apache License v2.0 which accompanies this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * 11 | * The Apache License v2.0 is available at 12 | * http://www.opensource.org/licenses/apache2.0.php 13 | * 14 | * You may elect to redistribute this code under either of these licenses. 15 | */ 16 | 17 | package com.github.netty.protocol.mqtt.interception; 18 | 19 | import com.github.netty.protocol.mqtt.subscriptions.Subscription; 20 | import io.netty.handler.codec.mqtt.MqttQoS; 21 | 22 | public class InterceptSubscribeMessage implements InterceptMessage { 23 | 24 | private final Subscription subscription; 25 | private final String username; 26 | 27 | public InterceptSubscribeMessage(Subscription subscription, String username) { 28 | this.subscription = subscription; 29 | this.username = username; 30 | } 31 | 32 | public String getClientID() { 33 | return subscription.getClientId(); 34 | } 35 | 36 | public MqttQoS getRequestedQos() { 37 | return subscription.getRequestedQos(); 38 | } 39 | 40 | public String getTopicFilter() { 41 | return subscription.getTopicFilter().toString(); 42 | } 43 | 44 | public String getUsername() { 45 | return username; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/protocol/mysql/AbstractPacketEncoder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 The Netty Project 3 | * 4 | * The Netty Project licenses this file to you under the Apache License, 5 | * version 2.0 (the "License"); you may not use this file except in compliance 6 | * with the License. You may obtain a copy of the License at: 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | 17 | package com.github.netty.protocol.mysql; 18 | 19 | import io.netty.buffer.ByteBuf; 20 | import io.netty.channel.ChannelHandlerContext; 21 | import io.netty.handler.codec.MessageToByteEncoder; 22 | 23 | 24 | public abstract class AbstractPacketEncoder extends MessageToByteEncoder { 25 | 26 | @Override 27 | final protected void encode(ChannelHandlerContext ctx, T packet, ByteBuf buf) throws Exception { 28 | int writerIdx = buf.writerIndex(); 29 | buf.writeInt(0); // Advance the writer index so we can set the packet length after encoding 30 | encodePacket(ctx, packet, buf); 31 | int len = buf.writerIndex() - writerIdx - 4; 32 | buf.setMediumLE(writerIdx, len) 33 | .setByte(writerIdx + 3, packet.getSequenceId()); 34 | } 35 | 36 | protected abstract void encodePacket(ChannelHandlerContext ctx, T packet, ByteBuf buf) throws Exception; 37 | 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/protocol/mysql/server/ServerErrorPacket.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 The Netty Project 3 | * 4 | * The Netty Project licenses this file to you under the Apache License, 5 | * version 2.0 (the "License"); you may not use this file except in compliance 6 | * with the License. You may obtain a copy of the License at: 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | 17 | package com.github.netty.protocol.mysql.server; 18 | 19 | import com.github.netty.protocol.mysql.AbstractMySqlPacket; 20 | 21 | /** 22 | * This packet indicates that an error occurred. 23 | */ 24 | public class ServerErrorPacket extends AbstractMySqlPacket implements ServerPacket { 25 | 26 | private final int errorNumber; 27 | private final byte[] sqlState; 28 | private final String message; 29 | 30 | public ServerErrorPacket(int sequenceId, int errorNumber, byte[] sqlState, String message) { 31 | super(sequenceId); 32 | this.errorNumber = errorNumber; 33 | this.sqlState = sqlState; 34 | this.message = message; 35 | } 36 | 37 | public int getErrorNumber() { 38 | return errorNumber; 39 | } 40 | 41 | public byte[] getSqlState() { 42 | return sqlState; 43 | } 44 | 45 | public String getMessage() { 46 | return message; 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/protocol/mqtt/interception/InterceptPublishMessage.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012-2018 The original author or authors 3 | * ------------------------------------------------------ 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Apache License v2.0 which accompanies this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * 11 | * The Apache License v2.0 is available at 12 | * http://www.opensource.org/licenses/apache2.0.php 13 | * 14 | * You may elect to redistribute this code under either of these licenses. 15 | */ 16 | 17 | package com.github.netty.protocol.mqtt.interception; 18 | 19 | import io.netty.buffer.ByteBuf; 20 | import io.netty.handler.codec.mqtt.MqttPublishMessage; 21 | 22 | public class InterceptPublishMessage extends InterceptAbstractMessage { 23 | 24 | private final MqttPublishMessage msg; 25 | private final String clientID; 26 | private final String username; 27 | 28 | public InterceptPublishMessage(MqttPublishMessage msg, String clientID, String username) { 29 | super(msg); 30 | this.msg = msg; 31 | this.clientID = clientID; 32 | this.username = username; 33 | } 34 | 35 | public String getTopicName() { 36 | return msg.variableHeader().topicName(); 37 | } 38 | 39 | public ByteBuf getPayload() { 40 | return msg.payload(); 41 | } 42 | 43 | public String getClientID() { 44 | return clientID; 45 | } 46 | 47 | public String getUsername() { 48 | return username; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/test/java/com/github/netty/nrpc/server/example/RpcServerAop.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.nrpc.server.example; 2 | 3 | import com.github.netty.core.util.LoggerFactoryX; 4 | import com.github.netty.protocol.NRpcProtocol; 5 | import com.github.netty.protocol.nrpc.RpcContext; 6 | import com.github.netty.protocol.nrpc.RpcServerChannelHandler; 7 | import com.github.netty.protocol.nrpc.RpcServerInstance; 8 | import com.github.netty.protocol.nrpc.State; 9 | import org.springframework.stereotype.Component; 10 | 11 | import java.util.Map; 12 | 13 | /** 14 | * rpc call Lifecycle Management 15 | * @author wangzihao 2020-04-24 16 | */ 17 | @Component 18 | public class RpcServerAop implements com.github.netty.protocol.nrpc.RpcServerAop { 19 | 20 | @Override 21 | public void onInitAfter(NRpcProtocol protocol) { 22 | 23 | } 24 | 25 | @Override 26 | public void onConnectAfter(RpcServerChannelHandler channel) { 27 | 28 | } 29 | 30 | @Override 31 | public void onDisconnectAfter(RpcServerChannelHandler channel) { 32 | 33 | } 34 | 35 | @Override 36 | public void onDecodeRequestBefore(RpcContext rpcContext, Map params) { 37 | 38 | } 39 | 40 | @Override 41 | public void onTimeout(RpcContext rpcContext) { 42 | 43 | } 44 | 45 | @Override 46 | public void onResponseAfter(RpcContext rpcContext) { 47 | 48 | } 49 | 50 | @Override 51 | public void onStateUpdate(RpcContext rpcContext, State formState, State toState) { 52 | LoggerFactoryX.getLogger(getClass()).info("requestId = {}, form = {}, to = {}",rpcContext.getRequest().getRequestId(),formState,toState); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/protocol/mqtt/MemorySubscriptionsRepository.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012-2018 The original author or authors 3 | * ------------------------------------------------------ 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Apache License v2.0 which accompanies this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * 11 | * The Apache License v2.0 is available at 12 | * http://www.opensource.org/licenses/apache2.0.php 13 | * 14 | * You may elect to redistribute this code under either of these licenses. 15 | */ 16 | package com.github.netty.protocol.mqtt; 17 | 18 | import com.github.netty.protocol.mqtt.subscriptions.Subscription; 19 | 20 | import java.util.ArrayList; 21 | import java.util.Collections; 22 | import java.util.List; 23 | 24 | public class MemorySubscriptionsRepository implements ISubscriptionsRepository { 25 | 26 | private final List subscriptions = new ArrayList<>(); 27 | 28 | @Override 29 | public List listAllSubscriptions() { 30 | return Collections.unmodifiableList(subscriptions); 31 | } 32 | 33 | @Override 34 | public void addNewSubscription(Subscription subscription) { 35 | subscriptions.add(subscription); 36 | } 37 | 38 | @Override 39 | public void removeSubscription(String topic, String clientID) { 40 | subscriptions.stream() 41 | .filter(s -> s.getTopicFilter().toString().equals(topic) && s.getClientId().equals(clientID)) 42 | .findFirst() 43 | .ifPresent(subscriptions::remove); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/protocol/servlet/util/HttpConstants.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.protocol.servlet.util; 2 | 3 | import io.netty.util.AsciiString; 4 | 5 | import java.nio.charset.Charset; 6 | 7 | /** 8 | * @author wangzihao 9 | * 2018/7/15/015 10 | */ 11 | public class HttpConstants { 12 | 13 | public static final String JSESSION_ID_COOKIE = "JSESSIONID"; 14 | public static final String JSESSION_ID_URL = "jsessionid"; 15 | 16 | public static final String HTTPS = "https"; 17 | public static final int HTTPS_PORT = 443; 18 | public static final int HTTP_PORT = 80; 19 | public static final String HTTP = "http"; 20 | public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8"); 21 | public static final String DEFAULT_SESSION_COOKIE_PATH = "/"; 22 | public static final AsciiString H2_EXT_STREAM_ID = AsciiString.cached("x-http2-stream-id"); 23 | public static final AsciiString H2_EXT_SCHEME = AsciiString.cached("x-http2-scheme"); 24 | public static final boolean EXIST_DEPENDENCY_H2; 25 | public static final boolean EXIST_JAKARTA_WEBSOCKET; 26 | 27 | static { 28 | boolean isExistH2; 29 | try { 30 | Class.forName("io.netty.handler.codec.http2.Http2ConnectionHandler"); 31 | isExistH2 = true; 32 | } catch (Throwable e) { 33 | isExistH2 = false; 34 | } 35 | EXIST_DEPENDENCY_H2 = isExistH2; 36 | } 37 | 38 | static { 39 | boolean existJavaxWebsocket; 40 | try { 41 | Class.forName("jakarta.websocket.Endpoint"); 42 | existJavaxWebsocket = true; 43 | } catch (Throwable e) { 44 | existJavaxWebsocket = false; 45 | } 46 | EXIST_JAKARTA_WEBSOCKET = existJavaxWebsocket; 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/protocol/mqtt/config/BrokerConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012-2018 The original author or authors 3 | * ------------------------------------------------------ 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Apache License v2.0 which accompanies this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * 11 | * The Apache License v2.0 is available at 12 | * http://www.opensource.org/licenses/apache2.0.php 13 | * 14 | * You may elect to redistribute this code under either of these licenses. 15 | */ 16 | package com.github.netty.protocol.mqtt.config; 17 | 18 | public class BrokerConfiguration { 19 | 20 | private final boolean allowAnonymous; 21 | private final boolean allowZeroByteClientId; 22 | private final boolean reauthorizeSubscriptionsOnConnect; 23 | 24 | public BrokerConfiguration() { 25 | this(true, false, false); 26 | } 27 | 28 | public BrokerConfiguration(boolean allowAnonymous, boolean allowZeroByteClientId, 29 | boolean reauthorizeSubscriptionsOnConnect) { 30 | this.allowAnonymous = allowAnonymous; 31 | this.allowZeroByteClientId = allowZeroByteClientId; 32 | this.reauthorizeSubscriptionsOnConnect = reauthorizeSubscriptionsOnConnect; 33 | } 34 | 35 | public boolean isAllowAnonymous() { 36 | return allowAnonymous; 37 | } 38 | 39 | public boolean isAllowZeroByteClientId() { 40 | return allowZeroByteClientId; 41 | } 42 | 43 | public boolean isReauthorizeSubscriptionsOnConnect() { 44 | return reauthorizeSubscriptionsOnConnect; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/test/resources/websocket/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | My WebSocket 5 | 6 | 7 | 8 | 9 | 是否发送字节流 10 |
11 | 12 | 13 |
14 |
15 | 16 | 17 | 71 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/protocol/mqtt/interception/AbstractInterceptHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012-2018 The original author or authors 3 | * ------------------------------------------------------ 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Apache License v2.0 which accompanies this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * 11 | * The Apache License v2.0 is available at 12 | * http://www.opensource.org/licenses/apache2.0.php 13 | * 14 | * You may elect to redistribute this code under either of these licenses. 15 | */ 16 | 17 | package com.github.netty.protocol.mqtt.interception; 18 | 19 | /** 20 | * Basic abstract class usefull to avoid empty methods creation in subclasses. 21 | */ 22 | public abstract class AbstractInterceptHandler implements InterceptHandler { 23 | 24 | @Override 25 | public Class[] getInterceptedMessageTypes() { 26 | return InterceptHandler.ALL_MESSAGE_TYPES; 27 | } 28 | 29 | @Override 30 | public void onConnect(InterceptConnectMessage msg) { 31 | } 32 | 33 | @Override 34 | public void onDisconnect(InterceptDisconnectMessage msg) { 35 | } 36 | 37 | @Override 38 | public void onConnectionLost(InterceptConnectionLostMessage msg) { 39 | } 40 | 41 | @Override 42 | public void onPublish(InterceptPublishMessage msg) { 43 | } 44 | 45 | @Override 46 | public void onSubscribe(InterceptSubscribeMessage msg) { 47 | } 48 | 49 | @Override 50 | public void onUnsubscribe(InterceptUnsubscribeMessage msg) { 51 | } 52 | 53 | @Override 54 | public void onMessageAcknowledged(InterceptAcknowledgedMessage msg) { 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/protocol/mysql/server/ServerResultsetRowPacket.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 The Netty Project 3 | * 4 | * The Netty Project licenses this file to you under the Apache License, 5 | * version 2.0 (the "License"); you may not use this file except in compliance 6 | * with the License. You may obtain a copy of the License at: 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | 17 | package com.github.netty.protocol.mysql.server; 18 | 19 | import com.github.netty.protocol.mysql.AbstractMySqlPacket; 20 | 21 | import java.util.ArrayList; 22 | import java.util.Collection; 23 | import java.util.Collections; 24 | import java.util.List; 25 | 26 | 27 | public class ServerResultsetRowPacket extends AbstractMySqlPacket implements ServerPacket { 28 | private final List values; 29 | 30 | public ServerResultsetRowPacket(int sequenceId, String... values) { 31 | super(sequenceId); 32 | this.values = new ArrayList<>(values.length); 33 | Collections.addAll(this.values, values); 34 | } 35 | 36 | public ServerResultsetRowPacket(int sequenceId, Collection values) { 37 | super(sequenceId); 38 | this.values = new ArrayList<>(values.size()); 39 | this.values.addAll(values); 40 | } 41 | 42 | public List getValues() { 43 | return values; 44 | } 45 | 46 | @Override 47 | public String toString() { 48 | return super.toString() + "," + values.size(); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/test/java/com/github/netty/mysql/MysqlTests.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.mysql; 2 | 3 | import com.mysql.cj.jdbc.MysqlDataSource; 4 | import org.junit.jupiter.api.Test; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.util.Assert; 7 | 8 | import java.sql.*; 9 | import java.util.ArrayList; 10 | import java.util.LinkedHashMap; 11 | import java.util.List; 12 | import java.util.Map; 13 | 14 | @SpringBootTest(classes = MysqlTests.class) 15 | public class MysqlTests { 16 | private final MysqlDataSource dataSource = new MysqlDataSource(); 17 | 18 | private static List> dumpResultSet(ResultSet resultSet) throws SQLException { 19 | List> list = new ArrayList<>(); 20 | ResultSetMetaData metaData = resultSet.getMetaData(); 21 | while (resultSet.next()) { 22 | Map map = new LinkedHashMap<>(); 23 | for (int i = 1; i <= metaData.getColumnCount(); i++) { 24 | map.put(metaData.getColumnName(i), resultSet.getObject(i)); 25 | } 26 | list.add(map); 27 | } 28 | return list; 29 | } 30 | 31 | public void init() { 32 | dataSource.setURL("jdbc:mysql://localhost:8080/ig_zues"); 33 | dataSource.setUser("root"); 34 | dataSource.setPassword("root"); 35 | } 36 | 37 | @Test 38 | public void test() throws SQLException { 39 | init(); 40 | 41 | try (Connection connection = dataSource.getConnection()) { 42 | PreparedStatement statement = connection.prepareStatement("select * from information_schema.schemata"); 43 | List> list = dumpResultSet(statement.executeQuery()); 44 | 45 | Assert.isTrue(list.size() > 0,"mysql test error"); 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/io/netty/channel/epoll/EpollChannelReportRunnable.java: -------------------------------------------------------------------------------- 1 | package io.netty.channel.epoll; 2 | 3 | import com.github.netty.core.TcpChannel; 4 | import com.github.netty.core.util.LoggerX; 5 | import io.netty.channel.ChannelOutboundBuffer; 6 | import io.netty.channel.EventLoop; 7 | import io.netty.channel.SingleThreadEventLoop; 8 | 9 | public class EpollChannelReportRunnable implements Runnable { 10 | private LoggerX logger; 11 | 12 | public EpollChannelReportRunnable(LoggerX logger) { 13 | this.logger = logger; 14 | } 15 | 16 | @Override 17 | public void run() { 18 | if (!TcpChannel.getChannels().values().isEmpty()) { 19 | for (TcpChannel ctx : TcpChannel.getChannels().values()) { 20 | AbstractEpollChannel channel = ((AbstractEpollChannel) ctx.getChannel()); 21 | boolean isFlushPending = channel.isFlagSet(Native.EPOLLOUT); 22 | ChannelOutboundBuffer outboundBuffer = ctx.getChannel().unsafe().outboundBuffer(); 23 | long totalPendingWriteBytes = outboundBuffer == null ? 0 : outboundBuffer.totalPendingWriteBytes(); 24 | EventLoop eventLoop = ctx.getChannel().eventLoop(); 25 | 26 | boolean inEventLoop = eventLoop.inEventLoop(); 27 | int pendingTasks = ((SingleThreadEventLoop) ctx.getChannel().eventLoop()).pendingTasks(); 28 | 29 | logger.info("remote = {}, isFlushPending = {}, totalPendingWriteBytes = {}/B, eventLoop = {}, pendingTasks = {}", 30 | ctx.getChannel().remoteAddress(), 31 | isFlushPending, 32 | totalPendingWriteBytes, 33 | eventLoop, 34 | pendingTasks); 35 | } 36 | logger.info("-----------------------"); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/test/java/com/github/netty/http2/Http2Tests.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.http2; 2 | 3 | import com.github.netty.protocol.servlet.http2.NettyHttp2Client; 4 | import io.netty.buffer.Unpooled; 5 | import io.netty.handler.codec.http.HttpMethod; 6 | import io.netty.handler.logging.LogLevel; 7 | import okhttp3.OkHttpClient; 8 | import okhttp3.Protocol; 9 | import okhttp3.Request; 10 | import okhttp3.Response; 11 | 12 | import java.util.Arrays; 13 | import java.util.List; 14 | 15 | public class Http2Tests { 16 | 17 | public static void main(String[] args) throws Exception { 18 | OkHttpClient okHttpClient = new OkHttpClient.Builder() 19 | .protocols(Arrays.asList(Protocol.H2_PRIOR_KNOWLEDGE)) 20 | .build(); 21 | 22 | Request build = new Request.Builder() 23 | .url("http://localhost/test") 24 | .build(); 25 | Response execute = okHttpClient.newCall(build).execute(); 26 | String string = execute.body().string(); 27 | System.out.println("execute = " + execute); 28 | 29 | NettyHttp2Client http2Client = new NettyHttp2Client("http://localhost") 30 | .logger(LogLevel.INFO) 31 | .awaitConnect(); 32 | for (int i = 0; i < 1; i++) { 33 | http2Client.writeAndFlush(HttpMethod.GET, "/test", Unpooled.EMPTY_BUFFER).onSuccess(e -> { 34 | System.out.println(e); 35 | }); 36 | } 37 | 38 | List httpPromises = http2Client.flush().get(); 39 | httpPromises.forEach(NettyHttp2Client.H2Response::close); 40 | 41 | Long closeTime = http2Client.close(true).get(); 42 | System.out.printf("connectTime = %d, closeTime = %d \n", 43 | http2Client.getEndConnectTimestamp() - http2Client.getBeginConnectTimestamp(), closeTime); 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/protocol/nrpc/RpcDone.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.protocol.nrpc; 2 | 3 | import com.github.netty.protocol.nrpc.exception.RpcResponseException; 4 | 5 | /** 6 | * rpc done callback 7 | * 8 | * @author wangzihao 9 | */ 10 | public interface RpcDone { 11 | /** 12 | * on chunk callback 13 | * 14 | * @param rpcResponse rpcResponse 15 | * @param ack ack 16 | */ 17 | void chunk(RpcPacket.ResponseChunkPacket rpcResponse, ChunkAck ack); 18 | 19 | /** 20 | * on done callback 21 | * 22 | * @param rpcResponse rpcResponse 23 | */ 24 | void done(RpcPacket.ResponseLastPacket rpcResponse); 25 | 26 | /** 27 | * on timeout 28 | * 29 | * @param requestId requestId 30 | * @param createTimestamp createTimestamp 31 | * @param expiryTimestamp expiryTimestamp 32 | */ 33 | void doneTimeout(int requestId, long createTimestamp, long expiryTimestamp); 34 | 35 | /** 36 | * If an exception state is returned, an exception is thrown 37 | * All response states above 400 are in error 38 | * 39 | * @param response response 40 | * @throws RpcResponseException RpcResponseException 41 | */ 42 | default void handlerResponseIfNeedThrow(RpcPacket.ResponsePacket response) throws RpcResponseException { 43 | if (response == null) { 44 | return; 45 | } 46 | 47 | Integer status = response.getStatus(); 48 | if (status == null || status >= RpcPacket.ResponsePacket.NO_SUCH_METHOD) { 49 | throw new RpcResponseException(status, "Failure rpc response. status=" + status + ",message=" + response.getMessage() + ",response=" + response, true); 50 | } 51 | } 52 | 53 | @FunctionalInterface 54 | interface ChunkListener { 55 | void onChunk(CHUNK chunk, int chunkId, ChunkAck ack); 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/protocol/servlet/util/HttpAbortPolicyWithReport.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.protocol.servlet.util; 2 | 3 | import com.github.netty.core.util.AbortPolicyWithReport; 4 | import com.github.netty.protocol.servlet.NettyMessageToServletRunnable; 5 | import com.github.netty.protocol.servlet.ServletHttpExchange; 6 | import jakarta.servlet.http.HttpServletResponse; 7 | 8 | import java.util.concurrent.ThreadPoolExecutor; 9 | 10 | /** 11 | * http refusal to handle the strategy, send 503 status code 12 | * 13 | * Status code (503) indicating that the HTTP server is 14 | * temporarily overloaded, and unable to handle the request. 15 | * 16 | * @author wangzihaogithub 2020-11-21 17 | * @see #rejectedExecution(NettyMessageToServletRunnable.HttpRunnable, ThreadPoolExecutor, ServletHttpExchange) 18 | */ 19 | public class HttpAbortPolicyWithReport extends AbortPolicyWithReport { 20 | public HttpAbortPolicyWithReport(String threadName, String dumpPath, String info) { 21 | super(threadName, dumpPath, info); 22 | } 23 | 24 | @Override 25 | public void rejectedExecution(Runnable r, ThreadPoolExecutor e) { 26 | if (r instanceof NettyMessageToServletRunnable.HttpRunnable) { 27 | NettyMessageToServletRunnable.HttpRunnable httpRunnable = (NettyMessageToServletRunnable.HttpRunnable) r; 28 | rejectedExecution(httpRunnable, e, httpRunnable.getExchange()); 29 | } else { 30 | super.rejectedExecution(r, e); 31 | } 32 | } 33 | 34 | protected void rejectedExecution(NettyMessageToServletRunnable.HttpRunnable httpRunnable, 35 | ThreadPoolExecutor e, ServletHttpExchange exchange) { 36 | exchange.getResponse().setStatus(HttpServletResponse.SC_SERVICE_UNAVAILABLE); 37 | exchange.getResponse().setHeader("Connection", "Close"); 38 | super.rejectedExecution(httpRunnable, e); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/test/java/com/github/netty/myprotocol/MyServer.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.myprotocol; 2 | 3 | import com.github.netty.StartupServer; 4 | import com.github.netty.core.AbstractChannelHandler; 5 | import com.github.netty.core.AbstractProtocol; 6 | import io.netty.buffer.ByteBuf; 7 | import io.netty.buffer.Unpooled; 8 | import io.netty.channel.Channel; 9 | import io.netty.channel.ChannelHandlerContext; 10 | 11 | import java.nio.charset.Charset; 12 | import java.util.Objects; 13 | 14 | public class MyServer { 15 | 16 | public static void main(String[] args) { 17 | StartupServer server = new StartupServer(8080); 18 | server.addProtocol(new MyProtocol()); 19 | server.start(); 20 | } 21 | 22 | public static class MyProtocol extends AbstractProtocol { 23 | public static final String HANDSHAKE_KEY = "开启吧!我的自定义协议"; 24 | private static final Charset UTF8 = Charset.forName("utf-8"); 25 | 26 | @Override 27 | public boolean canSupport(ByteBuf msg) { 28 | String reqString = msg.toString(UTF8); 29 | return Objects.equals(HANDSHAKE_KEY, reqString); 30 | } 31 | 32 | @Override 33 | public void addPipeline(Channel channel, ByteBuf clientFirstMsg) throws Exception { 34 | channel.pipeline().addLast(new AbstractChannelHandler() { 35 | private boolean connection; 36 | 37 | @Override 38 | protected void onMessageReceived(ChannelHandlerContext ctx, ByteBuf msg) throws Exception { 39 | if (connection) { 40 | System.out.println("收到! = " + msg.toString(UTF8)); 41 | } else { 42 | ctx.writeAndFlush(Unpooled.copiedBuffer("握手完毕! 请开始你的表演~", UTF8)); 43 | connection = true; 44 | } 45 | } 46 | }); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/io/netty/channel/nio/NioChannelReportRunnable.java: -------------------------------------------------------------------------------- 1 | package io.netty.channel.nio; 2 | 3 | import com.github.netty.core.TcpChannel; 4 | import com.github.netty.core.util.LoggerX; 5 | import io.netty.channel.ChannelOutboundBuffer; 6 | import io.netty.channel.EventLoop; 7 | import io.netty.channel.SingleThreadEventLoop; 8 | 9 | import java.nio.channels.SelectionKey; 10 | 11 | public class NioChannelReportRunnable implements Runnable { 12 | private LoggerX logger; 13 | 14 | public NioChannelReportRunnable(LoggerX logger) { 15 | this.logger = logger; 16 | } 17 | 18 | @Override 19 | public void run() { 20 | if (!TcpChannel.getChannels().values().isEmpty()) { 21 | for (TcpChannel ctx : TcpChannel.getChannels().values()) { 22 | SelectionKey selectionKey = ((AbstractNioChannel) ctx.getChannel()).selectionKey(); 23 | boolean isFlushPending = selectionKey.isValid() && (selectionKey.interestOps() & SelectionKey.OP_WRITE) != 0; 24 | ChannelOutboundBuffer outboundBuffer = ctx.getChannel().unsafe().outboundBuffer(); 25 | long totalPendingWriteBytes = outboundBuffer == null ? 0 : outboundBuffer.totalPendingWriteBytes(); 26 | EventLoop eventLoop = ctx.getChannel().eventLoop(); 27 | 28 | boolean inEventLoop = eventLoop.inEventLoop(); 29 | int pendingTasks = ((SingleThreadEventLoop) ctx.getChannel().eventLoop()).pendingTasks(); 30 | 31 | logger.info("remote = {}, isFlushPending = {}, totalPendingWriteBytes = {}/B, eventLoop = {}, pendingTasks = {}", 32 | ctx.getChannel().remoteAddress(), 33 | isFlushPending, 34 | totalPendingWriteBytes, 35 | eventLoop, 36 | pendingTasks); 37 | } 38 | logger.info("-----------------------"); 39 | } 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/protocol/mqtt/subscriptions/TNode.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012-2018 The original author or authors 3 | * ------------------------------------------------------ 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Apache License v2.0 which accompanies this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * 11 | * The Apache License v2.0 is available at 12 | * http://www.opensource.org/licenses/apache2.0.php 13 | * 14 | * You may elect to redistribute this code under either of these licenses. 15 | */ 16 | package com.github.netty.protocol.mqtt.subscriptions; 17 | 18 | class TNode extends CNode { 19 | 20 | @Override 21 | INode childOf(Token token) { 22 | throw new IllegalStateException("Can't be invoked on TNode"); 23 | } 24 | 25 | @Override 26 | CNode copy() { 27 | throw new IllegalStateException("Can't be invoked on TNode"); 28 | } 29 | 30 | @Override 31 | public void add(INode newINode) { 32 | throw new IllegalStateException("Can't be invoked on TNode"); 33 | } 34 | 35 | @Override 36 | CNode addSubscription(Subscription newSubscription) { 37 | throw new IllegalStateException("Can't be invoked on TNode"); 38 | } 39 | 40 | @Override 41 | boolean containsOnly(String clientId) { 42 | throw new IllegalStateException("Can't be invoked on TNode"); 43 | } 44 | 45 | @Override 46 | public boolean contains(String clientId) { 47 | throw new IllegalStateException("Can't be invoked on TNode"); 48 | } 49 | 50 | @Override 51 | void removeSubscriptionsFor(String clientId) { 52 | throw new IllegalStateException("Can't be invoked on TNode"); 53 | } 54 | 55 | @Override 56 | boolean anyChildrenMatch(Token token) { 57 | return false; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/core/util/NettyThreadX.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.core.util; 2 | 3 | import io.netty.util.concurrent.FastThreadLocalThread; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | import java.util.function.Consumer; 8 | 9 | /** 10 | * Created by wangzihao on 2018/9/9/009. 11 | */ 12 | public class NettyThreadX extends FastThreadLocalThread { 13 | private List> threadStopListenerList; 14 | 15 | public NettyThreadX() { 16 | super(); 17 | } 18 | 19 | public NettyThreadX(Runnable target) { 20 | super(target); 21 | } 22 | 23 | public NettyThreadX(ThreadGroup group, Runnable target) { 24 | super(group, target); 25 | } 26 | 27 | public NettyThreadX(String name) { 28 | super(name); 29 | } 30 | 31 | public NettyThreadX(ThreadGroup group, String name) { 32 | super(group, name); 33 | } 34 | 35 | public NettyThreadX(Runnable target, String name) { 36 | super(target, name); 37 | } 38 | 39 | public NettyThreadX(ThreadGroup group, Runnable target, String name) { 40 | super(group, target, name); 41 | } 42 | 43 | public NettyThreadX(ThreadGroup group, Runnable target, String name, long stackSize) { 44 | super(group, target, name, stackSize); 45 | } 46 | 47 | @Override 48 | public void run() { 49 | try { 50 | super.run(); 51 | } finally { 52 | if (threadStopListenerList != null) { 53 | for (Consumer threadStopListener : threadStopListenerList) { 54 | threadStopListener.accept(this); 55 | } 56 | } 57 | } 58 | } 59 | 60 | public void addThreadStopListener(Consumer threadStopListener) { 61 | if (threadStopListenerList == null) { 62 | threadStopListenerList = new ArrayList<>(); 63 | } 64 | threadStopListenerList.add(threadStopListener); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/protocol/mysql/exception/ProxyException.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.protocol.mysql.exception; 2 | 3 | import java.io.ByteArrayOutputStream; 4 | import java.io.IOException; 5 | import java.io.PrintStream; 6 | 7 | /** 8 | * ProxyException 9 | * 10 | * @author wangzihaogithub 2020-4-23 12:09:02 11 | */ 12 | public class ProxyException extends RuntimeException { 13 | public static final int ERROR_UNKOWN = 3000; 14 | public static final int ERROR_BACKEND_NO_CONNECTION = 3001; 15 | public static final int ERROR_BACKEND_CONNECT_FAIL = 3002; 16 | private int errorNumber = ERROR_UNKOWN; 17 | 18 | public ProxyException() { 19 | super(); 20 | } 21 | 22 | public ProxyException(int errorNumber, String message) { 23 | super(message); 24 | this.errorNumber = errorNumber; 25 | } 26 | 27 | public ProxyException(int errorNumber, String message, Throwable cause) { 28 | super(message, cause, false, false); 29 | this.errorNumber = errorNumber; 30 | } 31 | 32 | public static String stackTraceToString(Throwable cause) { 33 | ByteArrayOutputStream out = new ByteArrayOutputStream(); 34 | PrintStream pout = new PrintStream(out); 35 | cause.printStackTrace(pout); 36 | pout.flush(); 37 | try { 38 | return new String(out.toByteArray()); 39 | } finally { 40 | try { 41 | out.close(); 42 | } catch (IOException ignore) { 43 | // ignore as should never happen 44 | } 45 | } 46 | } 47 | 48 | public int getErrorNumber() { 49 | return errorNumber; 50 | } 51 | 52 | public void setErrorNumber(int errorNumber) { 53 | this.errorNumber = errorNumber; 54 | } 55 | 56 | @Override 57 | public String toString() { 58 | String s = getClass().getSimpleName(); 59 | String message = getLocalizedMessage(); 60 | return (message != null) ? (s + ": " + message) : s; 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/protocol/mysql/AbstractAuthPluginDataBuilder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 The Netty Project 3 | * 4 | * The Netty Project licenses this file to you under the Apache License, 5 | * version 2.0 (the "License"); you may not use this file except in compliance 6 | * with the License. You may obtain a copy of the License at: 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | 17 | package com.github.netty.protocol.mysql; 18 | 19 | import io.netty.buffer.ByteBuf; 20 | import io.netty.buffer.Unpooled; 21 | 22 | import java.util.Collection; 23 | import java.util.Collections; 24 | import java.util.Set; 25 | 26 | 27 | public abstract class AbstractAuthPluginDataBuilder { 28 | public final ByteBuf authPluginData = Unpooled.buffer(); 29 | public final Set capabilities = CapabilityFlags.getImplicitCapabilities(); 30 | 31 | public B addCapabilities(CapabilityFlags... capabilities) { 32 | Collections.addAll(this.capabilities, capabilities); 33 | return (B) this; 34 | } 35 | 36 | public B addCapabilities(Collection capabilities) { 37 | this.capabilities.addAll(capabilities); 38 | return (B) this; 39 | } 40 | 41 | public boolean hasCapability(CapabilityFlags capability) { 42 | return capabilities.contains(capability); 43 | } 44 | 45 | public B addAuthData(byte[] bytes) { 46 | authPluginData.writeBytes(bytes); 47 | return (B) this; 48 | } 49 | 50 | public B addAuthData(ByteBuf buf, int length) { 51 | authPluginData.writeBytes(buf, length); 52 | return (B) this; 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/protocol/mysql/server/ServerEofPacket.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 The Netty Project 3 | * 4 | * The Netty Project licenses this file to you under the Apache License, 5 | * version 2.0 (the "License"); you may not use this file except in compliance 6 | * with the License. You may obtain a copy of the License at: 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | 17 | package com.github.netty.protocol.mysql.server; 18 | 19 | import com.github.netty.protocol.mysql.AbstractMySqlPacket; 20 | import com.github.netty.protocol.mysql.ServerStatusFlag; 21 | 22 | import java.util.Collection; 23 | import java.util.Collections; 24 | import java.util.EnumSet; 25 | import java.util.Set; 26 | 27 | 28 | public class ServerEofPacket extends AbstractMySqlPacket implements ServerPacket { 29 | 30 | private final int warnings; 31 | private final Set statusFlags = EnumSet.noneOf(ServerStatusFlag.class); 32 | 33 | public ServerEofPacket(int sequenceId, int warnings, ServerStatusFlag... flags) { 34 | super(sequenceId); 35 | this.warnings = warnings; 36 | Collections.addAll(statusFlags, flags); 37 | } 38 | 39 | public ServerEofPacket(int sequenceId, int warnings, Collection flags) { 40 | super(sequenceId); 41 | this.warnings = warnings; 42 | statusFlags.addAll(flags); 43 | } 44 | 45 | public int getWarnings() { 46 | return warnings; 47 | } 48 | 49 | public Set getStatusFlags() { 50 | return statusFlags; 51 | } 52 | 53 | @Override 54 | public String toString() { 55 | return super.toString() + "," + statusFlags; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/protocol/dubbo/packet/BodyRequest.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.protocol.dubbo.packet; 2 | 3 | import com.github.netty.protocol.dubbo.Body; 4 | 5 | import java.util.Map; 6 | 7 | public class BodyRequest extends Body { 8 | private final String dubboVersion; 9 | private final String path; 10 | private final String version; 11 | private final String methodName; 12 | private final String parameterTypesDesc; 13 | private final Object[] parameterValues; 14 | private final Map attachments; 15 | 16 | public BodyRequest(String dubboVersion, String path, String version, 17 | String methodName, String parameterTypesDesc, 18 | Map attachments, 19 | Object[] parameterValues) { 20 | this.dubboVersion = dubboVersion; 21 | this.path = path; 22 | this.version = version; 23 | this.methodName = methodName; 24 | this.parameterTypesDesc = parameterTypesDesc; 25 | this.attachments = attachments; 26 | this.parameterValues = parameterValues; 27 | } 28 | 29 | public String getDubboVersion() { 30 | return dubboVersion; 31 | } 32 | 33 | public String getPath() { 34 | return path; 35 | } 36 | 37 | public String getVersion() { 38 | return version; 39 | } 40 | 41 | public String getMethodName() { 42 | return methodName; 43 | } 44 | 45 | public String getParameterTypesDesc() { 46 | return parameterTypesDesc; 47 | } 48 | 49 | public Object[] getParameterValues() { 50 | return parameterValues; 51 | } 52 | 53 | public Map getAttachments() { 54 | return attachments; 55 | } 56 | 57 | @Override 58 | public String toString() { 59 | return "BodyRequest{" + 60 | "\n\tpath='" + path + '\'' + 61 | ",\n\tmethodName='" + methodName + '\'' + 62 | ",\n\tattachments=" + attachments + 63 | "\n}"; 64 | } 65 | } -------------------------------------------------------------------------------- /src/test/java/com/github/netty/mqtt/MqttConsumerBootstrap.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.mqtt; 2 | 3 | import com.github.netty.core.util.LoggerFactoryX; 4 | import com.github.netty.core.util.LoggerX; 5 | import io.netty.handler.codec.mqtt.MqttQoS; 6 | import io.vertx.core.AbstractVerticle; 7 | import io.vertx.core.Verticle; 8 | import io.vertx.core.Vertx; 9 | import io.vertx.core.buffer.Buffer; 10 | import io.vertx.mqtt.MqttClient; 11 | import io.vertx.mqtt.MqttClientOptions; 12 | 13 | /** 14 | * 消费者测试 (一直运行) 注: mqtt-broker端口=8080 15 | * 16 | * 用于测试qps性能, 直接右键运行即可 17 | * MQTT协议 18 | * @author wangzihao 19 | * 2020/4/24 20 | */ 21 | public class MqttConsumerBootstrap { 22 | private static LoggerX logger = LoggerFactoryX.getLogger(MqttConsumerBootstrap.class); 23 | 24 | public static void main(String[] args) { 25 | Verticle verticle = new AbstractVerticle() { 26 | @Override 27 | public void start() { 28 | MqttClient client = MqttClient.create(vertx, new MqttClientOptions() 29 | //开启遗言 30 | .setWillFlag(true) 31 | .setWillTopic("willTopic") 32 | .setWillMessageBytes(Buffer.buffer("hello")) 33 | // .setWillMessage("hello") 34 | 35 | .setUsername("admin") 36 | .setPassword("123456") 37 | .setMaxMessageSize(8192)); 38 | 39 | client.connect(MqttBrokerBootstrap.PORT,"localhost").andThen(s -> { 40 | client.publishHandler(response -> { 41 | String message = new String(response.payload().getBytes()); 42 | logger.info("订阅收到topic={}的数据: {}", response.topicName(),message); 43 | }); 44 | 45 | client.subscribe("#", MqttQoS.AT_LEAST_ONCE.value()).andThen(resp -> { 46 | logger.info("subscribe {}", resp); 47 | }); 48 | 49 | }); 50 | } 51 | }; 52 | Vertx.vertx().deployVerticle(verticle); 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/protocol/mqtt/interception/Interceptor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012-2018 The original author or authors 3 | * ------------------------------------------------------ 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Apache License v2.0 which accompanies this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * 11 | * The Apache License v2.0 is available at 12 | * http://www.opensource.org/licenses/apache2.0.php 13 | * 14 | * You may elect to redistribute this code under either of these licenses. 15 | */ 16 | 17 | package com.github.netty.protocol.mqtt.interception; 18 | 19 | import com.github.netty.protocol.mqtt.subscriptions.Subscription; 20 | import io.netty.handler.codec.mqtt.MqttConnectMessage; 21 | import io.netty.handler.codec.mqtt.MqttPublishMessage; 22 | 23 | /** 24 | * This interface is to be used internally by the broker components. 25 | * 26 | * An interface is used instead of a class to allow more flexibility in changing an implementation. 27 | * 28 | * Interceptor implementations forward notifications to a InterceptHandler, that is 29 | * normally a field. So, the implementations should act as a proxy to a custom intercept handler. 30 | * 31 | * @see InterceptHandler 32 | */ 33 | public interface Interceptor { 34 | 35 | void notifyClientConnected(MqttConnectMessage msg); 36 | 37 | void notifyClientDisconnected(String clientID, String username); 38 | 39 | void notifyClientConnectionLost(String clientID, String username); 40 | 41 | void notifyTopicPublished(MqttPublishMessage msg, String clientID, String username); 42 | 43 | void notifyTopicSubscribed(Subscription sub, String username); 44 | 45 | void notifyTopicUnsubscribed(String topic, String clientID, String username); 46 | 47 | void notifyMessageAcknowledged(InterceptAcknowledgedMessage msg); 48 | 49 | void addInterceptHandler(InterceptHandler interceptHandler); 50 | 51 | void removeInterceptHandler(InterceptHandler interceptHandler); 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/protocol/mqtt/subscriptions/Token.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012-2018 The original author or authors 3 | * ------------------------------------------------------ 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Apache License v2.0 which accompanies this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * 11 | * The Apache License v2.0 is available at 12 | * http://www.opensource.org/licenses/apache2.0.php 13 | * 14 | * You may elect to redistribute this code under either of these licenses. 15 | */ 16 | 17 | package com.github.netty.protocol.mqtt.subscriptions; 18 | 19 | /** 20 | * Internal use only class. 21 | */ 22 | public class Token { 23 | 24 | static final Token EMPTY = new Token(""); 25 | static final Token MULTI = new Token("#"); 26 | static final Token SINGLE = new Token("+"); 27 | final String name; 28 | 29 | protected Token(String s) { 30 | name = s; 31 | } 32 | 33 | protected String name() { 34 | return name; 35 | } 36 | 37 | protected boolean match(Token t) { 38 | if (MULTI.equals(t) || SINGLE.equals(t)) { 39 | return false; 40 | } 41 | 42 | if (MULTI.equals(this) || SINGLE.equals(this)) { 43 | return true; 44 | } 45 | 46 | return equals(t); 47 | } 48 | 49 | @Override 50 | public int hashCode() { 51 | int hash = 7; 52 | hash = 29 * hash + (this.name != null ? this.name.hashCode() : 0); 53 | return hash; 54 | } 55 | 56 | @Override 57 | public boolean equals(Object obj) { 58 | if (obj == null) { 59 | return false; 60 | } 61 | if (getClass() != obj.getClass()) { 62 | return false; 63 | } 64 | final Token other = (Token) obj; 65 | return (this.name == null) ? (other.name == null) : this.name.equals(other.name); 66 | } 67 | 68 | @Override 69 | public String toString() { 70 | return name; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/core/util/ThreadPoolX.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.core.util; 2 | 3 | import java.util.concurrent.RejectedExecutionException; 4 | import java.util.concurrent.RejectedExecutionHandler; 5 | import java.util.concurrent.ScheduledThreadPoolExecutor; 6 | import java.util.concurrent.ThreadPoolExecutor; 7 | 8 | /** 9 | * @author wangzihao 10 | */ 11 | public class ThreadPoolX extends ScheduledThreadPoolExecutor { 12 | 13 | private static ThreadPoolX DEFAULT_INSTANCE; 14 | 15 | public ThreadPoolX(int corePoolSize) { 16 | this("", corePoolSize); 17 | } 18 | 19 | public ThreadPoolX(String preName, int corePoolSize) { 20 | this(preName, corePoolSize, Thread.MAX_PRIORITY, false); 21 | } 22 | 23 | public ThreadPoolX(String preName, int corePoolSize, int priority, boolean daemon) { 24 | super(corePoolSize, new ThreadFactoryX(preName, ThreadPoolX.class, priority, daemon), new RejectedExecutionHandlerX()); 25 | } 26 | 27 | public static ThreadPoolX getDefaultInstance() { 28 | if (DEFAULT_INSTANCE == null) { 29 | synchronized (ThreadPoolX.class) { 30 | if (DEFAULT_INSTANCE == null) { 31 | DEFAULT_INSTANCE = new ThreadPoolX("Default", SystemPropertyUtil.getInt("netty-core.defaultThreadPoolCount", 3)); 32 | } 33 | } 34 | } 35 | return DEFAULT_INSTANCE; 36 | } 37 | 38 | @Override 39 | public void execute(Runnable command) { 40 | super.execute(command); 41 | } 42 | 43 | @Override 44 | protected void beforeExecute(Thread t, Runnable r) { 45 | // 46 | } 47 | 48 | @Override 49 | protected void afterExecute(Runnable r, Throwable t) { 50 | // 51 | } 52 | 53 | private static class RejectedExecutionHandlerX implements RejectedExecutionHandler { 54 | 55 | private RejectedExecutionHandlerX() { 56 | } 57 | 58 | @Override 59 | public void rejectedExecution(Runnable r, ThreadPoolExecutor e) { 60 | throw new RejectedExecutionException("Task " + r.toString() + " rejected from " + e.toString()); 61 | } 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /src/test/java/com/github/netty/stomp/example/HelloController.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.stomp.example; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.messaging.Message; 7 | import org.springframework.messaging.handler.annotation.DestinationVariable; 8 | import org.springframework.messaging.handler.annotation.MessageMapping; 9 | import org.springframework.messaging.simp.SimpMessagingTemplate; 10 | import org.springframework.messaging.simp.annotation.SubscribeMapping; 11 | import org.springframework.messaging.simp.user.SimpUserRegistry; 12 | import org.springframework.web.bind.annotation.RestController; 13 | 14 | import java.security.Principal; 15 | 16 | /** 17 | * 我的房间Controller (供websocket客户端订阅或请求) 18 | * 19 | * @author wangzihao 20 | */ 21 | @RestController 22 | public class HelloController { 23 | private Logger logger = LoggerFactory.getLogger(getClass()); 24 | //所有在线的用户 25 | @Autowired 26 | private SimpUserRegistry userRegistry; 27 | //发送消息的工具类 (可以主动回复客户端) 28 | @Autowired 29 | private SimpMessagingTemplate messagingTemplate; 30 | 31 | /** 32 | * 订阅房间 33 | * 34 | * @param message 消息 35 | * @param principal 订阅人的用户身份(当前登录人的信息) 36 | * @param username 被订阅人的账号 37 | * @param roomName 被订阅的房间名 38 | */ 39 | @SubscribeMapping("/user/room/{username}/{roomName}") 40 | public void subscribeMyRoom(Message message, Principal principal, @DestinationVariable("username") String username, @DestinationVariable("roomName") String roomName) { 41 | logger.info("[" + principal.getName() + "]订阅了[" + username + "]的 [" + roomName + "] 房间"); 42 | } 43 | 44 | /** 45 | * 接收消息 46 | * 47 | * @param message 客户端的数据 48 | * @param principal 当前登录人的信息 49 | */ 50 | @MessageMapping("/receiveMessage") 51 | public void receiveMessage(Message message, Principal principal) { 52 | String payload = new String((byte[]) message.getPayload()); 53 | logger.info("已收到[" + principal.getName() + "]的消息[" + payload + "] 当前在线人数[" + userRegistry.getUserCount() + "]"); 54 | } 55 | 56 | } 57 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/protocol/nrpc/RpcClientCompletableFuture.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.protocol.nrpc; 2 | 3 | import org.reactivestreams.Subscriber; 4 | import org.reactivestreams.Subscription; 5 | 6 | import java.util.concurrent.CompletableFuture; 7 | 8 | /** 9 | * support CompletableFuture async response. 10 | * 11 | * @author wangzihao 12 | * 2020/05/30/019 13 | */ 14 | public class RpcClientCompletableFuture extends CompletableFuture { 15 | private Subscription subscription; 16 | 17 | RpcClientCompletableFuture(RpcClientReactivePublisher source) { 18 | source.subscribe(new SubscriberAdapter(this)); 19 | } 20 | 21 | @Override 22 | public boolean cancel(boolean mayInterruptIfRunning) { 23 | if (subscription != null) { 24 | subscription.cancel(); 25 | } 26 | return super.cancel(mayInterruptIfRunning); 27 | } 28 | 29 | public static class SubscriberAdapter implements Subscriber { 30 | private final RpcClientCompletableFuture completableFuture; 31 | private RESULT result; 32 | private Throwable throwable; 33 | 34 | private SubscriberAdapter(RpcClientCompletableFuture completableFuture) { 35 | this.completableFuture = completableFuture; 36 | } 37 | 38 | @Override 39 | public void onSubscribe(Subscription s) { 40 | s.request(1); 41 | completableFuture.subscription = s; 42 | } 43 | 44 | @Override 45 | public void onNext(RESULT o) { 46 | this.result = o; 47 | } 48 | 49 | @Override 50 | public void onError(Throwable t) { 51 | this.throwable = t; 52 | } 53 | 54 | @Override 55 | public void onComplete() { 56 | Throwable throwable = this.throwable; 57 | RESULT result = this.result; 58 | this.throwable = null; 59 | this.result = null; 60 | if (throwable != null) { 61 | completableFuture.completeExceptionally(throwable); 62 | } else { 63 | completableFuture.complete(result); 64 | } 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/protocol/nrpc/RpcClientRxjava3Observable.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.protocol.nrpc; 2 | 3 | import io.reactivex.rxjava3.annotations.NonNull; 4 | import io.reactivex.rxjava3.core.Observable; 5 | import io.reactivex.rxjava3.core.Observer; 6 | import io.reactivex.rxjava3.disposables.Disposable; 7 | import org.reactivestreams.Subscriber; 8 | import org.reactivestreams.Subscription; 9 | 10 | /** 11 | * support rxjava3 Observable async response. 12 | * 13 | * @author wangzihao 14 | * 2020/05/17/019 15 | */ 16 | public class RpcClientRxjava3Observable extends Observable { 17 | private static final Disposable EMPTY_DISPOSABLE = new Disposable() { 18 | @Override 19 | public void dispose() { 20 | // deliberately no-op 21 | } 22 | 23 | @Override 24 | public boolean isDisposed() { 25 | return true; 26 | } 27 | }; 28 | private final RpcClientReactivePublisher source; 29 | 30 | RpcClientRxjava3Observable(RpcClientReactivePublisher source) { 31 | this.source = source; 32 | } 33 | 34 | @Override 35 | protected void subscribeActual(@NonNull Observer observer) { 36 | source.subscribe(new SubscriberAdapter(observer, EMPTY_DISPOSABLE)); 37 | } 38 | 39 | private static class SubscriberAdapter implements Subscriber { 40 | private final Observer observer; 41 | private final Disposable disposable; 42 | 43 | private SubscriberAdapter(Observer observer, Disposable disposable) { 44 | this.observer = observer; 45 | this.disposable = disposable; 46 | } 47 | 48 | @Override 49 | public void onSubscribe(Subscription s) { 50 | s.request(1); 51 | observer.onSubscribe(disposable); 52 | } 53 | 54 | @Override 55 | public void onNext(Object o) { 56 | observer.onNext(o); 57 | } 58 | 59 | @Override 60 | public void onError(Throwable t) { 61 | observer.onError(t); 62 | } 63 | 64 | @Override 65 | public void onComplete() { 66 | observer.onComplete(); 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/protocol/mqtt/security/Authorization.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012-2018 The original author or authors 3 | * ------------------------------------------------------ 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Apache License v2.0 which accompanies this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * 11 | * The Apache License v2.0 is available at 12 | * http://www.opensource.org/licenses/apache2.0.php 13 | * 14 | * You may elect to redistribute this code under either of these licenses. 15 | */ 16 | 17 | package com.github.netty.protocol.mqtt.security; 18 | 19 | import com.github.netty.protocol.mqtt.subscriptions.Topic; 20 | 21 | import static com.github.netty.protocol.mqtt.security.Authorization.Permission.READWRITE; 22 | 23 | /** 24 | * Carries the read/write authorization to topics for the users. 25 | */ 26 | public class Authorization { 27 | 28 | protected final Topic topic; 29 | protected final Permission permission; 30 | 31 | Authorization(Topic topic) { 32 | this(topic, Permission.READWRITE); 33 | } 34 | 35 | Authorization(Topic topic, Permission permission) { 36 | this.topic = topic; 37 | this.permission = permission; 38 | } 39 | 40 | public boolean grant(Permission desiredPermission) { 41 | return permission == desiredPermission || permission == READWRITE; 42 | } 43 | 44 | @Override 45 | public boolean equals(Object o) { 46 | if (this == o) 47 | return true; 48 | if (o == null || getClass() != o.getClass()) 49 | return false; 50 | 51 | Authorization that = (Authorization) o; 52 | 53 | if (permission != that.permission) 54 | return false; 55 | return topic.equals(that.topic); 56 | 57 | } 58 | 59 | @Override 60 | public int hashCode() { 61 | int result = topic.hashCode(); 62 | result = 31 * result + permission.hashCode(); 63 | return result; 64 | } 65 | 66 | /** 67 | * Access rights 68 | */ 69 | enum Permission { 70 | READ, WRITE, READWRITE 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/core/ProtocolHandler.java: -------------------------------------------------------------------------------- 1 | package com.github.netty.core; 2 | 3 | import io.netty.buffer.ByteBuf; 4 | import io.netty.channel.Channel; 5 | 6 | /** 7 | * Protocol Handler 8 | * 9 | * @author wangzihao 10 | * 2018/11/11/011 11 | */ 12 | public interface ProtocolHandler extends Ordered { 13 | 14 | /** 15 | * Get the protocol name 16 | * 17 | * @return name 18 | */ 19 | default String getProtocolName() { 20 | String name = getClass().getSimpleName(); 21 | if (name.isEmpty()) { 22 | name = getClass().getName(); 23 | } 24 | return name; 25 | } 26 | 27 | /** 28 | * Support protocol 29 | * 30 | * @param clientFirstMsg client first message 31 | * @return true=Support, false=no Support 32 | */ 33 | boolean canSupport(ByteBuf clientFirstMsg); 34 | 35 | /** 36 | * Support protocol. if receive clientFirstMsg timeout, then call canSupport(channel) 37 | * 38 | * @param channel channel 39 | * @return true=Support, false=no Support 40 | */ 41 | default boolean canSupport(Channel channel) { 42 | return false; 43 | } 44 | 45 | /** 46 | * on out of max connection count 47 | * 48 | * @param clientFirstMsg clientFirstMsg 49 | * @param tcpChannel tcpChannel 50 | * @param currentConnections currentConnections 51 | * @param maxConnections maxConnections 52 | * @return boolean. false=discard, true=keep handle 53 | */ 54 | default boolean onOutOfMaxConnection(ByteBuf clientFirstMsg, TcpChannel tcpChannel, 55 | int currentConnections, 56 | int maxConnections) { 57 | return false; 58 | } 59 | 60 | /** 61 | * add protocol pipeline support 62 | * 63 | * @param channel TCP channel 64 | * @param clientFirstMsg clientFirstMsg 65 | * @throws Exception Exception 66 | */ 67 | void addPipeline(Channel channel, ByteBuf clientFirstMsg) throws Exception; 68 | 69 | /** 70 | * default Priority order 0 71 | * 72 | * @return The smaller the value of order, the more likely it is to be executed first 73 | */ 74 | @Override 75 | default int getOrder() { 76 | return 0; 77 | } 78 | 79 | } 80 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/protocol/mqtt/config/ClasspathResourceLoader.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012-2018 The original author or authors 3 | * ------------------------------------------------------ 4 | * All rights reserved. This program and the accompanying materials 5 | * are made available under the terms of the Eclipse Public License v1.0 6 | * and Apache License v2.0 which accompanies this distribution. 7 | * 8 | * The Eclipse Public License is available at 9 | * http://www.eclipse.org/legal/epl-v10.html 10 | * 11 | * The Apache License v2.0 is available at 12 | * http://www.opensource.org/licenses/apache2.0.php 13 | * 14 | * You may elect to redistribute this code under either of these licenses. 15 | */ 16 | 17 | package com.github.netty.protocol.mqtt.config; 18 | 19 | import com.github.netty.core.util.LoggerFactoryX; 20 | import com.github.netty.core.util.LoggerX; 21 | 22 | import java.io.InputStream; 23 | import java.io.InputStreamReader; 24 | import java.io.Reader; 25 | import java.nio.charset.Charset; 26 | 27 | public class ClasspathResourceLoader implements IResourceLoader { 28 | 29 | private static final LoggerX LOG = LoggerFactoryX.getLogger(ClasspathResourceLoader.class); 30 | 31 | private final String defaultResource; 32 | private final ClassLoader classLoader; 33 | 34 | public ClasspathResourceLoader() { 35 | this(IConfig.DEFAULT_CONFIG); 36 | } 37 | 38 | public ClasspathResourceLoader(String defaultResource) { 39 | this(defaultResource, Thread.currentThread().getContextClassLoader()); 40 | } 41 | 42 | public ClasspathResourceLoader(String defaultResource, ClassLoader classLoader) { 43 | this.defaultResource = defaultResource; 44 | this.classLoader = classLoader; 45 | } 46 | 47 | @Override 48 | public Reader loadDefaultResource() { 49 | return loadResource(defaultResource); 50 | } 51 | 52 | @Override 53 | public Reader loadResource(String relativePath) { 54 | LOG.info("Loading resource. RelativePath = {}.", relativePath); 55 | InputStream is = this.classLoader.getResourceAsStream(relativePath); 56 | return is != null ? new InputStreamReader(is, Charset.forName("UTF-8")) : null; 57 | } 58 | 59 | @Override 60 | public String getName() { 61 | return "classpath resource"; 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/com/github/netty/protocol/mysql/CapabilityFlags.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 The Netty Project 3 | * 4 | * The Netty Project licenses this file to you under the Apache License, 5 | * version 2.0 (the "License"); you may not use this file except in compliance 6 | * with the License. You may obtain a copy of the License at: 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | 17 | package com.github.netty.protocol.mysql; 18 | 19 | import java.util.EnumSet; 20 | 21 | /** 22 | * An enum of all the MySQL client/server capability flags. 23 | * 24 | * @see 25 | * Capability Flags Reference Documentation 26 | */ 27 | public enum CapabilityFlags { 28 | CLIENT_LONG_PASSWORD, 29 | CLIENT_FOUND_ROWS, 30 | CLIENT_LONG_FLAG, 31 | CLIENT_CONNECT_WITH_DB, 32 | CLIENT_NO_SCHEMA, 33 | CLIENT_COMPRESS, 34 | CLIENT_ODBC, 35 | CLIENT_LOCAL_FILES, 36 | CLIENT_IGNORE_SPACE, 37 | CLIENT_PROTOCOL_41, 38 | CLIENT_INTERACTIVE, 39 | CLIENT_SSL, 40 | CLIENT_IGNORE_SIGPIPE, 41 | CLIENT_TRANSACTIONS, 42 | CLIENT_RESERVED, 43 | CLIENT_SECURE_CONNECTION, 44 | CLIENT_MULTI_STATEMENTS, 45 | CLIENT_MULTI_RESULTS, 46 | CLIENT_PS_MULTI_RESULTS, 47 | CLIENT_PLUGIN_AUTH, 48 | CLIENT_CONNECT_ATTRS, 49 | CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA, 50 | CLIENT_CAN_HANDLE_EXPIRED_PASSWORDS, 51 | CLIENT_SESSION_TRACK, 52 | CLIENT_DEPRECATE_EOF, 53 | UNKNOWN_25, 54 | UNKNOWN_26, 55 | UNKNOWN_27, 56 | UNKNOWN_28, 57 | UNKNOWN_29, 58 | UNKNOWN_30, 59 | UNKNOWN_31; 60 | 61 | public static EnumSet getImplicitCapabilities() { 62 | return EnumSet.of( 63 | CapabilityFlags.CLIENT_LONG_PASSWORD, 64 | CapabilityFlags.CLIENT_PROTOCOL_41, 65 | CapabilityFlags.CLIENT_TRANSACTIONS, 66 | CapabilityFlags.CLIENT_SECURE_CONNECTION 67 | ); 68 | } 69 | 70 | } 71 | --------------------------------------------------------------------------------