package org.rpc4j.server; import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelOption; import io.netty.channel.EventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.nio.NioServerSocketChannel; import java.util.HashMap; import java.util.Map; import org.apache.commons.collections4.MapUtils; import org.rpc4j.common.RpcDecoder; import org.rpc4j.common.RpcEncoder; import org.rpc4j.common.RpcRequest; import org.rpc4j.common.RpcResponse; import org.rpc4j.common.registry.ServiceRegistry; import org.rpc4j.server.annotation.RPCService; import org.rpc4j.server.handler.RpcHandler; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.BeansException; import org.springframework.beans.factory.InitializingBean; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; /** * RPC服务器-(用于发布 RPC服务) * * @author huangyong * @since 1.0.0 */ public class RPCServer implements ApplicationContextAware, InitializingBean { private static final Logger Logger = LoggerFactory.getLogger(RPCServer.class); private String serverAddress; private ServiceRegistry serviceRegistry; private Map<String, Object> handlerMap = new HashMap<String, Object>(); public RPCServer(String serverAddress) { this.serverAddress = serverAddress; } /** * @param serverAddress * @param serviceRegistry */ public RPCServer(String serverAddress, ServiceRegistry serviceRegistry) { this.serverAddress = serverAddress; this.serviceRegistry = serviceRegistry; } @Override public void setApplicationContext(ApplicationContext ctx) throws BeansException { Map<String, Object> serviceBeanMap = ctx.getBeansWithAnnotation(RPCService.class); if (MapUtils.isNotEmpty(serviceBeanMap)) { for (Object serviceBean : serviceBeanMap.values()) { String interfaceName = serviceBean.getClass().getAnnotation(RPCService.class).value().getName(); handlerMap.put(interfaceName, serviceBean); } } } @Override public void afterPropertiesSet() throws Exception { EventLoopGroup bossGroup = new NioEventLoopGroup(); EventLoopGroup workerGroup = new NioEventLoopGroup(); try { ServerBootstrap bootstrap = new ServerBootstrap(); bootstrap.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class) .childHandler(new ChannelInitializer<SocketChannel>() { @Override public void initChannel(SocketChannel channel) throws Exception { channel.pipeline() .addLast(new RpcDecoder(RpcRequest.class)) .addLast(new RpcEncoder(RpcResponse.class)) .addLast(new RpcHandler(handlerMap)); } }) .option(ChannelOption.SO_BACKLOG, 128) .childOption(ChannelOption.SO_KEEPALIVE, true); String[] array = serverAddress.split(":"); String host = array[0]; int port = Integer.parseInt(array[1]); ChannelFuture future = bootstrap.bind(host, port).sync(); Logger.debug("server started on port {}", port); if (serviceRegistry != null) { serviceRegistry.register(serverAddress); } future.channel().closeFuture().sync(); } finally { workerGroup.shutdownGracefully(); bossGroup.shutdownGracefully(); } } }