SocketService.java 9.94 KB
package com.qnbar.smc.service;

import android.app.Service;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.util.Log;

import com.gimi.common.cinema.model.MessageEvent;
import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;

import org.greenrobot.eventbus.EventBus;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.ref.WeakReference;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Arrays;

public class SocketService extends Service {
    private static final String TAG = "BackService";
    private static final long HEART_BEAT_RATE = 30 * 1000;

    public static final String HOST = "121.43.189.162";// "192.168.1.21";//
    public static final int PORT = 9501;

    public static final String MESSAGE_ACTION = "com.dingmore.terminal.socket";
    public static final String HEART_BEAT_ACTION = "com.dingmore.terminal.socket.heart";

    public static final String HEART_BEAT_STRING = "00";//心跳包内容

    private ReadThread mReadThread;
    private Gson gson;

//    private LocalBroadcastManager mLocalBroadcastManager;

    private WeakReference<Socket> mSocket;

    // For heart Beat
    private Handler mHandler = new Handler();
    private Runnable heartBeatRunnable = new Runnable() {

        @Override
        public void run() {
            if (System.currentTimeMillis() - sendTime >= HEART_BEAT_RATE) {
                Log.d(TAG, "heart beat");
                boolean isSuccess = sendMsg(HEART_BEAT_STRING);//就发送一个HEART_BEAT_STRING过去 如果发送失败,就重新初始化一个socket
                if (!isSuccess) {
                    Log.d(TAG, "heart beat error restart");
                    mHandler.removeCallbacks(heartBeatRunnable);
                    mReadThread.release();
                    releaseLastSocket(mSocket);
                    new InitSocketThread().start();
                }
            } else {
                Log.d(TAG, "heart beat less than beat rate");
            }
            mHandler.postDelayed(this, HEART_BEAT_RATE);
        }
    };

    private long sendTime = 0L;

    @Override
    public IBinder onBind(Intent arg0) {
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        gson = new Gson();
        new InitSocketThread().start();
        Log.d(TAG, "socket service onCreate");
//        mLocalBroadcastManager = LocalBroadcastManager.getInstance(this);

    }

    public boolean sendMsg(String msg) {
        if (null == mSocket || null == mSocket.get()) {
            return false;
        }
        Log.d(TAG, msg);
        Socket soc = mSocket.get();
        try {
            if (!soc.isClosed() && !soc.isOutputShutdown()) {
                OutputStream os = soc.getOutputStream();
                String message = msg;
                os.write(message.getBytes());
                os.flush();
                sendTime = System.currentTimeMillis();//每次发送成数据,就改一下最后成功发送的时间,节省心跳间隔时间
            } else {
                return false;
            }
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    private void initSocket() {//初始化Socket
        try {
            Socket so = new Socket(HOST, PORT);
            mSocket = new WeakReference<Socket>(so);
            mReadThread = new ReadThread(so);
            mReadThread.start();
//            new Thread(heartBeatRunnable).start();
//            mHandler.post(heartBeatRunnable);//初始化成功后,就准备发送心跳包
            new HeatBeat(so).start();//上面的 one plus 3t NetworkOnMainThreadException!!!
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void releaseLastSocket(WeakReference<Socket> mSocket) {
        try {
            if (null != mSocket) {
                Socket sk = mSocket.get();
                if (!sk.isClosed()) {
                    sk.close();
                }
                sk = null;
                mSocket = null;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    class InitSocketThread extends Thread {
        @Override
        public void run() {
            super.run();
            initSocket();
        }
    }

    // Thread to read content from Socket
    class ReadThread extends Thread {
        private WeakReference<Socket> mWeakSocket;
        private boolean isStart = true;

        public ReadThread(Socket socket) {
            mWeakSocket = new WeakReference<Socket>(socket);
        }

        public void release() {
            isStart = false;
            releaseLastSocket(mWeakSocket);
        }

        @Override
        public void run() {
            super.run();
            Socket socket = mWeakSocket.get();
            if (null != socket) {
                try {
                    if (!sendRegister) {
                        Log.d(TAG, "send register mes");
                        String msg = "{\"cmd\":\"register\",\"data\":{\"room_sn\":\"000002\"}}\\r\\n\\r\\n";
                        sendMsg(msg);
                        Log.d(TAG, "" + msg);
                        sendRegister = true;
                    }
                    Log.d(TAG, "send register mes end");
                    InputStream is = socket.getInputStream();
                    byte[] buffer = new byte[1024 * 4];
                    int length = 0;
                    while (!socket.isClosed() && !socket.isInputShutdown()
                            && isStart && ((length = is.read(buffer)) != -1)) {
                        if (length > 0) {
                            String message = new String(Arrays.copyOf(buffer,
                                    length)).trim();
                            Log.d(TAG, message);
                            try {
                                SocketResponse socketResponse = gson.fromJson(message.trim(), SocketResponse.class);
                                switch (socketResponse.getCode()) {
                                    case 1001:
                                        sendMsg("{\"cmd\":\"reconnect\",\"data\":{\"room_sn\":\"000002\"}}\\r\\n\\r\\n");
                                        Log.d(TAG, "send reconnect mes");
                                        break;
                                    case 1002:
                                        Log.d(TAG, "re init socket");
                                        //                                    sendRegister = false;
                                        releaseLastSocket(mWeakSocket);
                                        initSocket();
                                        break;
                                }
                                if (("openDoor").equals(socketResponse.getCmd())) {
                                    MessageEvent messageEvent = new MessageEvent();
                                    messageEvent.setEventId(1701);
                                    messageEvent.setMessage("click item");
                                    EventBus.getDefault().post(messageEvent);
                                }
                            } catch (JsonSyntaxException e) {
                                Log.d(TAG, message);
                                e.printStackTrace();
                            }
                            //收到服务器过来的消息,就通过Broadcast发送出去
//                            if (message.equals(HEART_BEAT_STRING)) {//处理心跳回复
//                                Intent intent = new Intent(HEART_BEAT_ACTION);
//                                mLocalBroadcastManager.sendBroadcast(intent);
//                            } else {
//                                //其他消息回复
//                                Intent intent = new Intent(MESSAGE_ACTION);
//                                intent.putExtra("message", message);
//                                mLocalBroadcastManager.sendBroadcast(intent);
//                            }
                        }
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    boolean sendRegister = false;


    // Thread to read content from Socket
    class HeatBeat extends Thread {
        private WeakReference<Socket> mWeakSocket;
        private boolean isStart = true;

        public HeatBeat(Socket socket) {
            mWeakSocket = new WeakReference<Socket>(socket);
        }

        @Override
        public void run() {
            super.run();
            Socket socket = mWeakSocket.get();
            if (null != socket) {
                while (true) {
                    if (System.currentTimeMillis() - sendTime >= HEART_BEAT_RATE) {
                        Log.d(TAG, "heart beat");
                        boolean isSuccess = sendMsg(HEART_BEAT_STRING);//就发送一个HEART_BEAT_STRING过去 如果发送失败,就重新初始化一个socket
                        if (!isSuccess) {
                            Log.d(TAG, "heart beat error restart");
//                            mHandler.removeCallbacks(heartBeatRunnable);
                            mReadThread.release();
                            releaseLastSocket(mSocket);
                            new InitSocketThread().start();
                        }
                    } else {
                        Log.d(TAG, "heart beat less than beat rate");
                    }
                    try {
                        Thread.sleep(HEART_BEAT_RATE);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "socket service destroy");
    }
}