NETTY如何实现短连接

lushan 发布于 2010/11/16 09:11
阅读 10K+
收藏 4

现在用NETTY3写一个和联通SGIP协议短信网关通信的程序,现在用的长连接,服务器总是一段时间后断开连接,请问怎么保持连接

加载中
0
JavaGG
JavaGG

用心跳!

0
yuyoo4j
yuyoo4j

对, 用心跳消息. 

一般协议都支持心跳消息. 你定时发送一个心跳消息.

或者 如果它有查询消息, 你定时发送一个查询消息.

以前, 我用mina, 实现其他的协议没有心跳消息, 就定时发送查询协议版本号的消息, 这样保证连接长时间有效.

0
l
lushan

但是SGIP协议规范里好像没 心跳支持呀,如果用心跳 具体代码里怎么实现,谢谢指点

0
欧德高
欧德高

sgip是互为服务端,有消息要发时才建立连接,一个连接上可以发多条消息,没消息发就发送断开连接包

cmpp,smgp,cngp,smpp是运营商为服务端,sp/cp为客户端,接收消息的连接需要保持连接,各30秒发一个心跳包,发消息的连接则有消息要发时建立连接,如果是一个连接上同事收发小学则要保持链接,如果断开必须重连否则收不到mo消息

over

0
周虎
周虎

啥也不说,直接上代码。

类:ServerNIOHandler 别看名字是server它其实是客户端的handler,这个我是用来做反向连接的。所有handler的超类

import java.net.ConnectException;
import java.util.concurrent.TimeUnit;

import org.jboss.netty.bootstrap.ClientBootstrap;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.ChannelStateEvent;
import org.jboss.netty.channel.ExceptionEvent;
import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
import org.jboss.netty.channel.ChannelHandler.Sharable;
import org.jboss.netty.util.Timeout;
import org.jboss.netty.util.Timer;
import org.jboss.netty.util.TimerTask;

import com.zrat.server.nio.factory.ServerPipelineFactory;
@Sharable
public abstract class ServerNIOHandler extends SimpleChannelUpstreamHandler{
    final ClientBootstrap bootstrap;
    private final Timer timer;
    private long startTime = -1;

    public ServerNIOHandler(ClientBootstrap bootstrap, Timer timer) {
        this.bootstrap = bootstrap;
        this.timer = timer;
    }
   
    @Override
    public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e) {
        timer.newTimeout(new TimerTask() {
            public void run(Timeout timeout) throws Exception {
                bootstrap.connect();
            }
        }, ServerPipelineFactory.RECONNECT_DELAY, TimeUnit.SECONDS);
    }

    @Override
    public void channelConnected(ChannelHandlerContext ctx, ChannelStateEvent e) {
        if (startTime < 0) {
            startTime = System.currentTimeMillis();
        }
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) {
        Throwable cause = e.getCause();
        if (cause instanceof ConnectException) {
            startTime = -1;
            ctx.getChannel().close();
        }
        e.getCause().printStackTrace();
       
    }

}

类:ServerPipelineFactory 管道工厂类

import static org.jboss.netty.channel.Channels.pipeline;
import org.jboss.netty.bootstrap.ClientBootstrap;
import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.channel.ChannelPipelineFactory;
import org.jboss.netty.handler.codec.serialization.ObjectDecoder;
import org.jboss.netty.handler.codec.serialization.ObjectEncoder;
import org.jboss.netty.util.Timer;

import com.zrat.server.nio.handler.CommandHandler;
import com.zrat.server.nio.handler.FileHandler;

public class ServerPipelineFactory implements ChannelPipelineFactory {

    private Timer timer;
    private ClientBootstrap bootstrap;
   
    public static final int RECONNECT_DELAY = 5;
   
    public ServerPipelineFactory(ClientBootstrap bootstrap,Timer timer){
        super();
        this.timer = timer;
        this.bootstrap = bootstrap;
    }
   
    public ChannelPipeline getPipeline() throws Exception {
        ChannelPipeline pipeline = pipeline();

        pipeline.addLast("decoder", new ObjectDecoder());
        pipeline.addLast("encoder", new ObjectEncoder());

        pipeline.addLast("fileHandler", new FileHandler(bootstrap,timer));
        pipeline.addLast("commandHandler", new CommandHandler(bootstrap,timer));
        return pipeline;
    }
}

调用方法:

public void start(){
        final Timer timer = new HashedWheelTimer();
        final ClientBootstrap bootstrap = new ClientBootstrap(
                new NioClientSocketChannelFactory(
                        Executors.newCachedThreadPool(),
                        Executors.newCachedThreadPool()));
        bootstrap.setPipelineFactory(new ServerPipelineFactory(bootstrap,timer));

        bootstrap.setOption(
                "remoteAddress", new InetSocketAddress(host, port));
        bootstrap.connect();
    }

JoeyBlue
JoeyBlue
哥们 你这个是实现长连接的吧?
0
l
lushan

谢谢楼上的 你的代码对我帮助很大

0
周虎
周虎

不客气,必须的

0
鱿鱼
鱿鱼
SGIP 没有长连接的. 短链接 还得    Executors.newCachedThreadPool(), 不如直接 socket
leaphong
leaphong
直接用socket,自己控制比较麻烦
0
鱿鱼
鱿鱼
联通不支持长连接的.
返回顶部
顶部