All Downloads are FREE. Search and download functionalities are using the official Maven repository.

jizcode.netty.server.RtServer Maven / Gradle / Ivy

package jizcode.netty.server;

import java.nio.charset.Charset;
import java.util.List;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.ServerSocketChannel;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.LineBasedFrameDecoder;
import io.netty.handler.codec.string.StringDecoder;
import jizcode.netty.contract.BufferSize;
import jizcode.netty.contract.RtDataFromServer;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class RtServer{
	protected Log logger = LogFactory.getLog(this.getClass());
	private static RtServer rtServer;

	public static RtServer getInstance(){
		if(rtServer == null){
			rtServer = new RtServer();
		}
		return rtServer;
	}

	private ServerSocketChannel serverSocketChannel;
	private int port;
	private ClientCollection clientCollection;

	EventLoopGroup boss;
	EventLoopGroup worker;
	ServerBootstrap bootstrap;
	ChannelFuture future;

	public RtServer(){
		clientCollection = new ClientCollection();
	}

	/**
	 * 服务是否已经启动
	 * @return
	 */
	public boolean isStarted(){
		if(serverSocketChannel != null && serverSocketChannel.isOpen() && serverSocketChannel.isActive()){
			return true;
		}
		return false;
	}

	ReceiveRequestFunction onReceive;
	public void start(int port, ReceiveRequestFunction onReceive){
		if(!this.isStarted()){
			this.port = port;
			this.onReceive = onReceive;
			bind(this.port);
		}
	}

	private void bind(final int port) {
		Thread thread = new Thread(new Runnable() {
			@Override
			public void run() {
				//服务端要建立两个group,一个负责接收客户端的连接,一个负责处理数据传输
				//连接处理group
				boss = new NioEventLoopGroup();
				//事件处理group
				worker = new NioEventLoopGroup();
				bootstrap = new ServerBootstrap();
				// 绑定处理group
				bootstrap.group(boss, worker).channel(NioServerSocketChannel.class)
						//保持连接数
						.option(ChannelOption.SO_BACKLOG, 5000)
						//有数据立即发送
						.childOption(ChannelOption.TCP_NODELAY, true)
						//保持连接
						.childOption(ChannelOption.SO_KEEPALIVE, true)
						//处理新连接
						.childHandler(new ChannelInitializer() {
							@Override
							protected void initChannel(SocketChannel sc) throws Exception {
								// 增加任务处理
								ChannelPipeline p = sc.pipeline();
								//使用了netty自带的编码器和解码器
								p.addLast(new LineBasedFrameDecoder(BufferSize.Default),
										new StringDecoder(Charset.forName("utf-8")),
										new RtServerHandler());
							}
						});

				//绑定端口,同步等待成功
				try {
					future = bootstrap.bind(port).sync();
					if (future.isSuccess()) {
						serverSocketChannel = (ServerSocketChannel) future.channel();
						//logger.info("服务端开启成功");
					} else {
						//logger.info("服务端开启失败");
					}

					//等待服务监听端口关闭,就是由于这里会将线程阻塞,导致无法发送信息,所以我这里开了线程
					future.channel().closeFuture().sync();
					//logger.info("服务端关闭");
				} catch (Exception e) {
					e.printStackTrace();
				}
				finally {
					//优雅地退出,释放线程池资源
					boss.shutdownGracefully();
					worker.shutdownGracefully();
					//logger.info("服务端优雅地退出,释放线程池资源");
				}
			}
		});
		thread.start();
	}

	public void stop(){
		List clients = clientCollection.getClients();
		for (Client client : clients) {
			client.getChannel().close();
		}
		serverSocketChannel.close();
		future.cancel(true);
	}

	public List listClients(){
		return clientCollection.getClients();
	}

	public Client findClient(String id){
		return clientCollection.getClient(id);
	}

	/**
	 * 添加客户端channel,如果不存在直接添加,已存在,就更新
	 * @param id
	 * @param channel
	 */
	public synchronized void addClient(String id, Channel channel){
		clientCollection.saveClient(id, channel);
	}

	public ClientRequest request(String id, RtDataFromServer data){
		Client client = this.findClient(id);
		if(client==null){
			//logger.info("can not found client id:"+id);
			return ClientRequest.NotFound(data);
		}else{
			return client.request(data);
		}
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy