socketManager and socketHandler fix

This commit is contained in:
zhongchao
2021-01-25 17:21:26 +08:00
parent ff1a533447
commit cad4280d3c
10 changed files with 525 additions and 178 deletions

1
.idea/gradle.xml generated
View File

@@ -23,6 +23,7 @@
</set>
</option>
<option name="resolveModulePerSourceSet" value="false" />
<option name="useQualifiedModuleNames" value="true" />
</GradleProjectSettings>
</option>
</component>

View File

@@ -26,6 +26,11 @@ import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import static com.mogo.cloud.httpdns.MogoHttpDnsConfig.HTTP_DNS_ENV_DEMO;
import static com.mogo.cloud.httpdns.MogoHttpDnsConfig.HTTP_DNS_ENV_DEV;
import static com.mogo.cloud.httpdns.MogoHttpDnsConfig.HTTP_DNS_ENV_QA;
import static com.mogo.cloud.httpdns.MogoHttpDnsConfig.HTTP_DNS_ENV_RELEASE;
public class SocketManager implements IMogoCloudSocketManager, Callback {
private static final String TAG = "SocketManager";
@@ -176,12 +181,12 @@ public class SocketManager implements IMogoCloudSocketManager, Callback {
private Environment getEnvironment() {
switch (cloudClientConfig.getNetMode()) {
case 1:
case HTTP_DNS_ENV_DEV:
return Environment.dev;
case 2:
case 4:
case HTTP_DNS_ENV_QA:
case HTTP_DNS_ENV_DEMO:
return Environment.qa;
case 3:
case HTTP_DNS_ENV_RELEASE:
default:
return Environment.release;
}

View File

@@ -1,43 +1,21 @@
package com.mogo.realtime.constant;
import android.content.Context;
import android.os.SystemClock;
import android.util.Log;
import com.mogo.cloud.passport.MoGoAiCloudClient;
import com.mogo.cloud.socket.IMogoCloudSocketOnMessageListener;
import com.mogo.cloud.socket.MsgBody;
import com.mogo.cloud.socket.SocketManager;
import com.mogo.realtime.Interface.RealTimeApisHandler;
import com.mogo.realtime.entity.ADASRecognizedResult;
import com.mogo.realtime.entity.CloudLocationInfo;
import com.mogo.cloud.socket.WebSocketData;
import com.mogo.realtime.location.LocationResult;
import com.mogo.realtime.location.MogoRTKLocation;
import com.mogo.realtime.entity.OnePerSecondSendContent;
import com.mogo.realtime.socket.IMogoCloudOnMsgListener;
import com.mogo.realtime.socket.SocketHandler;
import com.mogo.realtime.util.MortonCode;
import com.mogo.utils.network.utils.GsonUtil;
import java.util.ArrayList;
import java.util.List;
import static com.mogo.cloud.socket.WebSocketMsgType.MSG_TYPE_ACK;
/**
* @author congtaowang
* @since 2020/12/14
* <p>
* 实时上报坐标、识别物体
*
*/
public class SnapshotUploadInTime implements MogoRTKLocation.RTKLocationListener {
private static final String TAG = "SnapshotUploadInTime";
private static volatile SnapshotUploadInTime sInstance;
private Context mContext;
private long serverTime = 0;
private long receiveMsgTime = 0;
private SnapshotUploadInTime() {
}
@@ -57,13 +35,8 @@ public class SnapshotUploadInTime implements MogoRTKLocation.RTKLocationListener
sInstance = null;
}
private Object readResolve() {
// 阻止反序列化,必须实现 Serializable 接口
return sInstance;
}
public void start(Context context, boolean useInner, String appId, IMogoCloudSocketOnMessageListener listener) {
mContext = context.getApplicationContext();
//todo 检查是否需要配置 默认开始定位上报
public void start(Context context, boolean useInner, String appId, IMogoCloudOnMsgListener listener) {
MogoRTKLocation.getInstance().registerRTKLocationListener(this);
SocketHandler.getInstance().initSocket(context, useInner, appId, listener);
}
@@ -74,87 +47,7 @@ public class SnapshotUploadInTime implements MogoRTKLocation.RTKLocationListener
@Override
public void onLocationChanged(List<CloudLocationInfo> cloudLocationInfos) {
startSendCarLocationAndAdasRecognizedResult2Server(cloudLocationInfos);
SocketHandler.getInstance().sendMsg(cloudLocationInfos);
}
private CloudLocationInfo mLastInfo;
private void startSendCarLocationAndAdasRecognizedResult2Server(List<CloudLocationInfo> cloudLocationInfo) {
CloudLocationInfo lastInfo = null;
// 如果数组内容不为空,就用数组最后一个值
if (!cloudLocationInfo.isEmpty()) {
lastInfo = cloudLocationInfo.get(cloudLocationInfo.size() - 1);
mLastInfo = lastInfo;
}
if (lastInfo == null) {
lastInfo = mLastInfo;
}
LocationResult locationResult = null;
if (lastInfo != null) {
// 定位点预测纠偏
lastInfo = SimpleLocationCorrectStrategy.getInstance().correct(lastInfo);
locationResult = new LocationResult();
if (lastInfo != null) {
locationResult.lastCoordinate = lastInfo;
locationResult.mortonCode = MortonCode.wrapEncodeMorton(lastInfo.getLon(), lastInfo.getLat());
}
locationResult.coordinates = new ArrayList<>();
locationResult.sn = MoGoAiCloudClient.getInstance().getAiCloudClientConfig().getSn();
locationResult.coordinates.addAll(cloudLocationInfo);
}
List<ADASRecognizedResult> recognizedResults = RealTimeApisHandler.getInstance().getApis().getRecognizedResultManager().getLastADASRecognizedResult();//外显接口返回
OnePerSecondSendContent content = new OnePerSecondSendContent();
content.self = locationResult;
content.adas = recognizedResults;
if (content.self == null &&
(content.adas == null || content.adas.isEmpty())) {
Log.d(TAG, "no information 2 sent");
return;
}
//发送socket msg
WebSocketData webSocketData = new WebSocketData();
webSocketData.setSeq(computeSendMsgTime());
webSocketData.setSn(MoGoAiCloudClient.getInstance().getAiCloudClientConfig().getSn());
webSocketData.setData(GsonUtil.jsonFromObject(content));
// MogoLocation lastKnown = MogoApisHandler.getInstance().getApis().getMapServiceApi()
// .getSingletonLocationClient(mContext)
// .getLastKnowLocation();
// if (lastKnown != null && !lastKnown.getCityCode().isEmpty()) {
// webSocketData.setCityCode(lastKnown.getCityCode());
// } else {
// webSocketData.setCityCode(null);
// }
String msg = GsonUtil.jsonFromObject(webSocketData);
int msgType = 0x040003; //低频数据
if (cloudLocationInfo.size() > 2) {
msgType = 0x040002; //高频数据
}
MsgBody msgBody = new MsgBody();
msgBody.msgType(msgType);
msgBody.content(msg);
SocketManager.getInstance().sendMsg(msgBody, msgId -> {
});
}
/**
* 服务端会在ack数据中增加服务端的时间戳{@link #serverTime}, 收到消息时,记录收到消息的时间{@link #receiveMsgTime},收消息的时间用{@link SystemClock#elapsedRealtime()}可以避免系统时间改变造成的影响
* 在发送数据时使用serverTime+(elapseRealtime()-receiveMsgTime)计算发送数据时的时间戳这个时间戳是基本相对服务端的时间戳为基准的时间忽略了ack下发时的时间延迟
* <p>
* 如果{@link #serverTime}或{@link #receiveMsgTime}数据有异常,则使用{@link System#currentTimeMillis()}当做当前时间,作为容错
*
* @return 基本相对服务端的时间戳为基准的时间
*/
private long computeSendMsgTime() {
long sendMsgTime;
if (serverTime > 0 && receiveMsgTime > 0) {
sendMsgTime = serverTime + (SystemClock.elapsedRealtime() - receiveMsgTime);
} else {
sendMsgTime = System.currentTimeMillis();
}
return sendMsgTime;
}
}

View File

@@ -0,0 +1,240 @@
package com.mogo.realtime.entity;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
import java.util.List;
/**
* 云端道路数据
*
* @author tongchenfei
*/
public class CloudRoadData implements Parcelable {
public static final int FROM_MY_LOCATION = 1;
public static final int FROM_ADAS = 2;
public static final int FROM_ROAD_UNIT = 3;
/**
* 物体类型
*/
private int type = -1;
private int fromType;
private double lat;
private double lon;
private String uuid;
private String sn;
private double speed;
private double heading;
private long systemTime;
/**
* 红绿灯状态 1红 2绿 3黄
*/
private int lightStatus;//
/**
* 红绿灯剩余时间 读秒
*/
private int lightLeftTime;
/**
* 视频流直播地址
*/
private String rtmpUrl;//
private double distance;//距离
private List< CloudLocationInfo > coordinates;
public int getType() {
return type;
}
public void setType( int type ) {
this.type = type;
}
public double getLat() {
return lat;
}
public void setLat( double lat ) {
this.lat = lat;
}
public double getLon() {
return lon;
}
public void setLon( double lon ) {
this.lon = lon;
}
public double getSpeed() {
return speed;
}
public void setSpeed( double speed ) {
this.speed = speed;
}
public long getSystemTime() {
return systemTime;
}
public void setSystemTime( long systemTime ) {
this.systemTime = systemTime;
}
public int getLightStatus() {
return lightStatus;
}
public void setLightStatus( int lightStatus ) {
this.lightStatus = lightStatus;
}
public int getLightLeftTime() {
return lightLeftTime;
}
public void setLightLeftTime( int lightLeftTime ) {
this.lightLeftTime = lightLeftTime;
}
public String getRtmpUrl() {
return rtmpUrl;
}
public void setRtmpUrl( String rtmpUrl ) {
this.rtmpUrl = rtmpUrl;
}
public double getDistance() {
return distance * 1000;
}
public void setDistance( double distance ) {
this.distance = distance;
}
public List< CloudLocationInfo > getCoordinates() {
return coordinates;
}
public void setCoordinates( List< CloudLocationInfo > coordinates ) {
this.coordinates = coordinates;
}
public void setUuid( String uuid ) {
this.uuid = uuid;
}
public String getUuid() {
return uuid;
}
public String getSn() {
return sn;
}
public double getHeading() {
return heading;
}
public void setHeading( double heading ) {
this.heading = heading;
}
public String getUniqueKey() {
if ( !TextUtils.isEmpty( uuid ) ) {
return uuid;
}
return sn;
}
public int getFromType() {
return fromType;
}
public void setFromType( int fromType ) {
this.fromType = fromType;
}
public CloudRoadData() {
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel( Parcel dest, int flags ) {
dest.writeInt( this.type );
dest.writeInt( this.fromType );
dest.writeDouble( this.lat );
dest.writeDouble( this.lon );
dest.writeString( this.uuid );
dest.writeString( this.sn );
dest.writeDouble( this.speed );
dest.writeDouble( this.heading );
dest.writeLong( this.systemTime );
dest.writeInt( this.lightStatus );
dest.writeInt( this.lightLeftTime );
dest.writeString( this.rtmpUrl );
dest.writeDouble( this.distance );
dest.writeTypedList( this.coordinates );
}
protected CloudRoadData(Parcel in ) {
this.type = in.readInt();
this.fromType = in.readInt();
this.lat = in.readDouble();
this.lon = in.readDouble();
this.uuid = in.readString();
this.sn = in.readString();
this.speed = in.readDouble();
this.heading = in.readDouble();
this.systemTime = in.readLong();
this.lightStatus = in.readInt();
this.lightLeftTime = in.readInt();
this.rtmpUrl = in.readString();
this.distance = in.readDouble();
this.coordinates = in.createTypedArrayList( CloudLocationInfo.CREATOR );
}
public static final Creator<CloudRoadData> CREATOR = new Creator<CloudRoadData>() {
@Override
public CloudRoadData createFromParcel(Parcel source ) {
return new CloudRoadData( source );
}
@Override
public CloudRoadData[] newArray(int size ) {
return new CloudRoadData[size];
}
};
@Override
public boolean equals( Object o ) {
if ( this == o ) {
return true;
}
if ( o == null || getClass() != o.getClass() ) {
return false;
}
CloudRoadData that = (CloudRoadData) o;
return Double.compare( that.lat, lat ) == 0 &&
Double.compare( that.lon, lon ) == 0;
}
}

View File

@@ -0,0 +1,151 @@
package com.mogo.realtime.entity;
import android.os.Parcel;
import android.os.Parcelable;
import java.util.List;
public
/*
* @author congtaowang
* @since 2020/10/26
*
* 描述
*/
class MogoSnapshotSetData implements Parcelable {
private String msgId;
private long time;
//过期时间
private long expire;
//总数据集合
private List<CloudRoadData> allList;
// 近景adas数据
private List<CloudRoadData> nearList;
//红绿灯
private CloudRoadData trafficLight;
//路边摄像头
private CloudRoadData camera;
// 自车速度 本地添加
public double curSpeed = 0.0;
@Override
public String toString() {
return "MogoSnapshotSetData{" +
"msgId='" + msgId + '\'' +
", time=" + time +
", expire=" + expire +
", allList=" + allList +
", nearList=" + nearList +
", camera=" + camera +
", curSpeed=" + curSpeed +
'}';
}
public String getMsgId() {
return msgId;
}
public void setMsgId(String msgId) {
this.msgId = msgId;
}
public long getTime() {
return time;
}
public void setTime(long time) {
this.time = time;
}
public long getExpire() {
return expire;
}
public void setExpire(long expire) {
this.expire = expire;
}
public List<CloudRoadData> getAllList() {
return allList;
}
public void setAllList(List<CloudRoadData> allList) {
this.allList = allList;
}
public CloudRoadData getTrafficLight() {
return trafficLight;
}
public void setTrafficLight(CloudRoadData trafficLight) {
this.trafficLight = trafficLight;
}
public CloudRoadData getCamera() {
return camera;
}
public void setCamera(CloudRoadData camera) {
this.camera = camera;
}
public List< CloudRoadData > getNearList() {
return nearList;
}
public void setNearList( List< CloudRoadData > nearList ) {
this.nearList = nearList;
}
public MogoSnapshotSetData() {
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel( Parcel dest, int flags ) {
dest.writeString( this.msgId );
dest.writeLong( this.time );
dest.writeLong( this.expire );
dest.writeTypedList( this.allList );
dest.writeTypedList( this.nearList );
dest.writeParcelable( this.trafficLight, flags );
dest.writeParcelable( this.camera, flags );
dest.writeDouble( this.curSpeed );
}
protected MogoSnapshotSetData(Parcel in ) {
this.msgId = in.readString();
this.time = in.readLong();
this.expire = in.readLong();
this.allList = in.createTypedArrayList( CloudRoadData.CREATOR );
this.nearList = in.createTypedArrayList( CloudRoadData.CREATOR );
this.trafficLight = in.readParcelable( CloudRoadData.class.getClassLoader() );
this.camera = in.readParcelable( CloudRoadData.class.getClassLoader() );
this.curSpeed = in.readDouble();
}
public static final Creator<MogoSnapshotSetData> CREATOR = new Creator<MogoSnapshotSetData>() {
@Override
public MogoSnapshotSetData createFromParcel(Parcel source ) {
return new MogoSnapshotSetData( source );
}
@Override
public MogoSnapshotSetData[] newArray(int size ) {
return new MogoSnapshotSetData[size];
}
};
}

View File

@@ -1,8 +1,6 @@
package com.mogo.realtime.entity;
import com.mogo.realtime.location.LocationResult;
import java.util.List;
public

View File

@@ -1,35 +0,0 @@
package com.mogo.realtime.location;
import com.mogo.realtime.entity.CloudLocationInfo;
import java.util.List;
public
/**
* @author congtaowang
* @since 2020/10/25
*
* 自车定位信息
*/
class LocationResult {
/**
* sn
*/
public String sn;
/**
* 最后一个定位点的莫顿码
*/
public long mortonCode;
/**
* 最后一个定位点
*/
public CloudLocationInfo lastCoordinate;
/**
* 1s 内的连续定位点
*/
public List< CloudLocationInfo > coordinates;
}

View File

@@ -46,8 +46,6 @@ public class MogoRTKLocation {
if (msg.what == MSG_DATA_CHANGED) {
mHandler.sendEmptyMessageDelayed(MSG_DATA_CHANGED, uploadDelay);
sendLocationData();
// Logger.d(TAG,"handleMessage开始发送消息");
}
}
};

View File

@@ -0,0 +1,8 @@
package com.mogo.realtime.socket;
import com.mogo.realtime.entity.MogoSnapshotSetData;
public interface IMogoCloudOnMsgListener {
void onMsgReceived(MogoSnapshotSetData mogoSnapshotSetData);
}

View File

@@ -2,26 +2,42 @@ package com.mogo.realtime.socket;
import android.content.Context;
import android.os.SystemClock;
import android.util.Log;
import com.mogo.cloud.passport.MoGoAiCloudClient;
import com.mogo.cloud.socket.IMogoCloudSocketOnMessageListener;
import com.mogo.cloud.socket.MsgBody;
import com.mogo.cloud.socket.SocketManager;
import com.mogo.cloud.socket.WebSocketData;
import com.mogo.realtime.Interface.RealTimeApisHandler;
import com.mogo.realtime.constant.SimpleLocationCorrectStrategy;
import com.mogo.realtime.entity.ADASRecognizedResult;
import com.mogo.realtime.entity.CloudLocationInfo;
import com.mogo.realtime.entity.LocationResult;
import com.mogo.realtime.entity.MogoSnapshotSetData;
import com.mogo.realtime.entity.OnePerSecondSendContent;
import com.mogo.realtime.util.MortonCode;
import com.mogo.utils.network.utils.GsonUtil;
import java.util.ArrayList;
import java.util.List;
import static com.mogo.cloud.socket.WebSocketMsgType.MSG_TYPE_ACK;
import static com.mogo.cloud.socket.WebSocketMsgType.MSG_TYPE_DOWNLINK_CAR_DATA;
import static com.mogo.cloud.socket.WebSocketMsgType.MSG_TYPE_UPLINK_CAR_DATA;
/**
* @author liujing
* @description 描述
* @since: 2021/1/22
*
*/
public class SocketHandler {
private static final String TAG = "SocketHandler";
private static volatile SocketHandler mInstance;
private long serverTime = 0;
private long receiveMsgTime = 0;
private List<IMogoCloudSocketOnMessageListener> listenerList;
private CloudLocationInfo mLastInfo;
private final List<IMogoCloudOnMsgListener> listenerList = new ArrayList<>();
public static SocketHandler getInstance() {
if (mInstance == null) {
@@ -37,27 +53,23 @@ public class SocketHandler {
/*
* useInner: 是否注册自己内部的监听
* */
public void initSocket(Context context, boolean useInner, String appId, IMogoCloudSocketOnMessageListener listener) {
public void initSocket(Context context, boolean useInner, String appId, IMogoCloudOnMsgListener listener) {
SocketManager.getInstance().init(context, appId);
if (useInner) {
SocketManager.getInstance().registerOnMessageListener(0x040002, onMessageListener);
SocketManager.getInstance().registerOnMessageListener(0x040003, onMessageListener);
} else {
SocketManager.getInstance().registerOnMessageListener(0x040002, listener);
SocketManager.getInstance().registerOnMessageListener(0x040003, listener);
SocketManager.getInstance().registerOnMessageListener(0x040002, onMessageListener);
SocketManager.getInstance().registerOnMessageListener(0x040003, onMessageListener);
if (listener != null && !listenerList.contains(listener)) {
listenerList.add(listener);
}
}
private final IMogoCloudSocketOnMessageListener<String> onMessageListener = new IMogoCloudSocketOnMessageListener<String>() {
private final IMogoCloudSocketOnMessageListener<WebSocketData> onMessageListener = new IMogoCloudSocketOnMessageListener<WebSocketData>() {
@Override
public Class<String> target() {
return String.class;
public Class<WebSocketData> target() {
return WebSocketData.class;
}
@Override
public void onMsgReceived(String message) {
WebSocketData webSocketData = GsonUtil.objectFromJson(message, WebSocketData.class);
public void onMsgReceived(WebSocketData webSocketData) {
int msgType = webSocketData.getMsgType();
if (msgType == MSG_TYPE_ACK.getMsgType()) {
if (webSocketData.getUtcTime() > 0) {
@@ -70,17 +82,93 @@ public class SocketHandler {
}
}
}
if (msgType == MSG_TYPE_DOWNLINK_CAR_DATA.getMsgType()) {
MogoSnapshotSetData data = GsonUtil.objectFromJson(webSocketData.getData(), MogoSnapshotSetData.class);
if (data == null) {
Log.e(TAG, "onMsgReceived MogoSnapshotSetData == null ");
return;
}
for (IMogoCloudOnMsgListener listener : listenerList) {
listener.onMsgReceived(data);
}
}
}
};
public void stop() {
//todo
// MogoRTKLocation.getInstance().unregisterRTKLocationListener();
// MogoRTKLocation.getInstance().stop();
for (int i = 0; i < listenerList.size(); i++) {
SocketManager.getInstance().unregisterOnMessageListener(0x040002, listenerList.get(i));
SocketManager.getInstance().unregisterOnMessageListener(0x040003, listenerList.get(i));
public void sendMsg(List<CloudLocationInfo> cloudLocationInfo) {
CloudLocationInfo lastInfo = null;
// 如果数组内容不为空,就用数组最后一个值
if (!cloudLocationInfo.isEmpty()) {
lastInfo = cloudLocationInfo.get(cloudLocationInfo.size() - 1);
mLastInfo = lastInfo;
}
if (lastInfo == null) {
lastInfo = mLastInfo;
}
LocationResult locationResult = null;
if (lastInfo != null) {
// 定位点预测纠偏
lastInfo = SimpleLocationCorrectStrategy.getInstance().correct(lastInfo);
locationResult = new LocationResult();
if (lastInfo != null) {
locationResult.lastCoordinate = lastInfo;
locationResult.mortonCode = MortonCode.wrapEncodeMorton(lastInfo.getLon(), lastInfo.getLat());
}
locationResult.coordinates = new ArrayList<>();
locationResult.sn = MoGoAiCloudClient.getInstance().getAiCloudClientConfig().getSn();
locationResult.coordinates.addAll(cloudLocationInfo);
}
List<ADASRecognizedResult> recognizedResults = RealTimeApisHandler.getInstance().getApis().getRecognizedResultManager().getLastADASRecognizedResult();//外显接口返回
OnePerSecondSendContent content = new OnePerSecondSendContent();
content.self = locationResult;
content.adas = recognizedResults;
if (content.self == null &&
(content.adas == null || content.adas.isEmpty())) {
Log.d(TAG, "no information to sent");
return;
}
WebSocketData webSocketData = new WebSocketData();
webSocketData.setMsgType(MSG_TYPE_UPLINK_CAR_DATA.getMsgType());
webSocketData.setSeq(computeSendMsgTime());
webSocketData.setSn(MoGoAiCloudClient.getInstance().getAiCloudClientConfig().getSn());
webSocketData.setData(GsonUtil.jsonFromObject(content));
String msg = GsonUtil.jsonFromObject(webSocketData);
int msgType = 0x040003; //低频数据
if (cloudLocationInfo.size() > 2) {
msgType = 0x040002; //高频数据
}
MsgBody msgBody = new MsgBody();
msgBody.msgType(msgType);
msgBody.content(msg);
SocketManager.getInstance().sendMsg(msgBody, msgId -> {
});
}
public void stop() {
SocketManager.getInstance().unregisterOnMessageListener(0x040002, onMessageListener);
SocketManager.getInstance().unregisterOnMessageListener(0x040003, onMessageListener);
listenerList.clear();
}
/**
* 服务端会在ack数据中增加服务端的时间戳{@link #serverTime}, 收到消息时,记录收到消息的时间{@link #receiveMsgTime},收消息的时间用{@link SystemClock#elapsedRealtime()}可以避免系统时间改变造成的影响
* 在发送数据时使用serverTime+(elapseRealtime()-receiveMsgTime)计算发送数据时的时间戳这个时间戳是基本相对服务端的时间戳为基准的时间忽略了ack下发时的时间延迟
* <p>
* 如果{@link #serverTime}或{@link #receiveMsgTime}数据有异常,则使用{@link System#currentTimeMillis()}当做当前时间,作为容错
*
* @return 基本相对服务端的时间戳为基准的时间
*/
private long computeSendMsgTime() {
long sendMsgTime;
if (serverTime > 0 && receiveMsgTime > 0) {
sendMsgTime = serverTime + (SystemClock.elapsedRealtime() - receiveMsgTime);
} else {
sendMsgTime = System.currentTimeMillis();
}
return sendMsgTime;
}
}