diff --git a/app/src/main/java/com/mogo/cloud/netty/client/NettyClientActivity.java b/app/src/main/java/com/mogo/cloud/netty/client/NettyClientActivity.java index 58271b3..8ee081c 100644 --- a/app/src/main/java/com/mogo/cloud/netty/client/NettyClientActivity.java +++ b/app/src/main/java/com/mogo/cloud/netty/client/NettyClientActivity.java @@ -1,8 +1,6 @@ package com.mogo.cloud.netty.client; -import android.net.nsd.NsdServiceInfo; import android.os.Bundle; -import android.text.TextUtils; import android.util.Log; import android.view.View; import android.widget.Button; @@ -15,17 +13,15 @@ import androidx.recyclerview.widget.RecyclerView; import com.mogo.cloud.R; import com.mogo.cloud.netty.LogBean; -import com.mogo.telematic.client.NettyTcpClient; -import com.mogo.telematic.client.NsdClient; -import com.mogo.telematic.client.listener.MessageStateListener; +import com.mogo.telematic.NSDNettyManager; import com.mogo.telematic.client.listener.NettyClientListener; import com.mogo.telematic.client.status.ConnectState; -public class NettyClientActivity extends AppCompatActivity implements View.OnClickListener, NettyClientListener { +import java.util.Arrays; + +public class NettyClientActivity extends AppCompatActivity implements View.OnClickListener, NettyClientListener { private static final String TAG = "NettyClientActivity"; - // client端用来过滤的 - public static final String SERVER_NAME = "NSD_SERVER"; private Button mClearLog; private Button mSendBtn; @@ -37,8 +33,8 @@ public class NettyClientActivity extends AppCompatActivity implements View.OnCli private LogAdapter mSendLogAdapter = new LogAdapter(); private LogAdapter mReceLogAdapter = new LogAdapter(); - private NettyTcpClient mNettyTcpClient; - private NsdClient nsdClient; + + private final byte[] sendByte = new byte[]{0x55, 0x54, 0x72, 0x21}; @Override protected void onCreate(Bundle savedInstanceState) { @@ -46,7 +42,7 @@ public class NettyClientActivity extends AppCompatActivity implements View.OnCli setContentView(R.layout.activity_netty_client); findViews(); initView(); - searchNsdServer(); + NSDNettyManager.getInstance().searchAndConnectServer(this, this); } private void initView() { @@ -71,6 +67,8 @@ public class NettyClientActivity extends AppCompatActivity implements View.OnCli mConnect.setOnClickListener(this); mSendBtn.setOnClickListener(this); mClearLog.setOnClickListener(this); + + mSendET.setText(Arrays.toString(sendByte)); } @Override @@ -81,27 +79,19 @@ public class NettyClientActivity extends AppCompatActivity implements View.OnCli break; case R.id.send_btn: - if (!mNettyTcpClient.getConnectStatus()) { + if (!NSDNettyManager.getInstance().getConnectStatus()) { Toast.makeText(getApplicationContext(), "未连接,请先连接", Toast.LENGTH_SHORT).show(); } else { - final String msg = mSendET.getText().toString(); - if (TextUtils.isEmpty(msg.trim())) { - return; - } - mNettyTcpClient.sendMsgToServer(msg, new MessageStateListener() { - @Override - public void isSendSuccss(boolean isSuccess) { - if (isSuccess) { - Log.d(TAG, "Write auth successful"); - logSend(msg); - } else { - Log.d(TAG, "Write auth error"); - } + NSDNettyManager.getInstance().sendByteArrayToServer(sendByte, isSuccess -> { + if (isSuccess) { + Log.d(TAG, "Write auth successful"); + logSend(Arrays.toString(sendByte)); + } else { + Log.d(TAG, "Write auth error"); } }); - mSendET.setText(""); + mSendET.setText(Arrays.toString(sendByte)); } - break; case R.id.clear_log: @@ -113,83 +103,22 @@ public class NettyClientActivity extends AppCompatActivity implements View.OnCli } } - /** - * 通过Nsd搜索注册过的服务端名称解析后拿到 IP 和端口,进行NettySocket的连接 - */ - private void searchNsdServer() { - - nsdClient = new NsdClient(NettyClientActivity.this, SERVER_NAME, new NsdClient.IServerFound() { - @Override - public void onServerFound(NsdServiceInfo info, int port) { - if (info != null) { - String hostAddress = info.getHost().getHostAddress(); - Log.d(TAG, "NSD查询到指定服务器信息ip为:" + hostAddress + ",port为:" + port); - //获取到指定的地址,进行Netty的连接 - connectNettyServer(hostAddress, port); - - if (info.getServiceName().equals(SERVER_NAME)) { - //扫描到以后停止 - nsdClient.stopNSDServer(); - } - } - } - - @Override - public void onServerFail() { - - } - }); - - nsdClient.startNSDClient(); - } - - private void connectNettyServer(String serverAddress, int port) { - Log.d(TAG, "connectNettyServer"); - if (serverAddress == null || serverAddress.length() == 0) { - Toast.makeText(this, "ip不能为空!", Toast.LENGTH_SHORT).show(); - return; - } - if (mNettyTcpClient == null) { - mNettyTcpClient = new NettyTcpClient.Builder() - .setHost(serverAddress) //设置服务端地址 - .setTcpPort(port) //设置服务端端口号 - .setMaxReconnectTimes(5) //设置最大重连次数 - .setReconnectIntervalTime(5) //设置重连间隔时间。单位:秒 - .setSendheartBeat(true) //设置是否发送心跳 - .setHeartBeatInterval(5) //设置心跳间隔时间。单位:秒 - .setHeartBeatData("I'm is HeartBeatData") //设置心跳数据,可以是String类型,也可以是byte[],以后设置的为准 - .setIndex(0) //设置客户端标识.(因为可能存在多个tcp连接) -// .setPacketSeparator("#")//用特殊字符,作为分隔符,解决粘包问题,默认是用换行符作为分隔符 -// .setMaxPacketLong(1024)//设置一次发送数据的最大长度,默认是1024,最大值为Integer.MAX - .build(); - mNettyTcpClient.setListener(NettyClientActivity.this); //设置TCP监听 - } - - if (!mNettyTcpClient.getConnectStatus()) { - mNettyTcpClient.connect();//连接服务器 - } else { - mNettyTcpClient.disconnect(); - } - } - @Override - public void onMessageResponseClient(String msg, int index) { - Log.e(TAG, "onMessageResponse:" + msg); - logRece(index + ":" + msg); + public void onMessageResponseClient(byte[] msg, int index) { + String result = Arrays.toString(msg); + Log.e(TAG, "onMessageResponse:" + result); + logRece(result); } @Override public void onClientStatusConnectChanged(final int statusCode, final int index) { - runOnUiThread(new Runnable() { - @Override - public void run() { - if (statusCode == ConnectState.STATUS_CONNECT_SUCCESS) { - Log.e(TAG, "STATUS_CONNECT_SUCCESS:"); - mConnect.setText("DisConnect:" + index); - } else { - Log.e(TAG, "onServiceStatusConnectChanged:" + statusCode); - mConnect.setText("Connect:" + index); - } + runOnUiThread(() -> { + if (statusCode == ConnectState.STATUS_CONNECT_SUCCESS) { + Log.e(TAG, "STATUS_CONNECT_SUCCESS:"); + mConnect.setText("DisConnect:" + index); + } else { + Log.e(TAG, "onServiceStatusConnectChanged:" + statusCode); + mConnect.setText("Connect:" + index); } }); @@ -198,43 +127,16 @@ public class NettyClientActivity extends AppCompatActivity implements View.OnCli private void logSend(String log) { LogBean logBean = new LogBean(System.currentTimeMillis(), log); mSendLogAdapter.getDataList().add(0, logBean); - runOnUiThread(new Runnable() { - @Override - public void run() { - mSendLogAdapter.notifyDataSetChanged(); - } - }); - + runOnUiThread(() -> mSendLogAdapter.notifyDataSetChanged()); } private void logRece(String log) { LogBean logBean = new LogBean(System.currentTimeMillis(), log); mReceLogAdapter.getDataList().add(0, logBean); - runOnUiThread(new Runnable() { - @Override - public void run() { - mReceLogAdapter.notifyDataSetChanged(); - } - }); - - } - - /** - * 方法三: - * byte[] to hex string - * - * @param bytes - * @return - */ - public static String bytesToHexFun3(byte[] bytes, int length) { - StringBuilder buf = new StringBuilder(length * 2); - for (int i = 0; i < length; i++) {// 使用String的format方法进行转换 - buf.append(String.format("%02x", new Integer(bytes[i] & 0xFF))); - } - return buf.toString(); + runOnUiThread(() -> mReceLogAdapter.notifyDataSetChanged()); } public void disconnect(View view) { - mNettyTcpClient.disconnect(); + NSDNettyManager.getInstance().disconnect(); } } diff --git a/app/src/main/java/com/mogo/cloud/netty/server/NettyServerActivity.java b/app/src/main/java/com/mogo/cloud/netty/server/NettyServerActivity.java index c4ebc2e..d43de80 100644 --- a/app/src/main/java/com/mogo/cloud/netty/server/NettyServerActivity.java +++ b/app/src/main/java/com/mogo/cloud/netty/server/NettyServerActivity.java @@ -2,9 +2,7 @@ package com.mogo.cloud.netty.server; import static android.widget.Toast.LENGTH_SHORT; -import android.net.nsd.NsdServiceInfo; import android.os.Bundle; -import android.text.TextUtils; import android.util.Log; import android.view.View; import android.widget.AdapterView; @@ -20,21 +18,19 @@ import androidx.recyclerview.widget.RecyclerView; import com.mogo.cloud.R; import com.mogo.cloud.netty.LogBean; +import com.mogo.telematic.NSDNettyManager; import com.mogo.telematic.NetworkUtils; -import com.mogo.telematic.server.NSDServer; import com.mogo.telematic.server.bean.ClientChanel; import com.mogo.telematic.server.netty.NettyServerListener; -import com.mogo.telematic.server.netty.NettyTcpServer; import java.lang.reflect.Field; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import io.netty.channel.Channel; -import io.netty.channel.ChannelFuture; -import io.netty.channel.ChannelFutureListener; -public class NettyServerActivity extends AppCompatActivity implements View.OnClickListener, NettyServerListener { +public class NettyServerActivity extends AppCompatActivity implements View.OnClickListener, NettyServerListener { private static final String TAG = "NettyServerActivity"; @@ -54,7 +50,7 @@ public class NettyServerActivity extends AppCompatActivity implements View.OnCli private CustomSpinnerAdapter spinnerAdapter; private TextView mIpView; - private NSDServer mNsdServer; + private final byte[] sendByte = new byte[]{0x55, 0x54, 0x72, 0x21}; @Override protected void onCreate(Bundle savedInstanceState) { @@ -76,12 +72,12 @@ public class NettyServerActivity extends AppCompatActivity implements View.OnCli public void onItemSelected(AdapterView parent, View view, int position, long id) { ClientChanel clientChanel = spinnerAdapter.getItem(position); Toast.makeText(NettyServerActivity.this, "onItemSelected:" + clientChanel.getClientIp(), Toast.LENGTH_LONG).show(); - NettyTcpServer.getInstance().selectorChannel(clientChanel.getChannel()); + NSDNettyManager.getInstance().selectChannel(clientChanel.getChannel()); } @Override public void onNothingSelected(AdapterView parent) { - NettyTcpServer.getInstance().selectorChannel(null); + NSDNettyManager.getInstance().selectChannel(null); Toast.makeText(NettyServerActivity.this, "onNothingSelected", Toast.LENGTH_LONG).show(); } }); @@ -95,7 +91,6 @@ public class NettyServerActivity extends AppCompatActivity implements View.OnCli LinearLayoutManager manager2 = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false); mReceList.setLayoutManager(manager2); mReceList.setAdapter(mReceLogAdapter); - } private void findViews() { @@ -112,6 +107,7 @@ public class NettyServerActivity extends AppCompatActivity implements View.OnCli startServer.setOnClickListener(this); mSendBtn.setOnClickListener(this); mClearLog.setOnClickListener(this); + mSendET.setText(Arrays.toString(sendByte)); } @Override @@ -124,29 +120,22 @@ public class NettyServerActivity extends AppCompatActivity implements View.OnCli public void onClick(View v) { switch (v.getId()) { case R.id.startServer: - startServer(); + NSDNettyManager.getInstance().startNSDNettyServer(this, this); break; case R.id.send_btn: - if (!NettyTcpServer.getInstance().isServerStart()) { + if (!NSDNettyManager.getInstance().isServerStart()) { Toast.makeText(getApplicationContext(), "未连接,请先连接", LENGTH_SHORT).show(); } else { - final String msg = mSendET.getText().toString(); - if (TextUtils.isEmpty(msg.trim())) { - return; - } - NettyTcpServer.getInstance().sendMsgToServer(msg, new ChannelFutureListener() { - @Override - public void operationComplete(ChannelFuture channelFuture) throws Exception { - if (channelFuture.isSuccess()) { //4 - Log.d(TAG, "Write auth successful"); - logSend(msg); - } else { - Log.d(TAG, "Write auth error"); - } + NSDNettyManager.getInstance().sendByteArrayToClient(sendByte, channelFuture -> { + if (channelFuture.isSuccess()) { + Log.d(TAG, "Write auth successful"); + logSend(Arrays.toString(sendByte)); + } else { + Log.d(TAG, "Write auth error"); } }); - mSendET.setText(""); + mSendET.setText(Arrays.toString(sendByte)); } break; @@ -159,26 +148,13 @@ public class NettyServerActivity extends AppCompatActivity implements View.OnCli } } - private void startServer() { - NettyTcpServer nettyTcpServer = NettyTcpServer.getInstance(); -// nettyTcpServer.setPacketSeparator("#"); - if (!nettyTcpServer.isServerStart()) { - nettyTcpServer.setListener(NettyServerActivity.this); - - nettyTcpServer.start(); - } else { - NettyTcpServer.getInstance().disconnect(); - } - } - - private void registerNsdServer() { - new Thread(nsdServerRunnable).start(); - } - @Override - public void onMessageResponseServer(String msg, String uniqueId) { -// Log.e(TAG,"onMessageResponseServer:ChannelId:"+uniqueId); - logRece(msg); + public void onMessageResponseServer(byte[] msg, String uniqueId) { + Log.e(TAG,"onMessageResponseServer:ChannelId:"+uniqueId); + + String result = Arrays.toString(msg); + Log.e(TAG, "onMessageResponse:" + result); + logRece(result); } @Override @@ -189,12 +165,9 @@ public class NettyServerActivity extends AppCompatActivity implements View.OnCli synchronized (clientChanelArray) { clientChanelArray.add(clientChanel); - runOnUiThread(new Runnable() { - @Override - public void run() { - Toast.makeText(NettyServerActivity.this, clientChanel.getClientIp() + " 建立连接", Toast.LENGTH_LONG).show(); - spinnerAdapter.notifyDataSetChanged(); - } + runOnUiThread(() -> { + Toast.makeText(NettyServerActivity.this, clientChanel.getClientIp() + " 建立连接", Toast.LENGTH_LONG).show(); + spinnerAdapter.notifyDataSetChanged(); }); } @@ -223,13 +196,10 @@ public class NettyServerActivity extends AppCompatActivity implements View.OnCli synchronized (clientChanelArray) { clientChanelArray.remove(clientChanel); - runOnUiThread(new Runnable() { - @Override - public void run() { - Log.e(TAG, "disconncect " + clientChanel.getClientIp()); - Toast.makeText(NettyServerActivity.this, clientChanel.getClientIp() + " 断开连接", Toast.LENGTH_LONG).show(); - spinnerAdapter.notifyDataSetChanged(); - } + runOnUiThread(() -> { + Log.e(TAG, "disconncect " + clientChanel.getClientIp()); + Toast.makeText(NettyServerActivity.this, clientChanel.getClientIp() + " 断开连接", Toast.LENGTH_LONG).show(); + spinnerAdapter.notifyDataSetChanged(); }); } @@ -241,84 +211,25 @@ public class NettyServerActivity extends AppCompatActivity implements View.OnCli @Override public void onStartServer() { - registerNsdServer(); Log.e(TAG, "onStartServer"); - runOnUiThread(new Runnable() { - @Override - public void run() { - startServer.setText("stopServer"); - } - }); + runOnUiThread(() -> startServer.setText("stopServer")); } @Override public void onStopServer() { Log.e(TAG, "onStopServer"); - if (mNsdServer != null) { - mNsdServer.stopNSDServer(); - } - runOnUiThread(new Runnable() { - @Override - public void run() { - startServer.setText("startServer"); - } - }); + runOnUiThread(() -> startServer.setText("startServer")); } - private void logSend(String log) { LogBean logBean = new LogBean(System.currentTimeMillis(), log); mSendLogAdapter.getDataList().add(0, logBean); - runOnUiThread(new Runnable() { - @Override - public void run() { - mSendLogAdapter.notifyDataSetChanged(); - } - }); - + runOnUiThread(() -> mSendLogAdapter.notifyDataSetChanged()); } private void logRece(String log) { LogBean logBean = new LogBean(System.currentTimeMillis(), log); mReceLogAdapter.getDataList().add(0, logBean); - runOnUiThread(new Runnable() { - @Override - public void run() { - mReceLogAdapter.notifyDataSetChanged(); - } - }); + runOnUiThread(() -> mReceLogAdapter.notifyDataSetChanged()); } - - /** - * 服务器端注册一个可供NSD探测到的网络 Ip 地址,便于给展示叫号机连接此socket - */ - Runnable nsdServerRunnable = new Runnable() { - @Override - public void run() { - - mNsdServer = new NSDServer(); - mNsdServer.startNSDServer(NettyServerActivity.this, NettyTcpServer.SERVER_NAME, NettyTcpServer.SERVER_PORT); - - mNsdServer.setRegisterState(new NSDServer.IRegisterState() { - @Override - public void onServiceRegistered(NsdServiceInfo serviceInfo) { - Log.i(TAG, "已注册服务onServiceRegistered: " + serviceInfo.toString()); - //已经注册可停止该服务 -// nsdServer.stopNSDServer(); - } - @Override - public void onRegistrationFailed(NsdServiceInfo serviceInfo, int errorCode) { - - } - @Override - public void onServiceUnregistered(NsdServiceInfo serviceInfo) { - - } - @Override - public void onUnregistrationFailed(NsdServiceInfo serviceInfo, int errorCode) { - - } - }); - } - }; } diff --git a/libraries/mogo-telematic/src/main/AndroidManifest.xml b/libraries/mogo-telematic/src/main/AndroidManifest.xml index 1644871..45436c0 100644 --- a/libraries/mogo-telematic/src/main/AndroidManifest.xml +++ b/libraries/mogo-telematic/src/main/AndroidManifest.xml @@ -1,8 +1,15 @@ + - - + + + + + + + \ No newline at end of file diff --git a/libraries/mogo-telematic/src/main/java/com/mogo/telematic/NSDNettyManager.java b/libraries/mogo-telematic/src/main/java/com/mogo/telematic/NSDNettyManager.java new file mode 100644 index 0000000..36230c6 --- /dev/null +++ b/libraries/mogo-telematic/src/main/java/com/mogo/telematic/NSDNettyManager.java @@ -0,0 +1,256 @@ +package com.mogo.telematic; + +import android.content.Context; +import android.content.Intent; +import android.net.nsd.NsdServiceInfo; +import android.util.Log; + +import com.mogo.telematic.client.NettyTcpClient; +import com.mogo.telematic.client.NsdClient; +import com.mogo.telematic.client.listener.MessageStateListener; +import com.mogo.telematic.client.listener.NettyClientListener; +import com.mogo.telematic.server.NSDServer; +import com.mogo.telematic.server.NettyServerService; +import com.mogo.telematic.server.bean.ClientChanel; +import com.mogo.telematic.server.netty.NettyServerListener; +import com.mogo.telematic.server.netty.NettyTcpServer; + +import io.netty.channel.Channel; +import io.netty.channel.ChannelFutureListener; + + +public class NSDNettyManager { + + private static final String TAG = "NSDNettyManager"; + + private volatile static NSDNettyManager sInstance; + // client端用来过滤的 + public static final String SERVER_NAME = "NSD_SERVER"; + private NSDServer mNsdServer; + private NettyTcpClient mNettyTcpClient; + private NsdClient mNsdClient; + private Context mContext; + private NettyServerListener mListener; + + private NSDNettyManager() { + } + + public static NSDNettyManager getInstance() { + if (sInstance == null) { + synchronized (NSDNettyManager.class) { + if (sInstance == null) { + sInstance = new NSDNettyManager(); + } + } + } + return sInstance; + } + + private NettyServerListener mDefaultListener = new NettyServerListener() { + @Override + public void onMessageResponseServer(Object msg, String ChannelId) { + + } + + @Override + public void onStartServer() { + registerNsdServer(); + if (mListener != null) { + mListener.onStartServer(); + } + } + + @Override + public void onStopServer() { + if (mNsdServer != null) { + mNsdServer.stopNSDServer(); + } + if (mListener != null) { + mListener.onStopServer(); + } + } + + @Override + public void onChannelConnect(Channel channel) { + if (mListener != null) { + mListener.onChannelConnect(channel); + } + } + + @Override + public void onChannelDisConnect(Channel channel) { + if (mListener != null) { + mListener.onChannelDisConnect(channel); + } + } + }; + + /** + * 启动Netty和NSD服务的Server端 + * @param context + * @param listener + */ + public void startNSDNettyServer(Context context, NettyServerListener listener) { + if (context == null) { + throw new RuntimeException("Context must not be null!"); + } else { + mContext = context; + } + mListener = listener; + NettyTcpServer nettyTcpServer = NettyTcpServer.getInstance(); + if (!nettyTcpServer.isServerStart()) { + nettyTcpServer.setListener(mDefaultListener); + nettyTcpServer.start(); + } else { + NettyTcpServer.getInstance().disconnect(); + } + } + + public boolean isServerStart() { + return NettyTcpServer.getInstance().isServerStart(); + } + + public void sendByteArrayToClient(byte[] byteArray, ChannelFutureListener listener) { + NettyTcpServer.getInstance().sendMsgToClient(byteArray, listener); + } + + /** + * 服务器端注册一个可供NSD探测到的网络 Ip 地址,便于给展示叫号机连接此socket + */ + private Runnable mNsdServerRunnable = new Runnable() { + @Override + public void run() { + if (mNsdServer == null) { + mNsdServer = new NSDServer(); + } + mNsdServer.startNSDServer(mContext, NettyTcpServer.SERVER_NAME, NettyTcpServer.SERVER_PORT); + + mNsdServer.setRegisterState(new NSDServer.IRegisterState() { + @Override + public void onServiceRegistered(NsdServiceInfo serviceInfo) { + Log.i(TAG, "已注册服务onServiceRegistered: " + serviceInfo.toString()); + //已经注册可停止该服务 +// nsdServer.stopNSDServer(); + } + @Override + public void onRegistrationFailed(NsdServiceInfo serviceInfo, int errorCode) { + + } + @Override + public void onServiceUnregistered(NsdServiceInfo serviceInfo) { + + } + @Override + public void onUnRegistrationFailed(NsdServiceInfo serviceInfo, int errorCode) { + + } + }); + } + }; + + private void registerNsdServer() { + new Thread(mNsdServerRunnable).start(); + } + + /** + * 选择连接的Client端的channel + * @param channel + */ + public void selectChannel(Channel channel) { + NettyTcpServer.getInstance().selectorChannel(channel); + } + + /** + * 搜索并连接Netty服务端 + * @param context + */ + public void searchAndConnectServer(Context context, NettyClientListener listener) { + if (mNsdClient == null) { + mNsdClient = new NsdClient(context, SERVER_NAME, new NsdClient.IServerFound() { + @Override + public void onServerFound(NsdServiceInfo info, int port) { + if (info != null) { + String hostAddress = info.getHost().getHostAddress(); + Log.d(TAG, "NSD查询到指定服务器信息ip为:" + hostAddress + ",port为:" + port); + //获取到指定的地址,进行Netty的连接 + connectNettyServer(hostAddress, port, listener); + + if (info.getServiceName().equals(SERVER_NAME)) { + //扫描到以后停止 + mNsdClient.stopServiceDiscovery(); + } + } + } + + @Override + public void onServerFail() { + + } + }); + } + mNsdClient.startNSDClient(); + } + + private void connectNettyServer(String serverAddress, int port, NettyClientListener listener) { + Log.d(TAG, "connectNettyServer"); + if (serverAddress == null || serverAddress.length() == 0) { + Log.e(TAG, "Netty Server的ip不能为空!"); + return; + } + if (mNettyTcpClient == null) { + mNettyTcpClient = new NettyTcpClient.Builder() + .setHost(serverAddress) //设置服务端地址 + .setTcpPort(port) //设置服务端端口号 + .setMaxReconnectTimes(5) //设置最大重连次数 + .setReconnectIntervalTime(5) //设置重连间隔时间。单位:秒 + .setSendHeartBeat(true) //设置是否发送心跳 + .setHeartBeatInterval(5) //设置心跳间隔时间。单位:秒 + .setHeartBeatData(new byte[]{0x00, 0x00, 0x00, 0x00}) //设置心跳数据,可以是String类型,也可以是byte[],以后设置的为准 + .setIndex(0) //设置客户端标识.(因为可能存在多个tcp连接) +// .setPacketSeparator("#")//用特殊字符,作为分隔符,解决粘包问题,默认是用换行符作为分隔符 +// .setMaxPacketLong(1024)//设置一次发送数据的最大长度,默认是1024,最大值为Integer.MAX + .build(); + if (listener != null) { + mNettyTcpClient.setListener(listener); //设置TCP监听 + } + } + + if (!mNettyTcpClient.getConnectStatus()) { + mNettyTcpClient.connect();//连接服务器 + } else { + mNettyTcpClient.disconnect(); + } + } + + public boolean getConnectStatus() { + return mNettyTcpClient.getConnectStatus(); + } + + /** + * 发送byte[]到服务端 + * @param byteArray + * @param listener + */ + public void sendByteArrayToServer(byte[] byteArray, final MessageStateListener listener) { + if (mNettyTcpClient != null) { + mNettyTcpClient.sendMsgToServer(byteArray, listener); + } + } + + public static String bytesToHexFun(byte[] bytes, int length) { + StringBuilder buf = new StringBuilder(length * 2); + for (int i = 0; i < length; i++) {// 使用String的format方法进行转换 + buf.append(String.format("%02x", new Integer(bytes[i] & 0xFF))); + } + return buf.toString(); + } + + /** + * 断开Netty连接 + */ + public void disconnect() { + if (mNettyTcpClient != null) { + mNettyTcpClient.disconnect(); + } + } +} diff --git a/libraries/mogo-telematic/src/main/java/com/mogo/telematic/client/NettyTcpClient.java b/libraries/mogo-telematic/src/main/java/com/mogo/telematic/client/NettyTcpClient.java index df4926f..ac38e9f 100644 --- a/libraries/mogo-telematic/src/main/java/com/mogo/telematic/client/NettyTcpClient.java +++ b/libraries/mogo-telematic/src/main/java/com/mogo/telematic/client/NettyTcpClient.java @@ -153,20 +153,7 @@ public class NettyTcpClient { if (isSendheartBeat) { ch.pipeline().addLast("ping", new IdleStateHandler(0, heartBeatInterval, 0, TimeUnit.SECONDS));//5s未发送数据,回调userEventTriggered } - - //黏包处理,需要客户端、服务端配合 - if (!TextUtils.isEmpty(packetSeparator)) { - ByteBuf delimiter= Unpooled.buffer(); - delimiter.writeBytes(packetSeparator.getBytes()); - ch.pipeline().addLast(new DelimiterBasedFrameDecoder(maxPacketLong,delimiter)); - } else { - ch.pipeline().addLast(new LineBasedFrameDecoder(maxPacketLong)); - } - ch.pipeline().addLast(new StringEncoder(CharsetUtil.UTF_8)); - ch.pipeline().addLast(new StringDecoder(CharsetUtil.UTF_8)); - - - ch.pipeline().addLast(new NettyClientHandler(listener, mIndex, isSendheartBeat, heartBeatData,packetSeparator)); + ch.pipeline().addLast(new NettyClientHandler(listener, mIndex, isSendheartBeat, heartBeatData, packetSeparator)); } }); @@ -272,14 +259,12 @@ public class NettyTcpClient { return false; } - public boolean sendMsgToServer(byte[] data, final MessageStateListener listener) { boolean flag = channel != null && isConnect; if (flag) { ByteBuf buf = Unpooled.copiedBuffer(data); - channel.writeAndFlush(buf).addListener(new ChannelFutureListener() { - @Override - public void operationComplete(ChannelFuture channelFuture) throws Exception { + channel.writeAndFlush(buf).addListener((ChannelFutureListener) channelFuture -> { + if (listener != null) { listener.isSendSuccss(channelFuture.isSuccess()); } }); @@ -408,7 +393,7 @@ public class NettyTcpClient { return this; } - public Builder setSendheartBeat(boolean isSendheartBeat) { + public Builder setSendHeartBeat(boolean isSendheartBeat) { this.isSendheartBeat = isSendheartBeat; return this; } diff --git a/libraries/mogo-telematic/src/main/java/com/mogo/telematic/client/NsdClient.java b/libraries/mogo-telematic/src/main/java/com/mogo/telematic/client/NsdClient.java index e54421e..72ff638 100644 --- a/libraries/mogo-telematic/src/main/java/com/mogo/telematic/client/NsdClient.java +++ b/libraries/mogo-telematic/src/main/java/com/mogo/telematic/client/NsdClient.java @@ -168,13 +168,13 @@ public class NsdClient { Message msg = Message.obtain(); msg.what = MSG_RESOLVER; msg.obj = serviceInfo; - mHandler.sendMessageDelayed(msg, 500); + mHandler.sendMessageDelayed(msg, 200); } }; } - public void stopNSDServer() { + public void stopServiceDiscovery() { mNsdManager.stopServiceDiscovery(mDiscoveryListener); } diff --git a/libraries/mogo-telematic/src/main/java/com/mogo/telematic/client/handler/NettyClientHandler.java b/libraries/mogo-telematic/src/main/java/com/mogo/telematic/client/handler/NettyClientHandler.java index 0f80c96..0677506 100644 --- a/libraries/mogo-telematic/src/main/java/com/mogo/telematic/client/handler/NettyClientHandler.java +++ b/libraries/mogo-telematic/src/main/java/com/mogo/telematic/client/handler/NettyClientHandler.java @@ -6,6 +6,8 @@ import android.util.Log; import com.mogo.telematic.client.listener.NettyClientListener; import com.mogo.telematic.client.status.ConnectState; +import java.io.UnsupportedEncodingException; + import io.netty.buffer.ByteBuf; import io.netty.buffer.Unpooled; import io.netty.channel.ChannelHandlerContext; @@ -14,7 +16,7 @@ import io.netty.handler.timeout.IdleState; import io.netty.handler.timeout.IdleStateEvent; -public class NettyClientHandler extends SimpleChannelInboundHandler { +public class NettyClientHandler extends SimpleChannelInboundHandler { private static final String TAG = "NettyClientHandler"; private final boolean isSendheartBeat; @@ -29,10 +31,10 @@ public class NettyClientHandler extends SimpleChannelInboundHandler { public NettyClientHandler(NettyClientListener listener, int index, boolean isSendheartBeat, Object heartBeatData) { - this(listener,index,isSendheartBeat,heartBeatData,null); + this(listener, index, isSendheartBeat, heartBeatData, null); } - public NettyClientHandler(NettyClientListener listener, int index, boolean isSendheartBeat, Object heartBeatData,String separator) { + public NettyClientHandler(NettyClientListener listener, int index, boolean isSendheartBeat, Object heartBeatData, String separator) { this.listener = listener; this.index = index; this.isSendheartBeat = isSendheartBeat; @@ -55,18 +57,13 @@ public class NettyClientHandler extends SimpleChannelInboundHandler { // ctx.channel().writeAndFlush("Heartbeat" + System.getProperty("line.separator")); if (isSendheartBeat) { if (heartBeatData == null) { - ctx.channel().writeAndFlush("Heartbeat" + packetSeparator); + ByteBuf buf = Unpooled.copiedBuffer(requestBody); + ctx.channel().writeAndFlush(buf); + } else if (heartBeatData instanceof byte[]) { + ByteBuf buf = Unpooled.copiedBuffer((byte[]) heartBeatData); + ctx.channel().writeAndFlush(buf); } 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"); - } + Log.e(TAG, "userEventTriggered: heartBeatData type error"); } } else { Log.e(TAG, "不发送心跳"); @@ -107,9 +104,18 @@ public class NettyClientHandler extends SimpleChannelInboundHandler { * @param msg 消息 */ @Override - protected void channelRead0(ChannelHandlerContext channelHandlerContext, String msg) { - Log.e(TAG, "channelRead0:"+msg); - listener.onMessageResponseClient(msg, index); + protected void channelRead0(ChannelHandlerContext channelHandlerContext, Object msg) { + Log.e(TAG, "channelRead0:" + msg); + try { + ByteBuf buf = (ByteBuf) msg; + byte[] bytes = new byte[buf.readableBytes()]; + buf.readBytes(bytes); + String result = new String(bytes, "utf-8"); + Log.e(TAG, "Server: " + result); + listener.onMessageResponseClient(bytes, index); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } } /** 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 index f71f670..a0e326f 100644 --- 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 @@ -10,9 +10,6 @@ public class 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() { @@ -38,7 +35,7 @@ public class NSDServer { public void onUnregistrationFailed(NsdServiceInfo serviceInfo, int errorCode) { Log.i(TAG, "onUnregistrationFailed serviceInfo: " + serviceInfo + " ,errorCode:" + errorCode); if (registerState != null) { - registerState.onUnregistrationFailed(serviceInfo, errorCode); + registerState.onUnRegistrationFailed(serviceInfo, errorCode); } } @@ -84,8 +81,7 @@ public class NSDServer { void onServiceUnregistered(NsdServiceInfo serviceInfo); //取消NSD注册成功 - void onUnregistrationFailed(NsdServiceInfo serviceInfo, int errorCode); //取消NSD注册失败 - + void onUnRegistrationFailed(NsdServiceInfo serviceInfo, int errorCode); //取消NSD注册失败 } //NSD服务接口对象 diff --git a/libraries/mogo-telematic/src/main/java/com/mogo/telematic/server/NettyServerService.java b/libraries/mogo-telematic/src/main/java/com/mogo/telematic/server/NettyServerService.java new file mode 100644 index 0000000..d2634ff --- /dev/null +++ b/libraries/mogo-telematic/src/main/java/com/mogo/telematic/server/NettyServerService.java @@ -0,0 +1,65 @@ +package com.mogo.telematic.server; + +import android.app.Service; +import android.content.Intent; +import android.os.IBinder; + +import com.mogo.telematic.server.netty.NettyServerListener; +import com.mogo.telematic.server.netty.NettyTcpServer; + +import io.netty.channel.Channel; + +public class NettyServerService extends Service { + + @Override + public void onCreate() { + super.onCreate(); + } + + @Override + public int onStartCommand(Intent intent, int flags, int startId) { +// NettyTcpServer nettyTcpServer = NettyTcpServer.getInstance(); +// if (!nettyTcpServer.isServerStart()) { +// nettyTcpServer.setListener(new NettyServerListener() { +// @Override +// public void onMessageResponseServer(Object msg, String ChannelId) { +// +// } +// +// @Override +// public void onStartServer() { +// +// } +// +// @Override +// public void onStopServer() { +// +// } +// +// @Override +// public void onChannelConnect(Channel channel) { +// +// } +// +// @Override +// public void onChannelDisConnect(Channel channel) { +// +// } +// }); +// nettyTcpServer.start(); +// } else { +// NettyTcpServer.getInstance().disconnect(); +// } + return super.onStartCommand(intent, flags, startId); + } + + @Override + public void onDestroy() { + super.onDestroy(); + } + + @Override + public IBinder onBind(Intent intent) { + return null; + } +} \ No newline at end of file