{
+
+ private static final String TAG = "NettyClientHandler";
+ private final boolean isSendheartBeat;
+ private NettyClientListener listener;
+ private int index;
+ private Object heartBeatData;
+ private String packetSeparator;
+
+ // private static final ByteBuf HEARTBEAT_SEQUENCE = Unpooled.unreleasableBuffer(Unpooled.copiedBuffer("Heartbeat"+System.getProperty("line.separator"),
+// CharsetUtil.UTF_8));
+ byte[] requestBody = {(byte) 0xFE, (byte) 0xED, (byte) 0xFE, 5, 4, (byte) 0xFF, 0x0a};
+
+
+ public NettyClientHandler(NettyClientListener listener, int index, boolean isSendheartBeat, Object heartBeatData) {
+ this(listener,index,isSendheartBeat,heartBeatData,null);
+ }
+
+ public NettyClientHandler(NettyClientListener listener, int index, boolean isSendheartBeat, Object heartBeatData,String separator) {
+ this.listener = listener;
+ this.index = index;
+ this.isSendheartBeat = isSendheartBeat;
+ this.heartBeatData = heartBeatData;
+ this.packetSeparator = TextUtils.isEmpty(separator) ? System.getProperty("line.separator") : separator;
+ }
+
+ /**
+ * 设定IdleStateHandler心跳检测每x秒进行一次读检测,
+ * 如果x秒内ChannelRead()方法未被调用则触发一次userEventTrigger()方法
+ *
+ * @param ctx ChannelHandlerContext
+ * @param evt IdleStateEvent
+ */
+ @Override
+ public void userEventTriggered(ChannelHandlerContext ctx, Object evt) {
+ if (evt instanceof IdleStateEvent) {
+ IdleStateEvent event = (IdleStateEvent) evt;
+ if (event.state() == IdleState.WRITER_IDLE) { //发送心跳
+// ctx.channel().writeAndFlush("Heartbeat" + System.getProperty("line.separator"));
+ if (isSendheartBeat) {
+ if (heartBeatData == null) {
+ ctx.channel().writeAndFlush("Heartbeat" + packetSeparator);
+ } else {
+ if (heartBeatData instanceof String) {
+// Log.d(TAG, "userEventTriggered: String");
+ ctx.channel().writeAndFlush(heartBeatData + packetSeparator);
+ } else if (heartBeatData instanceof byte[]) {
+// Log.d(TAG, "userEventTriggered: byte");
+ ByteBuf buf = Unpooled.copiedBuffer((byte[]) heartBeatData);
+ ctx.channel().writeAndFlush(buf);
+ } else {
+ Log.e(TAG, "userEventTriggered: heartBeatData type error");
+ }
+ }
+ } else {
+ Log.e(TAG, "不发送心跳");
+ }
+ }
+ }
+ }
+
+ /**
+ * 客户端上线
+ *
+ * @param ctx ChannelHandlerContext
+ */
+ @Override
+ public void channelActive(ChannelHandlerContext ctx) {
+ Log.e(TAG, "channelActive");
+// NettyTcpClient.getInstance().setConnectStatus(true);
+ listener.onClientStatusConnectChanged(ConnectState.STATUS_CONNECT_SUCCESS, index);
+ }
+
+ /**
+ * 客户端下线
+ *
+ * @param ctx ChannelHandlerContext
+ */
+ @Override
+ public void channelInactive(ChannelHandlerContext ctx) {
+ Log.e(TAG, "channelInactive");
+// NettyTcpClient.getInstance().setConnectStatus(false);
+// listener.onServiceStatusConnectChanged(NettyClientListener.STATUS_CONNECT_CLOSED);
+ // NettyTcpClient.getInstance().reconnect();
+ }
+
+ /**
+ * 客户端收到消息
+ *
+ * @param channelHandlerContext ChannelHandlerContext
+ * @param msg 消息
+ */
+ @Override
+ protected void channelRead0(ChannelHandlerContext channelHandlerContext, String msg) {
+ Log.e(TAG, "channelRead0:"+msg);
+ listener.onMessageResponseClient(msg, index);
+ }
+
+ /**
+ * @param ctx ChannelHandlerContext
+ * @param cause 异常
+ */
+ @Override
+ public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
+ // Close the connection when an exception is raised.
+// NettyTcpClient.getInstance().setConnectStatus(false);
+ Log.e(TAG, "exceptionCaught");
+ listener.onClientStatusConnectChanged(ConnectState.STATUS_CONNECT_ERROR, index);
+ cause.printStackTrace();
+ ctx.close();
+ }
+}
diff --git a/libraries/mogo-telematic/src/main/java/com/mogo/telematic/client/listener/MessageStateListener.java b/libraries/mogo-telematic/src/main/java/com/mogo/telematic/client/listener/MessageStateListener.java
new file mode 100644
index 0000000..f065307
--- /dev/null
+++ b/libraries/mogo-telematic/src/main/java/com/mogo/telematic/client/listener/MessageStateListener.java
@@ -0,0 +1,9 @@
+package com.mogo.telematic.client.listener;
+
+
+/**
+ * 发送状态监听
+ */
+public interface MessageStateListener {
+ void isSendSuccss(boolean isSuccess);
+}
diff --git a/libraries/mogo-telematic/src/main/java/com/mogo/telematic/client/listener/NettyClientListener.java b/libraries/mogo-telematic/src/main/java/com/mogo/telematic/client/listener/NettyClientListener.java
new file mode 100644
index 0000000..acfffef
--- /dev/null
+++ b/libraries/mogo-telematic/src/main/java/com/mogo/telematic/client/listener/NettyClientListener.java
@@ -0,0 +1,22 @@
+package com.mogo.telematic.client.listener;
+
+
+/**
+ * TCP状态变化监听
+ */
+public interface NettyClientListener {
+
+ /**
+ * 当接收到系统消息
+ * @param msg 消息
+ * @param index tcp 客户端的标识,因为一个应用程序可能有很多个长链接
+ */
+ void onMessageResponseClient(T msg, int index);
+
+ /**
+ * 当服务状态发生变化时触发
+ * @param statusCode 状态变化
+ * @param index tcp 客户端的标识,因为一个应用程序可能有很多个长链接
+ */
+ public void onClientStatusConnectChanged(int statusCode, int index);
+}
diff --git a/libraries/mogo-telematic/src/main/java/com/mogo/telematic/client/status/ConnectState.java b/libraries/mogo-telematic/src/main/java/com/mogo/telematic/client/status/ConnectState.java
new file mode 100644
index 0000000..08747a9
--- /dev/null
+++ b/libraries/mogo-telematic/src/main/java/com/mogo/telematic/client/status/ConnectState.java
@@ -0,0 +1,12 @@
+package com.mogo.telematic.client.status;
+
+/**
+ * 连接状态
+ */
+public class ConnectState {
+ public final static int STATUS_CONNECT_SUCCESS = 1;
+
+ public final static int STATUS_CONNECT_CLOSED = 0;
+
+ public final static int STATUS_CONNECT_ERROR = -1;
+}
diff --git a/libraries/mogo-telematic/src/main/java/com/mogo/telematic/server/NSDServer.java b/libraries/mogo-telematic/src/main/java/com/mogo/telematic/server/NSDServer.java
new file mode 100644
index 0000000..f71f670
--- /dev/null
+++ b/libraries/mogo-telematic/src/main/java/com/mogo/telematic/server/NSDServer.java
@@ -0,0 +1,99 @@
+package com.mogo.telematic.server;
+
+import android.content.Context;
+import android.net.nsd.NsdManager;
+import android.net.nsd.NsdServiceInfo;
+import android.util.Log;
+
+public class NSDServer {
+ public static final String TAG = "NSDServer";
+ private NsdManager mNsdManager;
+ private NsdManager.RegistrationListener mRegistrationListener;
+ private String mServerName;
+ private Context mContext;
+ private int mPort;
+ private String mServiceName;
+ private final String mServerType = "_http._tcp."; // 服务器type,要客户端扫描服务器的一致
+
+ public NSDServer() {
+ }
+
+ public void startNSDServer(Context context, String serviceName, int port) {
+ initializeRegistrationListener();
+ registerService(context, serviceName, port);
+ }
+
+ //实例化注册监听器
+ private void initializeRegistrationListener() {
+ mRegistrationListener = new NsdManager.RegistrationListener() {
+ @Override
+ public void onRegistrationFailed(NsdServiceInfo serviceInfo, int errorCode) {
+ Log.e(TAG, "NsdServiceInfo onRegistrationFailed");
+ if (registerState != null) {
+ registerState.onRegistrationFailed(serviceInfo, errorCode);
+ }
+ }
+
+ @Override
+ public void onUnregistrationFailed(NsdServiceInfo serviceInfo, int errorCode) {
+ Log.i(TAG, "onUnregistrationFailed serviceInfo: " + serviceInfo + " ,errorCode:" + errorCode);
+ if (registerState != null) {
+ registerState.onUnregistrationFailed(serviceInfo, errorCode);
+ }
+ }
+
+ @Override
+ public void onServiceRegistered(NsdServiceInfo serviceInfo) {
+ mServerName = serviceInfo.getServiceName();
+ Log.i(TAG, "onServiceRegistered: " + serviceInfo.toString());
+ Log.i(TAG, "mServerName onServiceRegistered: " + mServerName);
+ if (registerState != null) {
+ registerState.onServiceRegistered(serviceInfo);
+ }
+ }
+
+ @Override
+ public void onServiceUnregistered(NsdServiceInfo serviceInfo) {
+ Log.i(TAG, "onServiceUnregistered serviceInfo: " + serviceInfo);
+ if (registerState != null) {
+ registerState.onServiceUnregistered(serviceInfo);
+ }
+ }
+ };
+ }
+
+ private void registerService(Context context, String serviceName, int port) {
+ mNsdManager = (NsdManager) context.getSystemService(Context.NSD_SERVICE);
+ NsdServiceInfo serviceInfo = new NsdServiceInfo();
+ serviceInfo.setServiceName(serviceName);
+ serviceInfo.setPort(port);
+ serviceInfo.setServiceType(mServerType);
+ mNsdManager.registerService(serviceInfo, NsdManager.PROTOCOL_DNS_SD, mRegistrationListener);
+ }
+
+ public void stopNSDServer() {
+ mNsdManager.unregisterService(mRegistrationListener);
+ }
+
+
+ //NSD服务注册监听接口
+ public interface IRegisterState {
+ void onServiceRegistered(NsdServiceInfo serviceInfo); //注册NSD成功
+
+ void onRegistrationFailed(NsdServiceInfo serviceInfo, int errorCode); //注册NSD失败
+
+ void onServiceUnregistered(NsdServiceInfo serviceInfo); //取消NSD注册成功
+
+ void onUnregistrationFailed(NsdServiceInfo serviceInfo, int errorCode); //取消NSD注册失败
+
+ }
+
+ //NSD服务接口对象
+ private IRegisterState registerState;
+
+
+ //设置NSD服务接口对象
+ public void setRegisterState(IRegisterState registerState) {
+ this.registerState = registerState;
+ }
+}
diff --git a/libraries/mogo-telematic/src/main/java/com/mogo/telematic/server/bean/ClientChanel.java b/libraries/mogo-telematic/src/main/java/com/mogo/telematic/server/bean/ClientChanel.java
new file mode 100644
index 0000000..fafdcef
--- /dev/null
+++ b/libraries/mogo-telematic/src/main/java/com/mogo/telematic/server/bean/ClientChanel.java
@@ -0,0 +1,46 @@
+package com.mogo.telematic.server.bean;
+
+import io.netty.channel.Channel;
+
+/**
+ * 客户端信息
+ */
+public class ClientChanel {
+
+ private String clientIp; //客户端ip
+
+ private Channel channel; //与客户端建立的通道
+
+ private String shortId; //通道的唯一标示
+
+
+ public ClientChanel(String clientIp, Channel channel, String shortId) {
+ this.clientIp = clientIp;
+ this.channel = channel;
+ this.shortId = shortId;
+ }
+
+ public String getClientIp() {
+ return clientIp;
+ }
+
+ public void setClientIp(String clientIp) {
+ this.clientIp = clientIp;
+ }
+
+ public Channel getChannel() {
+ return channel;
+ }
+
+ public void setChannel(Channel channel) {
+ this.channel = channel;
+ }
+
+ public String getShortId() {
+ return shortId;
+ }
+
+ public void setShortId(String shortId) {
+ this.shortId = shortId;
+ }
+}
diff --git a/libraries/mogo-telematic/src/main/java/com/mogo/telematic/占位 b/libraries/mogo-telematic/src/main/java/com/mogo/telematic/占位
deleted file mode 100644
index e69de29..0000000