客户端 UDP 调用netty 参考



import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Enumeration;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.atomic.AtomicInteger;

import org.jboss.netty.bootstrap.ConnectionlessBootstrap;
import org.jboss.netty.channel.AdaptiveReceiveBufferSizePredictor;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelFuture;
import org.jboss.netty.channel.ChannelFutureListener;
import org.jboss.netty.channel.FixedReceiveBufferSizePredictorFactory;
import org.jboss.netty.channel.socket.DatagramChannel;
import org.jboss.netty.channel.socket.DatagramChannelFactory;
import org.jboss.netty.channel.socket.oio.OioDatagramChannelFactory;
import org.jboss.netty.util.AlarmManagerTimer;
import org.jboss.netty.util.AlarmManagerTimerFactory;

import com.lenovo.lsf.push.log.PushLog;
import com.lenovo.lsf.push.log.PushLog.LEVEL;
import com.lenovo.lsf.push.net.handler.PushUDPHandler;
import com.lenovo.lsf.push.net.pipeline.PushUDPPipelineFactory;
import com.lenovo.lsf.push.net.protobuf.PushUDPCommandProtos.COMMAND_TYPE;
import com.lenovo.lsf.push.net.protobuf.PushUDPCommandProtos.PUSH_UDP_COMMAND;
import com.lenovo.lsf.push.net.protobuf.PushUDPCommandProtos.PUSH_UDP_COMMAND.TTL_INIT;
import com.lenovo.lsf.push.net.protobuf.PushUDPCommandProtos.PUSH_UDP_COMMAND.TTL_INIT.Builder;
import com.lenovo.lsf.push.util.DeviceUtil;
import com.lenovo.lsf.push.util.PushWakeLock;
import com.lenovo.lsf.sdac.SDACDeviceInfo;

import android.content.Context;
import android.content.Intent;
import android.util.Log;

public class PushMessageUDPImpl extends PushDAONetAware implements IPushMessage {

    private Context context;
    private static ConnectionlessBootstrap bootstrap;
    private  ChannelFuture channelFuture;
    private static DatagramChannel databramChannel;
    private String lastNetType="";
    private String lastIPAddress="";
    private String HOST;
    private int PORT;
    private String requestURI;
    public static final String PUSH_UDP_WAKE_LOCK = "PUSH_UDP_WAKE_LOCK";
    public static final int INIT_UDP_FAIL_COUNT = 0;
    private int udpFailCount = INIT_UDP_FAIL_COUNT;

    public static final int MAX_UDP_INIT_COUNT = 5;
    public static String last_local_ip = null;
    public static int ttl = 25;
    private PushMessageUDPDelayRetryProxy delayProxy;
    private PushUDPIntervalTunningManager tunningManager;
    private AlarmManagerTimerFactory timerFactory;
    //用来生成唯一的PushUDPCommand id
    private static AtomicInteger requstCode = new AtomicInteger(0);
    //id max
    private final int MAX_TIMER = 256;
    private boolean isTTLInitRunning = false;
    private boolean udpInitialized = false;
    

    public PushMessageUDPImpl(Context context) {
        super(context);
        // TODO Auto-generated constructor stub
        this.context = context;
        delayProxy = new PushMessageUDPDelayRetryProxy();
        tunningManager = new PushUDPIntervalTunningManager();
        timerFactory = new AlarmManagerTimerFactory(PushService.ACTION_INTERNAL_UDP_ALARM_TIMER);

    }
    
    public int getUdpFailCount() {
        return udpFailCount;
    }

    public void setUdpFailCount(int udpFailCount) {
        this.udpFailCount = udpFailCount;
    }


    @Override
    public void resetDayPollCount() {
        // TODO Auto-generated method stub

    }

    @Override
    public void resetFailCount() {
        // TODO Auto-generated method stub
        udpFailCount = INIT_UDP_FAIL_COUNT;
    }
    


    @Override
    public void online() {
        // TODO Auto-generated method stub
        start();
    }

    @Override
    public void offline() {
        // TODO Auto-generated method stub
        stop();
    }

    public boolean isTTLInitRunning() {
        return isTTLInitRunning;
    }

    public void setTTLInitRunning(boolean isTTLInitRunning) {
        this.isTTLInitRunning = isTTLInitRunning;
    }
    
    @Override
    public void start() {
        // TODO Auto-generated method stub
        if(isSwitchOn() && isNetAvailable() && !isEmpty()){

            String currentNetType = getNetType();
            String currentIPAddress = getIpAddress();
                
            PushLog.log(context, LEVEL.INFO, "PushMessageUDPImpl.start", "lastNetType:"+lastNetType+", currentNetType:"+currentNetType);    
            PushLog.log(context, LEVEL.INFO, "PushMessageUDPImpl.start", "lastIPAddress:"+lastIPAddress+", currentIPAddress:"+currentIPAddress);    
            
            lastNetType = currentNetType;
            lastIPAddress = currentIPAddress;
            
            requestURI = getPushUDPRequestUrl();
            
            if(requestURI != null && requestURI.indexOf(":") != -1) {
                HOST = requestURI.substring(0, requestURI.indexOf(":"));
                String portStr = requestURI.substring(requestURI.indexOf(":") + 1, requestURI.length());
                try{
                    PORT = Integer.parseInt(portStr);
                } catch (NumberFormatException e) {
                    e.printStackTrace();
                }
                PushLog.log(context, PushLog.LEVEL.INFO, "PushMessageUDPImpl.start",
                        "HOST:" + HOST+"PORT:"+PORT);
            }
            



            /*
            if (currentIPAddress != null
                    && !currentIPAddress.equals(lastIPAddress)) {

                initTTL();

            }
            */
            if(!isTTLInitRunning()) {
                initTTL();
            }
                
        }else{
            Intent i = PushService.newIntent(context,PushService.ACTION_INTERNAL_UDP_STOP_ALL);
            //context.sendBroadcast(i);
            i = PushIntentAware.awareIntent(context, i);
            context.startService(i);
        }
    }
    
    void initTTL() {
        setTTLInitRunning(true);
        

        setUdpInitialized(false);
        
        PushWakeLock.acquire(context, PUSH_UDP_WAKE_LOCK, 30);
        DatagramChannelFactory f = new OioDatagramChannelFactory(
                Executors.newCachedThreadPool());
        bootstrap = new ConnectionlessBootstrap(f);

        // Configure the pipeline factory.
        bootstrap.setPipelineFactory(new PushUDPPipelineFactory(
                context,timerFactory.getNewAlarmManagerTimer(context), this));

        // Enable broadcast
        bootstrap.setOption("broadcast", "false");
        bootstrap.setOption("receiveBufferSizePredictorFactory",
                new FixedReceiveBufferSizePredictorFactory(102400));

        databramChannel = (DatagramChannel) bootstrap
                .bind(new InetSocketAddress(0));
        
        write();
    }
    
    void write() {       
        // write TTL_INIT to server
        PUSH_UDP_COMMAND command = getInitTTLCommand(getUDPPushCommandId());
        PushLog.log(context, PushLog.LEVEL.INFO,
                "PushMessageUDPImpl.write", "send ttl init to server>>>>>>>>>>>>ttlInit:"+command.getTtlInit().getTtl());
        channelFuture = databramChannel.write(command,
                new InetSocketAddress(HOST,PORT));
        
        
        channelFuture.addListener(new ChannelFutureListener(){

            @Override
            public void operationComplete(ChannelFuture future)
                    throws Exception {
                // TODO Auto-generated method stub
                if (!future.isSuccess()) {
                    timerFactory.destroyAlarmManagerTimer(context);
                    setTTLInitRunning(false);
                    if(future != null){
                        Channel channel = future.getChannel();
                        if(channel != null){
                            channel.close();
                            // Wait for the server to close the connection.
                            channel.getCloseFuture().awaitUninterruptibly();
                        }
                    }

                    PushLog.log(context, LEVEL.INFO, "PushMessageUDPImpl.sendTTLInitRequest", "connect fail begin to release wake lock!!!");
                    PushWakeLock.release(context,PUSH_UDP_WAKE_LOCK);
               
                }
            }
            
        });
}
    
    public PUSH_UDP_COMMAND getInitTTLCommand(int id){
        // build TTL_INIT command
        Builder builder = TTL_INIT.newBuilder();
        String st = getSt();
        builder.setSt(st==null ? "":st);
        builder.setTtl(ttl);
        try{
            String netType = DeviceUtil.getNetType(context);
            if(netType != null && !netType.equals("")) {
                if(netType.equals("wifi"))
                    builder.setNetType(DeviceUtil.WIFI);
                else if(netType.equals("mobile"))
                    builder.setNetType(DeviceUtil.MOBILE);
            }
        } catch (Exception e){
            e.printStackTrace();
        }
        try{
            String optCode = SDACDeviceInfo.getInstance().getSdacInfo(context)
                    .getSystemID();
            if(optCode != null && !optCode.equals("")) {
                int code = Integer.parseInt(optCode);
                builder.setOptCode(code);
            }
        } catch (Exception e){
            e.printStackTrace();
        }
        try{
            String cellId = DeviceUtil.getCellId(context);
            if(cellId != null && !cellId.equals("")) {
                int cId = Integer.parseInt(cellId);
                builder.setNetType(cId);
            }
            
        } catch (Exception e){
            e.printStackTrace();
        }
        
        TTL_INIT ttlInit = builder.build();
        PUSH_UDP_COMMAND command = PUSH_UDP_COMMAND.newBuilder().setId(id)
                .setType(COMMAND_TYPE.TTL_INIT).setVer(PushUDPHandler.COMMAND_VERSION).setTtlInit(ttlInit).build();
        return command;
    }
    
    @Override
    public void stop() {
        // TODO Auto-generated method stub
        if(isTTLInitRunning()) {
            delayProxy.cancelUDPPushRetryAlarm(context);
            
            setTTLInitRunning(false);
            resetFailCount();
            PushLog.log(context, PushLog.LEVEL.INFO, "PushMessageUDPImpl.stop",
                    "PushMessageUDPImpl.stop");
            timerFactory.destroyAlarmManagerTimer(context);
            if(channelFuture != null){
                Channel channel = channelFuture.getChannel();
                if(channel != null){
                    PushLog.log(context, LEVEL.INFO, "PushMessageUDPImpl.stop", "channel has been closed by future !!!");
                    channel.close();
                    // Wait for the server to close the connection.
                    channel.getCloseFuture().awaitUninterruptibly();
                }
            }
            
        }
    }

    @Override
    public void udpAvaliable() {
        // TODO Auto-generated method stub

    }

    @Override
    public void udpUnAvaliable() {
        // TODO Auto-generated method stub

    }

    @Override
    public void expire(int requestCode) {
        // TODO Auto-generated method stub
        AlarmManagerTimer timer  = timerFactory.getAlarmManagerTimer(context);
        
        // TODO Auto-generated method stub
        if(timer != null){
          timer.expire(requestCode);
        }else{
            
            PushLog.log(context, LEVEL.INFO, "PushMessageUDPImpl.expire()", "push service instance has been recreated, restart initTTL !!!");

            setTTLInitRunning(false);
            if(channelFuture != null){
            Channel channel = channelFuture.getChannel();
            if(channel != null){
            channel.close();
            // Wait for the server to close the connection.
            channel.getCloseFuture().awaitUninterruptibly();
            }
            }


            
            Intent i = PushService.newIntent(context,PushService.ACTION_INTERNAL_UDP_START_ALL);
            //context.sendBroadcast(i);
            i = PushIntentAware.awareIntent(context, i);
            context.startService(i);
        }
    }

    @Override
    public void switchOn() {
        // TODO Auto-generated method stub
        setSwitch(context, true);
    }

    @Override
    public void switchOff() {
        // TODO Auto-generated method stub
        setSwitch(context, false);
    }
    
    public AlarmManagerTimerFactory getTimerFactory() {
        return timerFactory;
    }

    public void setTimerFactory(AlarmManagerTimerFactory timerFactory) {
        this.timerFactory = timerFactory;
    }

    public PushMessageUDPDelayRetryProxy getDelayProxy() {
        return delayProxy;
    }

    public void setDelayProxy(PushMessageUDPDelayRetryProxy delayProxy) {
        this.delayProxy = delayProxy;
    }
    
    public PushUDPIntervalTunningManager getTunningManager() {
        return tunningManager;
    }

    public void setTunningManager(PushUDPIntervalTunningManager tunningManager) {
        this.tunningManager = tunningManager;
    }
    
    public boolean isUdpInitialized() {
        return udpInitialized;
    }

    public void setUdpInitialized(boolean udpInitialized) {
        this.udpInitialized = udpInitialized;
    }

    
    private String getPushUDPRequestUrl() {

        ExecutorService executor = Executors.newSingleThreadExecutor();
        Future<String> future = (Future<String>) executor
                .submit(new Callable<String>() {

                    @Override
                    public String call() throws Exception {
                        String addr = getServerAddr("rpsb002");
                        if(addr == null) {
                            PushLog.log(context, LEVEL.INFO, "PushMessageUDPImpl.getPushUDPRequestUrl", "get server address failed");
                        }else{
                            PushLog.log(context, LEVEL.INFO, "PushMessageUDPImpl.getPushUDPRequestUrl", "url:"+addr);
                        }
                        
                        StringBuilder sb = new StringBuilder(addr==null ? "":addr);

                        PushLog.log(context, LEVEL.INFO, "PushMessageUDPImpl.getPushUDPRequestUrl", "command line is:" + sb.toString());
                        
                        return sb.toString();
                    }

                });

        try {
            String pushURI = future.get();
            return pushURI;
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        return null;
    }

    
    //生成全局唯一UDPPushCommand id
    public int getUDPPushCommandId() {
        int code = requstCode.getAndIncrement();
        if (code > MAX_TIMER) {
            code = 0;
            requstCode = new AtomicInteger(0);
        }
        return code;
    }

    @Override
    public void resetUdpAvaliable() {
        // TODO Auto-generated method stub
        
    }


}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

FocusOneThread

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值