
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