1. 程式人生 > >網路通訊Socket+Protobuf協議

網路通訊Socket+Protobuf協議

不多說了,直接貼程式碼

大家好,如果做即時通訊,相信大家對socket也有一定的瞭解,下面主要是對socket長連線,資料封包解包,外加protobuf的例子,希望能對各位有所幫助

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketException;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.locks.ReentrantLock;


import android.content.Context;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.util.Log;


/**
 * socket管理類
 * @author ZengJ
 *
 */
public class IPPushManager{
public static final String tag = IPPushManager.class.getSimpleName();
private String mHostname;
private int mPort;


private PushListener mPushListener;
public static IPPushManager pushManager;


/**
* 寫到伺服器的處理器
*/
private ReadThread mReadThread;
private HandlerThread mWriteThread;
private HandlerThread mProtocaolThread;
private WriteHandler mWriteHandler;


public static long readWriteBytesCount = 0;


/**
* Socket通道
*/
private Socket mSocket;
private InputStream mInputStream;
private OutputStream mOutputStream;


private ReentrantLock mSockConnectionReentrantLock = new ReentrantLock();


private Context mContext;
private Set<ISocketClient> mListener = new CopyOnWriteArraySet<ISocketClient>();
// 儲存每次上傳器的物件
private HashMap<Long, UploadFile> mMapUploadFile = new HashMap<Long, UploadFile>();
// 儲存每次下載器的物件
private HashMap<Integer, DownloadFile> mMapDownLoadFile = new HashMap<Integer, DownloadFile>();


private IPPushManager(String hostName, int port) {
mHostname = hostName;
mPort = port;
}


public static void init(String hostName, int port) {
if (pushManager == null) {
pushManager = new IPPushManager(hostName, port);
}
}


public static IPPushManager getInstance() {
if (pushManager == null) {
throw new RuntimeException("before call init()");
}
return pushManager;
}


public void addListener(ISocketClient listener) {
if (listener != null) {
mListener.add(listener);
}


}


public void removeListener(ISocketClient listener) {
if (listener != null) {
mListener.remove(listener);
}
}


/**
* 傳送訊息
* 
* @Title: send
* @Description: TODO
* @return: void
*/
public void send(byte[] request) {
if (mWriteHandler != null) {
mWriteHandler.sendMessage(mWriteHandler.obtainMessage(0, request));
}
}


public void setPushListener(PushListener pushListener) {
mPushListener = pushListener;
}


/**
* 建立連線
* 
* @Title: connect
* @Description: TODO
* @return: void
*/
public void connect(final OnConnectListener listener) {
new Thread() {
public void run() {
mSockConnectionReentrantLock.lock();
try {
if (isConnected()) {
return;
}


// dissConnect();


InetSocketAddress addr = new InetSocketAddress(mHostname,
mPort);
mSocket = new Socket();
mSocket.connect(addr, 10 * 1000);
if (mSocket.isConnected()) {
mSocket.setKeepAlive(true); // 長連線
mSocket.setTcpNoDelay(true);// 資料不作緩衝,立即傳送
mSocket.setSoLinger(true, 0);// socket關閉時,立即釋放資源
mInputStream = mSocket.getInputStream();
mOutputStream = mSocket.getOutputStream();
// 初始化協議處理器
mProtocaolThread = new HandlerThread(
"IPPush ProtocaolController");
mProtocaolThread.start();


mReadThread = new ReadThread();
mReadThread.setName("IPPush ReadHandlerThread");
mReadThread.start();


mWriteThread = new HandlerThread(
"IPPush WriteHandlerThread");
mWriteThread.start();
mWriteHandler = new WriteHandler(
mWriteThread.getLooper());


if (listener != null) {
listener.onConnectSuccess(IPPushManager.this);
}
} else {
// 連線失敗
if (listener != null) {
listener.onConnectFail(new SocketException("連線失敗"));
}
}
} catch (Exception e) {
// 連線失敗
if (listener != null) {
listener.onConnectFail(e);
}
dissConnect();


} finally {
mSockConnectionReentrantLock.unlock();
}
};
}.start();
}


/**
* 通道是否開啟
* 
* @Title: isOpen
* @Description: TODO
* @return
* @return: boolean
*/
public boolean isConnected() {
try {
return mSocket != null && mSocket.isConnected()
&& !mSocket.isInputShutdown()
&& !mSocket.isOutputShutdown();
} catch (Exception e) {
return false;
}
}


public void onPush() {
if (mPushListener != null) {
mPushListener.onPush();
}
}


/**
* 斷開連線
* 
* @Title: dissConnect
* @Description: TODO
* @return: void
*/
public void dissConnect() {
try {
if (mInputStream != null) {
mInputStream.close();
mInputStream = null;
}


if (mOutputStream != null) {
mOutputStream.close();
mOutputStream = null;
}


if (mSocket != null) {
mSocket.close();
mSocket = null;
}


if (mWriteHandler != null) {
mWriteHandler.sendEmptyMessage(-1);
mWriteHandler = null;
}


readWriteBytesCount = 0;
} catch (Exception e) {
}
}


private class WriteHandler extends Handler {


public WriteHandler(Looper looper) {
super(looper);
}


@Override
public void handleMessage(Message msg) {
if (msg.what == -1) {
getLooper().quit();
return;
}


if (msg.obj != null && msg.obj instanceof byte[]) {


if (!isConnected()) {
// 伺服器已斷開連線
return;
}


try {
byte[] buffer = (byte[]) msg.obj;
readWriteBytesCount += buffer.length;
mOutputStream.write(buffer);
mOutputStream.flush();


Log.d("IPPush", "-----------------------------");
} catch (IOException e) {
e.printStackTrace();
dissConnect();
LogHelper.e(tag + "_WriteHandler發生了IOException",
e.getMessage());
}
}


super.handleMessage(msg);
}
}


private class ReadThread extends Thread {


public ReadThread() {
}


private boolean readData(byte[] data) {
int length = data.length;
long firstTime = 0;
int i = 0;
while (true) {
if (firstTime == 0) {
firstTime = System.currentTimeMillis();
} else {
if (System.currentTimeMillis() - firstTime > 3000) {
return false;
}
}
try {
int readLength = 0;
if ((readLength = mInputStream.read(data, i, length - i)) == length
- i) {
// 讀取成功,資料在data裡
Log.d("data", "" + data.length);
return true;
} else {
i += readLength;
}


} catch (IOException e) {
e.printStackTrace();
LogHelper.e(tag + "_Error", e.getMessage());
return false;
}
}
}


@Override
public void run() {//資料讀取這一塊就根據具體協議來定
try {
StringBuffer stringBuffer = new StringBuffer();
Log.d("stringBuffer", "" + stringBuffer.length());
String line = null;
final byte[] successHeader = new byte[3];
while (isConnected()) {
byte[] header = new byte[4];
if (readData(header)) {
int length = Util.toInt(header);
byte[] data = new byte[length];
if (readData(data)) {
int i = mListener.size();
for (ISocketClient listener : mListener) {
ProtobufHandler.getInstance(mContext).read(
listener, mContext, data);
}
}
}
/*
* if (mInputStream.read(header) == 3) { int length =
* mInputStream.read(); Log.d("length", "" + length); byte[]
* data = new byte[length]; long firstTime = 0; int i = 0;
* while(true){ if(firstTime == 0){ firstTime =
* System.currentTimeMillis(); } else{
* if(System.currentTimeMillis() - firstTime > 3000){ break;
* } } if ((i = mInputStream.read(data, i, length - i)) ==
* length - i) { // 讀取成功,資料在data裡 Log.d("data", "" +
* data.length); // for (int i = 0; i < data.length; i++) {
* // Log.d("data"+i, "" + data[i]); // }
* 
* for(ISocketClient listener : mListener){
* ProtobufHandler.getInstance(mContext).read(listener,
* mContext, data); } break; } else {
* 
* } }
* 
* }
*/
/*
* try { Thread.sleep(2000); } catch (InterruptedException
* e) { }
*/
}


// while (isConnected()) {
//
//
// byte[] recvMsg2 = recvMsg(mInputStream);
// Log.d("recvMsg2", "" + recvMsg2.length);
// byte[] readByte = Bytes.readByte(recvMsg2);
// Log.d("readByte", "" + readByte.length);
// ProtobufHandler.getInstance(mContext).read(mListener1,
// mContext, readByte);
// try {
// Thread.sleep(5000);
// } catch (InterruptedException e) {
// }
// }
} catch (Exception e) {
e.printStackTrace();
LogHelper.e(tag + "_ReadThread發生了IOException", e.getMessage());
} finally {
// dissConnect();
}


// 伺服器已斷開連線
}
}


/**
* 接收server的資訊
* 
* @return
* @throws SmsClientException
* @author fisher
*/
public byte[] recvMsg(InputStream inpustream) {
try {


byte len[] = new byte[1024];
int count = inpustream.read(len);


byte[] temp = new byte[count];
for (int i = 0; i < count; i++) {
temp[i] = len[i];
}
return temp;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}


/**
* 上傳檔案
* 
* @return 返回本次請求的flag標識
* @throws ConnectionException
*/
public long upLoadFile(String url, InputStream is, String filename,
Map<String, String> map, long flag, UploadFileCallback callback)
throws Exception {
UploadFile upLoadFile = new UploadFile(mContext, is, filename, url,
map, callback, flag);
mMapUploadFile.put(flag, upLoadFile);
new Thread(upLoadFile).start();
return flag;
}


/**
* 下載檔案
* 
* @param url
* @return -1請求失敗
* @throws ConnectionException
*/
public int downLoadFile(Context context, String url, int flag,
DownloadFileCallback callback) throws Exception {


if (CommonFuncation.isEmptyOrNullStr(url)) {
return -1;
}
String filename = url.substring(url.lastIndexOf("/") + 1, url.length());
return downLoadFile(context, url, Config.cacheAudioPath, filename,
flag, callback);
}


/**
* 下載檔案
* 
* @param url
* @param dir
* @param filename
* @return
* @throws ConnectionException
*/
public int downLoadFile(Context context, String url, String dir,
String filename, int flag, DownloadFileCallback callback)
throws Exception {


mMapDownLoadFile.put(flag, null);
File file = new File(dir, filename);
DownloadFile downLoadFile = new DownloadFile(context, callback, url,
filename, file.getAbsolutePath(), flag, file.exists());
new Thread(downLoadFile).start();
return flag;
}


// 關閉下載
public void closeDownLoadFile(int flag) {
if (mMapDownLoadFile.containsKey(flag)) {
mMapDownLoadFile.get(flag).close();
mMapDownLoadFile.remove(flag);
}
}


public static interface OnConnectListener {
public void onConnectSuccess(IPPushManager manager);


public void onConnectFail(Exception e);
}


public static interface PushListener {
/**
* 有推送內容到達
* 
* @Title: onPush
* @Description: TODO
* @return: void
*/
public void onPush();
}




}



import java.util.HashMap;
import java.util.List;
import java.util.Stack;


import android.app.Activity;
import android.app.ActivityManager;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Binder;
import android.os.IBinder;
import android.os.SystemClock;
import android.text.TextUtils;
import android.util.Log;





/**
 * 
 * @author ZengJ
 * @data 2014-04-24 10:20:15
 * @version 1.0.0
 * 
 * 
 */
public class IPPushService extends Service {
public final static String tag = IPPushService.class.getSimpleName();
public final static String ACTION_HEART = "com.changyou.rc_sdk.socket。heart";
public final static String ACTION_SEND = "com.changyou.rc_sdk.socket.send";
public final static String PARAMS_SEND = "data";
public final static String NETWORK = ConnectivityManager.CONNECTIVITY_ACTION;
public final static int REQUEST_CODE_HEART_ALARM = 0x99;


private String mHost = "";
private int mPort = 0;
private static final int NET_CHECK_HEART_TIME = 25 * 1000;
private static final int WAP_CHECK_HEART_TIME = 25 * 1000;
public static boolean isOpen = false;
public static int sHeartCount = 0;
private int mHeartCheckTime = NET_CHECK_HEART_TIME;// 25s檢測一次心跳狀態
private IPPushServiceBinder mIPPushServiceBinder = new IPPushServiceBinder();
private IPPushManager mIPPushManager;
private IPPushHeartReceiver mIPPushHeartReceiver;
HashMap<Type, ISocketClient> mMaps;


public void registerListener(Type type, ISocketClient listener) {


}


/**
* 啟動IPPush服務
* 
* @Title: startIPPushService
* @Description: TODO
* @param context
* @return: void
* 
* 
*/
public static synchronized void startIPPushService(Context context,
String host, int port) {
if (isOpen) {
return;
}


if (isServiceRunning(context)) {
return;
}


isOpen = true;


if (context == null) {
return;
}


try {
context.startService(new Intent(context, IPPushService.class)
.putExtra("host", host).putExtra("port", port));
} catch (Exception e) {
}
}


/**
* 重啟IPPush服務
* 
* @Title: startIPPushService
* @Description: TODO
* @param context
* @return: void
*/
public static synchronized void restartIPPushService(Context context,
String host, int port) {
if (isOpen) {
return;
}


if (context == null) {
return;
}


closeIPPushService(context);
startIPPushService(context, host, port);
}


/**
* 關閉IPPush服務
* 
* @Title: closeIPPushService
* @Description: TODO
* @param context
* @return: void
*/
public static synchronized void closeIPPushService(Context context) {
if (context == null) {
return;
}


try {
context.stopService(new Intent(context, IPPushService.class));
} catch (Exception e) {
}
}


/**
* 用來判斷服務是否執行.
* 
* @param context
* @param className
*            判斷的服務名字:包名+類名
* @return true 在執行, false 不在執行
*/


public static boolean isServiceRunning(Context context) {
boolean isRunning = false;
ActivityManager activityManager = (ActivityManager) context
.getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningServiceInfo> serviceList = activityManager
.getRunningServices(Integer.MAX_VALUE);
if (!(serviceList.size() > 0)) {
return false;
}
for (int i = 0; i < serviceList.size(); i++) {
if (serviceList.get(i).service.getClassName().equals(
IPPushService.class.getName()) == true) {
isRunning = true;
break;
}
}
return isRunning;
}


@Override
public void onCreate() {
super.onCreate();


mIPPushHeartReceiver = new IPPushHeartReceiver();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(ACTION_HEART);
intentFilter.addAction(ACTION_SEND);
intentFilter.addAction(NETWORK);
registerReceiver(mIPPushHeartReceiver, intentFilter);
}


private class IPPushHeartReceiver extends BroadcastReceiver {


@Override
public void onReceive(Context context, Intent intent) {


String action = intent.getAction();
if (ACTION_HEART.equals(action)) {
LogHelper.d(tag + "_心跳中", "(" + sHeartCount++ + ")...");
if (mIPPushManager == null || !mIPPushManager.isConnected()) {
// 發起註冊並連線的任務
LogHelper.d(tag + "_connect", " 失去連線");
connect();
} else {
// 發出心跳包
RCMessage.Builder builder = Params.sendHeartbeat();


byte[] writeHeart = ProtobufHandler.getInstance(context)
.writeHeart(builder, IPPushService.this);
if (writeHeart != null) {
mIPPushManager.send(writeHeart);
}
// RCMessage.Builder builder = RCMessage.newBuilder();
// HeatBit.Builder heatbit = HeatBit.newBuilder();
// heatbit.setUid(ChangYouManager.getInstance().getUid());
// heatbit.setGameKey(ChangYouManager.getInstance().getUid());
// heatbit.setDistrict(ChangYouManager.getInstance().getUid());
// heatbit.setServerid(ChangYouManager.getInstance().getUid());
// heatbit.setNickname(ChangYouManager.getInstance().getUid());
// builder.setHeatBit(heatbit);
// builder.setUri(Type.HEAT_BIT);
// RCMessage message = builder.build();
// byte[] byteArray = message.toByteArray();
// byte[] setByteLength = Bytes.setByteLength(byteArray);
// mIPPushManager.send(setByteLength);
// CommonFuncation.log("write", byteArray.length);
// CommonFuncation.log("setByteLength",
// setByteLength.length);
LogHelper.d(tag + "_HEART", "傳送客戶端心跳請求");
// 設定下次心跳時間
setCheckHeartTime(NetworkUtil.getNetworkType(context));
setHeartAlarm();
}


} else if (ACTION_SEND.equals(action)) {
if (mIPPushManager != null && mIPPushManager.isConnected()) {
byte[] data = intent.getByteArrayExtra(PARAMS_SEND);
if (data != null) {


mIPPushManager.send(data);
}
}
} else if (NETWORK.equals(action)) {
Log.d("mark", "網路狀態已經改變");
ConnectivityManager connectivityManager = (ConnectivityManager)


getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo info = connectivityManager.getActiveNetworkInfo();
if (info != null && info.isAvailable()) {
String name = info.getTypeName();
Log.d("mark", "當前網路名稱:" + name);
connect();
} else {
Log.d("mark", "沒有可用網路");
connect();
}
}


}
}


@Override
@Deprecated
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);


if (intent == null) {
stopSelf();
return;
}
// 獲取啟動引數
mHost = intent.getStringExtra("host");
mPort = intent.getIntExtra("port", -1);


LogHelper.d(tag+"_獲取啟動引數", "獲取啟動引數");
LogHelper.d(tag+"_Host:", mHost);
LogHelper.d(tag+"_Port:", mPort);


if (TextUtils.isEmpty(mHost) || mPort <= 0) {
LogHelper.d("獲取啟動引數失敗", "獲取啟動引數失敗");
stopSelf();
return;
} else {
connect();
}
}


private void setHeartAlarm() {
setCheckHeartTime(NetworkUtil.getNetworkType(this));
LogHelper.d(tag+"_設定心跳監聽:", mHeartCheckTime);


// 註冊一個鬧鐘  心跳這塊ELAPSED_REALTIME 這個休眠後是不會發送心跳了,建議加上cpu休眠喚醒,
//但是比較耗電,程式碼會在最下面,諸君最好是在服務或者application裡面新增
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(ACTION_HEART);
// PendingIntent pendingIntent=PendingIntent.getBroadcast(this, 0, i,
// PendingIntent.FLAG_UPDATE_CURRENT);
// long elapsedRealtime = SystemClock.elapsedRealtime();
// alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME,
// elapsedRealtime, 25*1000, pendingIntent);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this,
REQUEST_CODE_HEART_ALARM, i, PendingIntent.FLAG_CANCEL_CURRENT);
// 如果系統中已存在該鬧鐘,先取消
// alarmManager.cancel(pendingIntent);
// 設定鬧鐘時間(伺服器返回的時間是以秒為單位)
long triggerAtTime = SystemClock.elapsedRealtime() + 25 * 1000;
alarmManager.set(AlarmManager.ELAPSED_REALTIME, triggerAtTime,
pendingIntent);
LogHelper.d(tag+"_設定心跳監聽1:", mHeartCheckTime);
}


/**
* 連線IPPush服務
* 
* @Title: connect
* @Description: TODO
* @return: void
*/
private void connect() {
if (!NetworkUtil.isNetworkConnected(this)) {
LogHelper.d(tag+"_connect", " 網路連線不可用");
return;
}


if (mIPPushManager == null) {
mIPPushManager = IPPushManager.getInstance();
mIPPushManager.setPushListener(new PushListener() {


@Override
public void onPush() {
LogHelper.d(tag+"_onPush", "true");
}
});
}


if (!mIPPushManager.isConnected()) {
LogHelper.d(tag+"_connect", " 開始連線");
mIPPushManager.connect(new OnConnectListener() {


@Override
public void onConnectSuccess(IPPushManager manager) {
LogHelper.d(tag+"_connect", " 連線成功");
// // 發起註冊請求
// RCMessage.Builder builder=RCMessage.newBuilder();
// HeatBit.Builder heatbit=HeatBit.newBuilder();
// heatbit.setUid(ChangYouManager.getInstance().getUid());
// heatbit.setGameKey(ChangYouManager.getInstance().getUid());
// heatbit.setDistrict(ChangYouManager.getInstance().getUid());
// heatbit.setServerid(ChangYouManager.getInstance().getUid());
// heatbit.setNickname(ChangYouManager.getInstance().getUid());
// builder.setHeatBit(heatbit);
// builder.setUri(Type.HEAT_BIT);
// byte[] write =
// ProtobufHandler.getInstance().write(IPPushService.this,
// builder);
// byte[] setByteLength = Bytes.setByteLength(write);
// CommonFuncation.log("write", write.length);
// CommonFuncation.log("setByteLength",
// setByteLength.length);
// mIPPushManager.send(setByteLength);


// 傳送心跳監聽
sendBroadcast(new Intent(ACTION_HEART));
}


@Override
public void onConnectFail(Exception e) {
// 稍後重試
LogHelper.d(tag+"_connect", " 連線失敗");
}
});
}
}


@Override
public IBinder onBind(Intent intent) {
return mIPPushServiceBinder;
}


@Override
public void onDestroy() {
super.onDestroy();


if (mIPPushHeartReceiver != null) {
unregisterReceiver(mIPPushHeartReceiver);
}


if (mIPPushManager != null) {
// mIPPushManager.dissConnect();
}


isOpen = false;
}


// public void onEventMainThread(NetworkChangeEvent event) {
// CommonFuncation.log("網路狀態發生變化:" + event.type);
// setCheckHeartTime(event.type);
// sendBroadcast(new Intent(ACTION_HEART));
// }


/**
* 判斷網路狀態
* 
* @Title: getAPNType
* @Description: TODO
* @param context
* @return
* @return: int
*/
public void setCheckHeartTime(int networkType) {
if (networkType == 0) {
mHeartCheckTime = NET_CHECK_HEART_TIME;
} else if (networkType == 1) {
mHeartCheckTime = NET_CHECK_HEART_TIME;
} else if (networkType == 2) {
mHeartCheckTime = WAP_CHECK_HEART_TIME;
} else if (networkType == 3) {
mHeartCheckTime = NET_CHECK_HEART_TIME;
} else if (networkType == 4) {
mHeartCheckTime = NET_CHECK_HEART_TIME;
} else {
mHeartCheckTime = WAP_CHECK_HEART_TIME;
}
}


class IPPushServiceBinder extends Binder {
public IPPushService getService() {
return IPPushService.this;
}
}


public static interface IIPPushServiceBindListener {
public void onServiceDisconnected();


public void onServiceConnected(IPPushService service);
}




}


import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;


import android.content.Context;
import android.content.Intent;





/**
 * 
 * @author ZengJ
 * @data 2014-04-28 14:20:23
 */
public class ProtobufHandler {
public static final String tag = ProtobufHandler.class.getSimpleName();
private long reqNum;
private HashMap<Long, Long> mProtoMap;
private List<ListenerHolder> mListnerList;
private static ProtobufHandler protobufHandler;


private ProtobufHandler(Context context) {
reqNum = 0;
mProtoMap = new HashMap<Long, Long>();
mListnerList = new ArrayList<ListenerHolder>();
}


public static ProtobufHandler getInstance(Context context) {
if (protobufHandler == null) {
protobufHandler = new ProtobufHandler(context);
}
return protobufHandler;
}


/**
* 客戶端資料請求
* 
* @param builder
* @return
*/
public void write(Context context, RCMessage.Builder builder,
IProtobufListener protoHolder) {
builder.setMsgSeqno(++reqNum);
RCMessage message = builder.build();
byte[] byteArray = message.toByteArray();
byte[] setByteLength = Bytes.setByteLength(byteArray);
context.sendBroadcast(new Intent(IPPushService.ACTION_SEND).putExtra(
IPPushService.PARAMS_SEND, setByteLength));
LogHelper.d(tag + "_byteArray", byteArray.length);
LogHelper.d(tag + "_setByteLength", setByteLength.length);
ProtoHolder holder = new ProtoHolder(reqNum, protoHolder);
mProtoMap.put(reqNum, reqNum);
}


/**
* 客戶端心跳
* 
* @param builder
* @return
*/
public byte[] writeHeart(RCMessage.Builder builder,
IProtobufListener protoHolder) {
builder.setMsgSeqno(++reqNum);
RCMessage message = builder.build();
byte[] byteArray = message.toByteArray();
byte[] setByteLength = Bytes.setByteLength(byteArray);
LogHelper.d(tag + "_byteArray", byteArray.length);
LogHelper.d(tag + "_setByteLength", setByteLength.length);
ProtoHolder holder = new ProtoHolder(reqNum, protoHolder);
mProtoMap.put(reqNum, reqNum);
return setByteLength;
}


/**
* 從伺服器讀取資料
* 
* @param bytes
*/
public void read(ISocketClient iSocketClient, Context context, byte[] bytes) {
try {
if (bytes == null) {
return;
}
RCMessage message = RCMessage.parseFrom(bytes);
FilterUtil.getInstance().filterReceiveSocket(iSocketClient,
context, message);
// if (message.hasMsgSeqno() == false) {
// RCMessage.Type type = message.getUri();
// for (ListenerHolder listenerHolder : mListnerList) {
// if (listenerHolder.mType == type)
// listenerHolder.mProtobufListener.handleProto(message);
// }
// return;
// }


} catch (InvalidProtocolBufferException e) {
e.printStackTrace();
}


}


public void RegisterRecListener(RCMessage.Type type,
IProtobufListener protoListener) {
mListnerList.add(new ListenerHolder(type, protoListener));
}


public void UnregisterRecListener(IProtobufListener protoListener) {
for (Iterator<ListenerHolder> it = mListnerList.iterator(); it
.hasNext();) {
ListenerHolder listenerHolder = it.next();
if (listenerHolder == protoListener)
it.remove();
}
}


class ListenerHolder {
public RCMessage.Type mType;
public IProtobufListener mProtobufListener;


public ListenerHolder(RCMessage.Type type,
IProtobufListener protobufListener) {
mType = type;
mProtobufListener = protobufListener;


}
}


class ProtoHolder {
public long seq;
public IProtobufListener protoHolder;
public ProtoTimeoutRunnable runnable;


public ProtoHolder(long seq, IProtobufListener proListener) {
this.seq = seq;
this.protoHolder = proListener;
this.runnable = new ProtoTimeoutRunnable(this.seq);
}
}


class ProtoTimeoutRunnable implements Runnable {
public long seq;


public ProtoTimeoutRunnable(long seq) {
this.seq = seq;
}


@Override
public void run() {
// 這裡應該是超時
if (mProtoMap.containsKey(seq)) {
// ProtoHolder protoHoler = mProtoMap.remove(this.seq);
// protoHoler.protoHandler.handleProtoTimeout();
}
}
}


}


public void acquireWakeLock(){
if(wakeLock == null){
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKE_TAG);
wakeLock.acquire();
}
}

public void releaseWakeLock(){
if(wakeLock != null && wakeLock.isHeld()){
wakeLock.release();
wakeLock = null;
}
}


在oncreate新增,銷燬的時候釋放,親,喚醒鎖記得加許可權,也可以用timer+喚醒鎖,先到這了有時間在寫,多多關注,精彩在後續