diff --git a/app/src/main/java/com/casic/br/operationsite/extensions/Direction.kt b/app/src/main/java/com/casic/br/operationsite/extensions/Direction.kt index 4774c89..d0b247b 100644 --- a/app/src/main/java/com/casic/br/operationsite/extensions/Direction.kt +++ b/app/src/main/java/com/casic/br/operationsite/extensions/Direction.kt @@ -33,4 +33,12 @@ fun createStopCommand(): ByteArray { return byteArrayOf(0xFF.toByte(), 0x01, 0x00, 0x00, 0x00, 0x00, 0x01) +} + +fun createCloseLightCommand(): ByteArray { + return byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x91.toByte(), 0x00, 0x00, 0x92.toByte()) +} + +fun createOpenLightCommand(): ByteArray { + return byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x91.toByte(), 0x01, 0x00, 0x93.toByte()) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/extensions/Direction.kt b/app/src/main/java/com/casic/br/operationsite/extensions/Direction.kt index 4774c89..d0b247b 100644 --- a/app/src/main/java/com/casic/br/operationsite/extensions/Direction.kt +++ b/app/src/main/java/com/casic/br/operationsite/extensions/Direction.kt @@ -33,4 +33,12 @@ fun createStopCommand(): ByteArray { return byteArrayOf(0xFF.toByte(), 0x01, 0x00, 0x00, 0x00, 0x00, 0x01) +} + +fun createCloseLightCommand(): ByteArray { + return byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x91.toByte(), 0x00, 0x00, 0x92.toByte()) +} + +fun createOpenLightCommand(): ByteArray { + return byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x91.toByte(), 0x01, 0x00, 0x93.toByte()) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt b/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt index e6a213a..c76f73b 100644 --- a/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt +++ b/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt @@ -32,11 +32,6 @@ const val HK_NET_USERNAME = "admin" const val HK_NET_PASSWORD = "1234qwer" const val WIFI_PASSWORD = "zhsz20311hw" - - const val STATUS_CONNECT_SUCCESS = 1 //连接成功 - const val STATUS_CONNECT_CLOSED = 0 //关闭连接 - const val STATUS_CONNECT_ERROR = 0 //连接失败 - - const val CONNECT_SUCCESS = 2023042501 - const val RECONNECT = 2023042502 + const val UDP_HOST = "192.168.31.233" + const val UDP_PORT = 9000 } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/extensions/Direction.kt b/app/src/main/java/com/casic/br/operationsite/extensions/Direction.kt index 4774c89..d0b247b 100644 --- a/app/src/main/java/com/casic/br/operationsite/extensions/Direction.kt +++ b/app/src/main/java/com/casic/br/operationsite/extensions/Direction.kt @@ -33,4 +33,12 @@ fun createStopCommand(): ByteArray { return byteArrayOf(0xFF.toByte(), 0x01, 0x00, 0x00, 0x00, 0x00, 0x01) +} + +fun createCloseLightCommand(): ByteArray { + return byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x91.toByte(), 0x00, 0x00, 0x92.toByte()) +} + +fun createOpenLightCommand(): ByteArray { + return byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x91.toByte(), 0x01, 0x00, 0x93.toByte()) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt b/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt index e6a213a..c76f73b 100644 --- a/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt +++ b/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt @@ -32,11 +32,6 @@ const val HK_NET_USERNAME = "admin" const val HK_NET_PASSWORD = "1234qwer" const val WIFI_PASSWORD = "zhsz20311hw" - - const val STATUS_CONNECT_SUCCESS = 1 //连接成功 - const val STATUS_CONNECT_CLOSED = 0 //关闭连接 - const val STATUS_CONNECT_ERROR = 0 //连接失败 - - const val CONNECT_SUCCESS = 2023042501 - const val RECONNECT = 2023042502 + const val UDP_HOST = "192.168.31.233" + const val UDP_PORT = 9000 } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/utils/netty/ISocketListener.kt b/app/src/main/java/com/casic/br/operationsite/utils/netty/ISocketListener.kt deleted file mode 100644 index f718b89..0000000 --- a/app/src/main/java/com/casic/br/operationsite/utils/netty/ISocketListener.kt +++ /dev/null @@ -1,13 +0,0 @@ -package com.casic.br.operationsite.utils.netty - -interface ISocketListener { - /** - * 当接收到系统消息 - */ - fun onMessageResponse(data: ByteArray) - - /** - * 当连接状态发生变化时调用 - */ - fun onServiceStatusConnectChanged(statusCode: Int) -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/extensions/Direction.kt b/app/src/main/java/com/casic/br/operationsite/extensions/Direction.kt index 4774c89..d0b247b 100644 --- a/app/src/main/java/com/casic/br/operationsite/extensions/Direction.kt +++ b/app/src/main/java/com/casic/br/operationsite/extensions/Direction.kt @@ -33,4 +33,12 @@ fun createStopCommand(): ByteArray { return byteArrayOf(0xFF.toByte(), 0x01, 0x00, 0x00, 0x00, 0x00, 0x01) +} + +fun createCloseLightCommand(): ByteArray { + return byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x91.toByte(), 0x00, 0x00, 0x92.toByte()) +} + +fun createOpenLightCommand(): ByteArray { + return byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x91.toByte(), 0x01, 0x00, 0x93.toByte()) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt b/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt index e6a213a..c76f73b 100644 --- a/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt +++ b/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt @@ -32,11 +32,6 @@ const val HK_NET_USERNAME = "admin" const val HK_NET_PASSWORD = "1234qwer" const val WIFI_PASSWORD = "zhsz20311hw" - - const val STATUS_CONNECT_SUCCESS = 1 //连接成功 - const val STATUS_CONNECT_CLOSED = 0 //关闭连接 - const val STATUS_CONNECT_ERROR = 0 //连接失败 - - const val CONNECT_SUCCESS = 2023042501 - const val RECONNECT = 2023042502 + const val UDP_HOST = "192.168.31.233" + const val UDP_PORT = 9000 } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/utils/netty/ISocketListener.kt b/app/src/main/java/com/casic/br/operationsite/utils/netty/ISocketListener.kt deleted file mode 100644 index f718b89..0000000 --- a/app/src/main/java/com/casic/br/operationsite/utils/netty/ISocketListener.kt +++ /dev/null @@ -1,13 +0,0 @@ -package com.casic.br.operationsite.utils.netty - -interface ISocketListener { - /** - * 当接收到系统消息 - */ - fun onMessageResponse(data: ByteArray) - - /** - * 当连接状态发生变化时调用 - */ - fun onServiceStatusConnectChanged(statusCode: Int) -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/utils/netty/SocketChannelHandle.kt b/app/src/main/java/com/casic/br/operationsite/utils/netty/SocketChannelHandle.kt deleted file mode 100644 index 6f3d8f7..0000000 --- a/app/src/main/java/com/casic/br/operationsite/utils/netty/SocketChannelHandle.kt +++ /dev/null @@ -1,38 +0,0 @@ -package com.casic.br.operationsite.utils.netty - -import android.util.Log -import com.casic.br.operationsite.utils.LocaleConstant -import io.netty.channel.ChannelHandlerContext -import io.netty.channel.SimpleChannelInboundHandler - -class SocketChannelHandle(private val listener: ISocketListener) : - SimpleChannelInboundHandler() { - - private val kTag = "SocketChannelHandle" - - override fun channelActive(ctx: ChannelHandlerContext) { - super.channelActive(ctx) - Log.d(kTag, "channelActive ===> 连接成功") - listener.onServiceStatusConnectChanged(LocaleConstant.STATUS_CONNECT_SUCCESS) - } - - override fun channelInactive(ctx: ChannelHandlerContext) { - super.channelInactive(ctx) - Log.e(kTag, "channelInactive: 连接断开") - listener.onServiceStatusConnectChanged(LocaleConstant.STATUS_CONNECT_ERROR) - } - - override fun channelRead0(ctx: ChannelHandlerContext, data: ByteArray?) { - if (data == null) { - return - } - listener.onMessageResponse(data) - } - - override fun exceptionCaught(ctx: ChannelHandlerContext, cause: Throwable) { - super.exceptionCaught(ctx, cause) - listener.onServiceStatusConnectChanged(LocaleConstant.STATUS_CONNECT_ERROR) - cause.printStackTrace() - ctx.close() - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/extensions/Direction.kt b/app/src/main/java/com/casic/br/operationsite/extensions/Direction.kt index 4774c89..d0b247b 100644 --- a/app/src/main/java/com/casic/br/operationsite/extensions/Direction.kt +++ b/app/src/main/java/com/casic/br/operationsite/extensions/Direction.kt @@ -33,4 +33,12 @@ fun createStopCommand(): ByteArray { return byteArrayOf(0xFF.toByte(), 0x01, 0x00, 0x00, 0x00, 0x00, 0x01) +} + +fun createCloseLightCommand(): ByteArray { + return byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x91.toByte(), 0x00, 0x00, 0x92.toByte()) +} + +fun createOpenLightCommand(): ByteArray { + return byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x91.toByte(), 0x01, 0x00, 0x93.toByte()) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt b/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt index e6a213a..c76f73b 100644 --- a/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt +++ b/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt @@ -32,11 +32,6 @@ const val HK_NET_USERNAME = "admin" const val HK_NET_PASSWORD = "1234qwer" const val WIFI_PASSWORD = "zhsz20311hw" - - const val STATUS_CONNECT_SUCCESS = 1 //连接成功 - const val STATUS_CONNECT_CLOSED = 0 //关闭连接 - const val STATUS_CONNECT_ERROR = 0 //连接失败 - - const val CONNECT_SUCCESS = 2023042501 - const val RECONNECT = 2023042502 + const val UDP_HOST = "192.168.31.233" + const val UDP_PORT = 9000 } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/utils/netty/ISocketListener.kt b/app/src/main/java/com/casic/br/operationsite/utils/netty/ISocketListener.kt deleted file mode 100644 index f718b89..0000000 --- a/app/src/main/java/com/casic/br/operationsite/utils/netty/ISocketListener.kt +++ /dev/null @@ -1,13 +0,0 @@ -package com.casic.br.operationsite.utils.netty - -interface ISocketListener { - /** - * 当接收到系统消息 - */ - fun onMessageResponse(data: ByteArray) - - /** - * 当连接状态发生变化时调用 - */ - fun onServiceStatusConnectChanged(statusCode: Int) -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/utils/netty/SocketChannelHandle.kt b/app/src/main/java/com/casic/br/operationsite/utils/netty/SocketChannelHandle.kt deleted file mode 100644 index 6f3d8f7..0000000 --- a/app/src/main/java/com/casic/br/operationsite/utils/netty/SocketChannelHandle.kt +++ /dev/null @@ -1,38 +0,0 @@ -package com.casic.br.operationsite.utils.netty - -import android.util.Log -import com.casic.br.operationsite.utils.LocaleConstant -import io.netty.channel.ChannelHandlerContext -import io.netty.channel.SimpleChannelInboundHandler - -class SocketChannelHandle(private val listener: ISocketListener) : - SimpleChannelInboundHandler() { - - private val kTag = "SocketChannelHandle" - - override fun channelActive(ctx: ChannelHandlerContext) { - super.channelActive(ctx) - Log.d(kTag, "channelActive ===> 连接成功") - listener.onServiceStatusConnectChanged(LocaleConstant.STATUS_CONNECT_SUCCESS) - } - - override fun channelInactive(ctx: ChannelHandlerContext) { - super.channelInactive(ctx) - Log.e(kTag, "channelInactive: 连接断开") - listener.onServiceStatusConnectChanged(LocaleConstant.STATUS_CONNECT_ERROR) - } - - override fun channelRead0(ctx: ChannelHandlerContext, data: ByteArray?) { - if (data == null) { - return - } - listener.onMessageResponse(data) - } - - override fun exceptionCaught(ctx: ChannelHandlerContext, cause: Throwable) { - super.exceptionCaught(ctx, cause) - listener.onServiceStatusConnectChanged(LocaleConstant.STATUS_CONNECT_ERROR) - cause.printStackTrace() - ctx.close() - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/utils/netty/SocketClient.kt b/app/src/main/java/com/casic/br/operationsite/utils/netty/SocketClient.kt deleted file mode 100644 index 30ce2b8..0000000 --- a/app/src/main/java/com/casic/br/operationsite/utils/netty/SocketClient.kt +++ /dev/null @@ -1,143 +0,0 @@ -package com.casic.br.operationsite.utils.netty - -import android.os.SystemClock -import android.util.Log -import com.casic.br.operationsite.utils.LocaleConstant -import io.netty.bootstrap.Bootstrap -import io.netty.channel.* -import io.netty.channel.nio.NioEventLoopGroup -import io.netty.channel.socket.SocketChannel -import io.netty.channel.socket.nio.NioSocketChannel -import io.netty.handler.codec.bytes.ByteArrayDecoder -import io.netty.handler.codec.bytes.ByteArrayEncoder -import io.netty.handler.timeout.IdleStateHandler - -class SocketClient { - - private val kTag = "SocketClient" - private lateinit var hostname: String - private var port = 0 - private var nioEventLoopGroup: NioEventLoopGroup? = null - private var channel: Channel? = null - private var listener: ISocketListener? = null - private var reconnectNum = Int.MAX_VALUE - private var isNeedReconnect = true - private var isConnecting = false - private var reconnectIntervalTime: Long = 15000 - var connectStatus = false - - fun setSocketListener(listener: ISocketListener?) { - this.listener = listener - } - - fun connect(hostname: String, port: Int) { - this.hostname = hostname - this.port = port - Log.d(kTag, "connect ===> 开始连接TCP服务器") - if (isConnecting) { - return - } - //起个线程 - val clientThread = object : Thread("client-Netty") { - override fun run() { - super.run() - isNeedReconnect = true - reconnectNum = Int.MAX_VALUE - connectServer() - } - } - clientThread.start() - } - - private fun connectServer() { - synchronized(this) { - var channelFuture: ChannelFuture? = null //连接管理对象 - if (!connectStatus) { - isConnecting = true - nioEventLoopGroup = NioEventLoopGroup() //设置的连接group - val bootstrap = Bootstrap() - bootstrap.group(nioEventLoopGroup) //设置的一系列连接参数操作等 - .channel(NioSocketChannel::class.java) - .option(ChannelOption.TCP_NODELAY, true) //无阻塞 - .option(ChannelOption.SO_KEEPALIVE, true) //长连接 - .option( - ChannelOption.RCVBUF_ALLOCATOR, - AdaptiveRecvByteBufAllocator(5000, 5000, 8000) - ) //接收缓冲区 最小值太小时数据接收不全 - .handler(object : ChannelInitializer() { - override fun initChannel(channel: SocketChannel) { - val pipeline = channel.pipeline() - pipeline.addLast(IdleStateHandler(60, 10, 0)) - pipeline.addLast(ByteArrayDecoder()) - pipeline.addLast(ByteArrayEncoder()) - pipeline.addLast(SocketChannelHandle(listener!!)) - } - }) - try { - //连接监听 - channelFuture = bootstrap.connect(hostname, port) - .addListener(object : ChannelFutureListener { - override fun operationComplete(channelFuture: ChannelFuture) { - if (channelFuture.isSuccess) { - connectStatus = true - channel = channelFuture.channel() - } else { - Log.e(kTag, "operationComplete: 连接失败") - connectStatus = false - } - isConnecting = false - } - }).sync() - // 等待连接关闭 - channelFuture.channel().closeFuture().sync() - } catch (e: Exception) { - e.printStackTrace() - } finally { - connectStatus = false - listener?.onServiceStatusConnectChanged(LocaleConstant.STATUS_CONNECT_CLOSED) - if (null != channelFuture) { - if (channelFuture.channel() != null && channelFuture.channel().isOpen) { - channelFuture.channel().close() - } - } - nioEventLoopGroup?.shutdownGracefully() - reconnect() //重新连接 - } - } - } - } - - //断开连接 - fun disconnect() { - Log.d(kTag, "disconnect ===> 断开连接") - isNeedReconnect = false - nioEventLoopGroup?.shutdownGracefully() - } - - //重新连接 - private fun reconnect() { - if (isNeedReconnect && reconnectNum > 0 && !connectStatus) { - reconnectNum-- - SystemClock.sleep(reconnectIntervalTime) - if (isNeedReconnect && reconnectNum > 0 && !connectStatus) { - Log.d(kTag, "reconnect ===> 重新连接") - connectServer() - } - } - } - - fun sendData(bytes: ByteArray) { - if (bytes.isNotEmpty()) { - channel?.writeAndFlush(bytes)?.addListener(ChannelFutureListener { future -> - if (future.isSuccess) { - Log.d(kTag, "sendData ===> 发送成功") - } else { - // 关闭连接,节约资源 - Log.d(kTag, "sendData ===> 关闭连接,节约资源") - future.channel().close() - nioEventLoopGroup?.shutdownGracefully() - } - }) - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/extensions/Direction.kt b/app/src/main/java/com/casic/br/operationsite/extensions/Direction.kt index 4774c89..d0b247b 100644 --- a/app/src/main/java/com/casic/br/operationsite/extensions/Direction.kt +++ b/app/src/main/java/com/casic/br/operationsite/extensions/Direction.kt @@ -33,4 +33,12 @@ fun createStopCommand(): ByteArray { return byteArrayOf(0xFF.toByte(), 0x01, 0x00, 0x00, 0x00, 0x00, 0x01) +} + +fun createCloseLightCommand(): ByteArray { + return byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x91.toByte(), 0x00, 0x00, 0x92.toByte()) +} + +fun createOpenLightCommand(): ByteArray { + return byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x91.toByte(), 0x01, 0x00, 0x93.toByte()) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt b/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt index e6a213a..c76f73b 100644 --- a/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt +++ b/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt @@ -32,11 +32,6 @@ const val HK_NET_USERNAME = "admin" const val HK_NET_PASSWORD = "1234qwer" const val WIFI_PASSWORD = "zhsz20311hw" - - const val STATUS_CONNECT_SUCCESS = 1 //连接成功 - const val STATUS_CONNECT_CLOSED = 0 //关闭连接 - const val STATUS_CONNECT_ERROR = 0 //连接失败 - - const val CONNECT_SUCCESS = 2023042501 - const val RECONNECT = 2023042502 + const val UDP_HOST = "192.168.31.233" + const val UDP_PORT = 9000 } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/utils/netty/ISocketListener.kt b/app/src/main/java/com/casic/br/operationsite/utils/netty/ISocketListener.kt deleted file mode 100644 index f718b89..0000000 --- a/app/src/main/java/com/casic/br/operationsite/utils/netty/ISocketListener.kt +++ /dev/null @@ -1,13 +0,0 @@ -package com.casic.br.operationsite.utils.netty - -interface ISocketListener { - /** - * 当接收到系统消息 - */ - fun onMessageResponse(data: ByteArray) - - /** - * 当连接状态发生变化时调用 - */ - fun onServiceStatusConnectChanged(statusCode: Int) -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/utils/netty/SocketChannelHandle.kt b/app/src/main/java/com/casic/br/operationsite/utils/netty/SocketChannelHandle.kt deleted file mode 100644 index 6f3d8f7..0000000 --- a/app/src/main/java/com/casic/br/operationsite/utils/netty/SocketChannelHandle.kt +++ /dev/null @@ -1,38 +0,0 @@ -package com.casic.br.operationsite.utils.netty - -import android.util.Log -import com.casic.br.operationsite.utils.LocaleConstant -import io.netty.channel.ChannelHandlerContext -import io.netty.channel.SimpleChannelInboundHandler - -class SocketChannelHandle(private val listener: ISocketListener) : - SimpleChannelInboundHandler() { - - private val kTag = "SocketChannelHandle" - - override fun channelActive(ctx: ChannelHandlerContext) { - super.channelActive(ctx) - Log.d(kTag, "channelActive ===> 连接成功") - listener.onServiceStatusConnectChanged(LocaleConstant.STATUS_CONNECT_SUCCESS) - } - - override fun channelInactive(ctx: ChannelHandlerContext) { - super.channelInactive(ctx) - Log.e(kTag, "channelInactive: 连接断开") - listener.onServiceStatusConnectChanged(LocaleConstant.STATUS_CONNECT_ERROR) - } - - override fun channelRead0(ctx: ChannelHandlerContext, data: ByteArray?) { - if (data == null) { - return - } - listener.onMessageResponse(data) - } - - override fun exceptionCaught(ctx: ChannelHandlerContext, cause: Throwable) { - super.exceptionCaught(ctx, cause) - listener.onServiceStatusConnectChanged(LocaleConstant.STATUS_CONNECT_ERROR) - cause.printStackTrace() - ctx.close() - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/utils/netty/SocketClient.kt b/app/src/main/java/com/casic/br/operationsite/utils/netty/SocketClient.kt deleted file mode 100644 index 30ce2b8..0000000 --- a/app/src/main/java/com/casic/br/operationsite/utils/netty/SocketClient.kt +++ /dev/null @@ -1,143 +0,0 @@ -package com.casic.br.operationsite.utils.netty - -import android.os.SystemClock -import android.util.Log -import com.casic.br.operationsite.utils.LocaleConstant -import io.netty.bootstrap.Bootstrap -import io.netty.channel.* -import io.netty.channel.nio.NioEventLoopGroup -import io.netty.channel.socket.SocketChannel -import io.netty.channel.socket.nio.NioSocketChannel -import io.netty.handler.codec.bytes.ByteArrayDecoder -import io.netty.handler.codec.bytes.ByteArrayEncoder -import io.netty.handler.timeout.IdleStateHandler - -class SocketClient { - - private val kTag = "SocketClient" - private lateinit var hostname: String - private var port = 0 - private var nioEventLoopGroup: NioEventLoopGroup? = null - private var channel: Channel? = null - private var listener: ISocketListener? = null - private var reconnectNum = Int.MAX_VALUE - private var isNeedReconnect = true - private var isConnecting = false - private var reconnectIntervalTime: Long = 15000 - var connectStatus = false - - fun setSocketListener(listener: ISocketListener?) { - this.listener = listener - } - - fun connect(hostname: String, port: Int) { - this.hostname = hostname - this.port = port - Log.d(kTag, "connect ===> 开始连接TCP服务器") - if (isConnecting) { - return - } - //起个线程 - val clientThread = object : Thread("client-Netty") { - override fun run() { - super.run() - isNeedReconnect = true - reconnectNum = Int.MAX_VALUE - connectServer() - } - } - clientThread.start() - } - - private fun connectServer() { - synchronized(this) { - var channelFuture: ChannelFuture? = null //连接管理对象 - if (!connectStatus) { - isConnecting = true - nioEventLoopGroup = NioEventLoopGroup() //设置的连接group - val bootstrap = Bootstrap() - bootstrap.group(nioEventLoopGroup) //设置的一系列连接参数操作等 - .channel(NioSocketChannel::class.java) - .option(ChannelOption.TCP_NODELAY, true) //无阻塞 - .option(ChannelOption.SO_KEEPALIVE, true) //长连接 - .option( - ChannelOption.RCVBUF_ALLOCATOR, - AdaptiveRecvByteBufAllocator(5000, 5000, 8000) - ) //接收缓冲区 最小值太小时数据接收不全 - .handler(object : ChannelInitializer() { - override fun initChannel(channel: SocketChannel) { - val pipeline = channel.pipeline() - pipeline.addLast(IdleStateHandler(60, 10, 0)) - pipeline.addLast(ByteArrayDecoder()) - pipeline.addLast(ByteArrayEncoder()) - pipeline.addLast(SocketChannelHandle(listener!!)) - } - }) - try { - //连接监听 - channelFuture = bootstrap.connect(hostname, port) - .addListener(object : ChannelFutureListener { - override fun operationComplete(channelFuture: ChannelFuture) { - if (channelFuture.isSuccess) { - connectStatus = true - channel = channelFuture.channel() - } else { - Log.e(kTag, "operationComplete: 连接失败") - connectStatus = false - } - isConnecting = false - } - }).sync() - // 等待连接关闭 - channelFuture.channel().closeFuture().sync() - } catch (e: Exception) { - e.printStackTrace() - } finally { - connectStatus = false - listener?.onServiceStatusConnectChanged(LocaleConstant.STATUS_CONNECT_CLOSED) - if (null != channelFuture) { - if (channelFuture.channel() != null && channelFuture.channel().isOpen) { - channelFuture.channel().close() - } - } - nioEventLoopGroup?.shutdownGracefully() - reconnect() //重新连接 - } - } - } - } - - //断开连接 - fun disconnect() { - Log.d(kTag, "disconnect ===> 断开连接") - isNeedReconnect = false - nioEventLoopGroup?.shutdownGracefully() - } - - //重新连接 - private fun reconnect() { - if (isNeedReconnect && reconnectNum > 0 && !connectStatus) { - reconnectNum-- - SystemClock.sleep(reconnectIntervalTime) - if (isNeedReconnect && reconnectNum > 0 && !connectStatus) { - Log.d(kTag, "reconnect ===> 重新连接") - connectServer() - } - } - } - - fun sendData(bytes: ByteArray) { - if (bytes.isNotEmpty()) { - channel?.writeAndFlush(bytes)?.addListener(ChannelFutureListener { future -> - if (future.isSuccess) { - Log.d(kTag, "sendData ===> 发送成功") - } else { - // 关闭连接,节约资源 - Log.d(kTag, "sendData ===> 关闭连接,节约资源") - future.channel().close() - nioEventLoopGroup?.shutdownGracefully() - } - }) - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/utils/netty/SocketManager.kt b/app/src/main/java/com/casic/br/operationsite/utils/netty/SocketManager.kt deleted file mode 100644 index c9ff455..0000000 --- a/app/src/main/java/com/casic/br/operationsite/utils/netty/SocketManager.kt +++ /dev/null @@ -1,55 +0,0 @@ -package com.casic.br.operationsite.utils.netty - -import android.util.Log -import com.casic.br.operationsite.utils.LocaleConstant -import com.casic.br.operationsite.view.MethaneActivity - -class SocketManager : ISocketListener { - - companion object { - //Kotlin委托模式双重锁单例 - val get: SocketManager by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) { - SocketManager() - } - } - - private val kTag = "SocketManager" - private val nettyClient by lazy { SocketClient() } - - fun connectNetty(hostname: String, port: Int) { - Thread { - if (!nettyClient.connectStatus) { - nettyClient.setSocketListener(this) - nettyClient.connect(hostname, port) - } else { - nettyClient.disconnect() - } - }.start() - } - - override fun onMessageResponse(data: ByteArray) { - Log.d(kTag, "onMessageResponse <=== " + data.contentToString()) - } - - override fun onServiceStatusConnectChanged(statusCode: Int) { - if (statusCode == LocaleConstant.STATUS_CONNECT_SUCCESS) { - if (nettyClient.connectStatus) { - Log.d(kTag, "连接成功") - MethaneActivity.weakReferenceHandler.sendEmptyMessage(LocaleConstant.CONNECT_SUCCESS) - } - } else { - if (!nettyClient.connectStatus) { - Log.e(kTag, "onServiceStatusConnectChanged:$statusCode,连接断开,正在重连") - MethaneActivity.weakReferenceHandler.sendEmptyMessage(LocaleConstant.RECONNECT) - } - } - } - - fun sendData(data: ByteArray) { - nettyClient.sendData(data) - } - - fun close() { - nettyClient.disconnect() - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/extensions/Direction.kt b/app/src/main/java/com/casic/br/operationsite/extensions/Direction.kt index 4774c89..d0b247b 100644 --- a/app/src/main/java/com/casic/br/operationsite/extensions/Direction.kt +++ b/app/src/main/java/com/casic/br/operationsite/extensions/Direction.kt @@ -33,4 +33,12 @@ fun createStopCommand(): ByteArray { return byteArrayOf(0xFF.toByte(), 0x01, 0x00, 0x00, 0x00, 0x00, 0x01) +} + +fun createCloseLightCommand(): ByteArray { + return byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x91.toByte(), 0x00, 0x00, 0x92.toByte()) +} + +fun createOpenLightCommand(): ByteArray { + return byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x91.toByte(), 0x01, 0x00, 0x93.toByte()) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt b/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt index e6a213a..c76f73b 100644 --- a/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt +++ b/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt @@ -32,11 +32,6 @@ const val HK_NET_USERNAME = "admin" const val HK_NET_PASSWORD = "1234qwer" const val WIFI_PASSWORD = "zhsz20311hw" - - const val STATUS_CONNECT_SUCCESS = 1 //连接成功 - const val STATUS_CONNECT_CLOSED = 0 //关闭连接 - const val STATUS_CONNECT_ERROR = 0 //连接失败 - - const val CONNECT_SUCCESS = 2023042501 - const val RECONNECT = 2023042502 + const val UDP_HOST = "192.168.31.233" + const val UDP_PORT = 9000 } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/utils/netty/ISocketListener.kt b/app/src/main/java/com/casic/br/operationsite/utils/netty/ISocketListener.kt deleted file mode 100644 index f718b89..0000000 --- a/app/src/main/java/com/casic/br/operationsite/utils/netty/ISocketListener.kt +++ /dev/null @@ -1,13 +0,0 @@ -package com.casic.br.operationsite.utils.netty - -interface ISocketListener { - /** - * 当接收到系统消息 - */ - fun onMessageResponse(data: ByteArray) - - /** - * 当连接状态发生变化时调用 - */ - fun onServiceStatusConnectChanged(statusCode: Int) -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/utils/netty/SocketChannelHandle.kt b/app/src/main/java/com/casic/br/operationsite/utils/netty/SocketChannelHandle.kt deleted file mode 100644 index 6f3d8f7..0000000 --- a/app/src/main/java/com/casic/br/operationsite/utils/netty/SocketChannelHandle.kt +++ /dev/null @@ -1,38 +0,0 @@ -package com.casic.br.operationsite.utils.netty - -import android.util.Log -import com.casic.br.operationsite.utils.LocaleConstant -import io.netty.channel.ChannelHandlerContext -import io.netty.channel.SimpleChannelInboundHandler - -class SocketChannelHandle(private val listener: ISocketListener) : - SimpleChannelInboundHandler() { - - private val kTag = "SocketChannelHandle" - - override fun channelActive(ctx: ChannelHandlerContext) { - super.channelActive(ctx) - Log.d(kTag, "channelActive ===> 连接成功") - listener.onServiceStatusConnectChanged(LocaleConstant.STATUS_CONNECT_SUCCESS) - } - - override fun channelInactive(ctx: ChannelHandlerContext) { - super.channelInactive(ctx) - Log.e(kTag, "channelInactive: 连接断开") - listener.onServiceStatusConnectChanged(LocaleConstant.STATUS_CONNECT_ERROR) - } - - override fun channelRead0(ctx: ChannelHandlerContext, data: ByteArray?) { - if (data == null) { - return - } - listener.onMessageResponse(data) - } - - override fun exceptionCaught(ctx: ChannelHandlerContext, cause: Throwable) { - super.exceptionCaught(ctx, cause) - listener.onServiceStatusConnectChanged(LocaleConstant.STATUS_CONNECT_ERROR) - cause.printStackTrace() - ctx.close() - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/utils/netty/SocketClient.kt b/app/src/main/java/com/casic/br/operationsite/utils/netty/SocketClient.kt deleted file mode 100644 index 30ce2b8..0000000 --- a/app/src/main/java/com/casic/br/operationsite/utils/netty/SocketClient.kt +++ /dev/null @@ -1,143 +0,0 @@ -package com.casic.br.operationsite.utils.netty - -import android.os.SystemClock -import android.util.Log -import com.casic.br.operationsite.utils.LocaleConstant -import io.netty.bootstrap.Bootstrap -import io.netty.channel.* -import io.netty.channel.nio.NioEventLoopGroup -import io.netty.channel.socket.SocketChannel -import io.netty.channel.socket.nio.NioSocketChannel -import io.netty.handler.codec.bytes.ByteArrayDecoder -import io.netty.handler.codec.bytes.ByteArrayEncoder -import io.netty.handler.timeout.IdleStateHandler - -class SocketClient { - - private val kTag = "SocketClient" - private lateinit var hostname: String - private var port = 0 - private var nioEventLoopGroup: NioEventLoopGroup? = null - private var channel: Channel? = null - private var listener: ISocketListener? = null - private var reconnectNum = Int.MAX_VALUE - private var isNeedReconnect = true - private var isConnecting = false - private var reconnectIntervalTime: Long = 15000 - var connectStatus = false - - fun setSocketListener(listener: ISocketListener?) { - this.listener = listener - } - - fun connect(hostname: String, port: Int) { - this.hostname = hostname - this.port = port - Log.d(kTag, "connect ===> 开始连接TCP服务器") - if (isConnecting) { - return - } - //起个线程 - val clientThread = object : Thread("client-Netty") { - override fun run() { - super.run() - isNeedReconnect = true - reconnectNum = Int.MAX_VALUE - connectServer() - } - } - clientThread.start() - } - - private fun connectServer() { - synchronized(this) { - var channelFuture: ChannelFuture? = null //连接管理对象 - if (!connectStatus) { - isConnecting = true - nioEventLoopGroup = NioEventLoopGroup() //设置的连接group - val bootstrap = Bootstrap() - bootstrap.group(nioEventLoopGroup) //设置的一系列连接参数操作等 - .channel(NioSocketChannel::class.java) - .option(ChannelOption.TCP_NODELAY, true) //无阻塞 - .option(ChannelOption.SO_KEEPALIVE, true) //长连接 - .option( - ChannelOption.RCVBUF_ALLOCATOR, - AdaptiveRecvByteBufAllocator(5000, 5000, 8000) - ) //接收缓冲区 最小值太小时数据接收不全 - .handler(object : ChannelInitializer() { - override fun initChannel(channel: SocketChannel) { - val pipeline = channel.pipeline() - pipeline.addLast(IdleStateHandler(60, 10, 0)) - pipeline.addLast(ByteArrayDecoder()) - pipeline.addLast(ByteArrayEncoder()) - pipeline.addLast(SocketChannelHandle(listener!!)) - } - }) - try { - //连接监听 - channelFuture = bootstrap.connect(hostname, port) - .addListener(object : ChannelFutureListener { - override fun operationComplete(channelFuture: ChannelFuture) { - if (channelFuture.isSuccess) { - connectStatus = true - channel = channelFuture.channel() - } else { - Log.e(kTag, "operationComplete: 连接失败") - connectStatus = false - } - isConnecting = false - } - }).sync() - // 等待连接关闭 - channelFuture.channel().closeFuture().sync() - } catch (e: Exception) { - e.printStackTrace() - } finally { - connectStatus = false - listener?.onServiceStatusConnectChanged(LocaleConstant.STATUS_CONNECT_CLOSED) - if (null != channelFuture) { - if (channelFuture.channel() != null && channelFuture.channel().isOpen) { - channelFuture.channel().close() - } - } - nioEventLoopGroup?.shutdownGracefully() - reconnect() //重新连接 - } - } - } - } - - //断开连接 - fun disconnect() { - Log.d(kTag, "disconnect ===> 断开连接") - isNeedReconnect = false - nioEventLoopGroup?.shutdownGracefully() - } - - //重新连接 - private fun reconnect() { - if (isNeedReconnect && reconnectNum > 0 && !connectStatus) { - reconnectNum-- - SystemClock.sleep(reconnectIntervalTime) - if (isNeedReconnect && reconnectNum > 0 && !connectStatus) { - Log.d(kTag, "reconnect ===> 重新连接") - connectServer() - } - } - } - - fun sendData(bytes: ByteArray) { - if (bytes.isNotEmpty()) { - channel?.writeAndFlush(bytes)?.addListener(ChannelFutureListener { future -> - if (future.isSuccess) { - Log.d(kTag, "sendData ===> 发送成功") - } else { - // 关闭连接,节约资源 - Log.d(kTag, "sendData ===> 关闭连接,节约资源") - future.channel().close() - nioEventLoopGroup?.shutdownGracefully() - } - }) - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/utils/netty/SocketManager.kt b/app/src/main/java/com/casic/br/operationsite/utils/netty/SocketManager.kt deleted file mode 100644 index c9ff455..0000000 --- a/app/src/main/java/com/casic/br/operationsite/utils/netty/SocketManager.kt +++ /dev/null @@ -1,55 +0,0 @@ -package com.casic.br.operationsite.utils.netty - -import android.util.Log -import com.casic.br.operationsite.utils.LocaleConstant -import com.casic.br.operationsite.view.MethaneActivity - -class SocketManager : ISocketListener { - - companion object { - //Kotlin委托模式双重锁单例 - val get: SocketManager by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) { - SocketManager() - } - } - - private val kTag = "SocketManager" - private val nettyClient by lazy { SocketClient() } - - fun connectNetty(hostname: String, port: Int) { - Thread { - if (!nettyClient.connectStatus) { - nettyClient.setSocketListener(this) - nettyClient.connect(hostname, port) - } else { - nettyClient.disconnect() - } - }.start() - } - - override fun onMessageResponse(data: ByteArray) { - Log.d(kTag, "onMessageResponse <=== " + data.contentToString()) - } - - override fun onServiceStatusConnectChanged(statusCode: Int) { - if (statusCode == LocaleConstant.STATUS_CONNECT_SUCCESS) { - if (nettyClient.connectStatus) { - Log.d(kTag, "连接成功") - MethaneActivity.weakReferenceHandler.sendEmptyMessage(LocaleConstant.CONNECT_SUCCESS) - } - } else { - if (!nettyClient.connectStatus) { - Log.e(kTag, "onServiceStatusConnectChanged:$statusCode,连接断开,正在重连") - MethaneActivity.weakReferenceHandler.sendEmptyMessage(LocaleConstant.RECONNECT) - } - } - } - - fun sendData(data: ByteArray) { - nettyClient.sendData(data) - } - - fun close() { - nettyClient.disconnect() - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/utils/netty/UdpChannelInboundHandler.kt b/app/src/main/java/com/casic/br/operationsite/utils/netty/UdpChannelInboundHandler.kt new file mode 100644 index 0000000..a7f9d27 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/utils/netty/UdpChannelInboundHandler.kt @@ -0,0 +1,36 @@ +package com.casic.br.operationsite.utils.netty + +import io.netty.channel.ChannelHandlerContext +import io.netty.channel.SimpleChannelInboundHandler +import io.netty.channel.socket.DatagramPacket +import io.netty.util.CharsetUtil + + +abstract class UdpChannelInboundHandler : SimpleChannelInboundHandler() { + + private var handlerContext: ChannelHandlerContext? = null + + override fun channelActive(ctx: ChannelHandlerContext?) { + super.channelActive(ctx) + handlerContext = ctx + } + + override fun channelInactive(ctx: ChannelHandlerContext?) { + super.channelInactive(ctx) + handlerContext?.close() + } + + fun sendDatagramPacket(obj: Any) { + handlerContext?.writeAndFlush(obj) + } + + fun releasePort() { + handlerContext?.close() + } + + override fun channelRead0(ctx: ChannelHandlerContext, datagramPacket: DatagramPacket) { + receivedMessage(datagramPacket.content().toString(CharsetUtil.UTF_8)) + } + + abstract fun receivedMessage(data: String) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/extensions/Direction.kt b/app/src/main/java/com/casic/br/operationsite/extensions/Direction.kt index 4774c89..d0b247b 100644 --- a/app/src/main/java/com/casic/br/operationsite/extensions/Direction.kt +++ b/app/src/main/java/com/casic/br/operationsite/extensions/Direction.kt @@ -33,4 +33,12 @@ fun createStopCommand(): ByteArray { return byteArrayOf(0xFF.toByte(), 0x01, 0x00, 0x00, 0x00, 0x00, 0x01) +} + +fun createCloseLightCommand(): ByteArray { + return byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x91.toByte(), 0x00, 0x00, 0x92.toByte()) +} + +fun createOpenLightCommand(): ByteArray { + return byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x91.toByte(), 0x01, 0x00, 0x93.toByte()) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt b/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt index e6a213a..c76f73b 100644 --- a/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt +++ b/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt @@ -32,11 +32,6 @@ const val HK_NET_USERNAME = "admin" const val HK_NET_PASSWORD = "1234qwer" const val WIFI_PASSWORD = "zhsz20311hw" - - const val STATUS_CONNECT_SUCCESS = 1 //连接成功 - const val STATUS_CONNECT_CLOSED = 0 //关闭连接 - const val STATUS_CONNECT_ERROR = 0 //连接失败 - - const val CONNECT_SUCCESS = 2023042501 - const val RECONNECT = 2023042502 + const val UDP_HOST = "192.168.31.233" + const val UDP_PORT = 9000 } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/utils/netty/ISocketListener.kt b/app/src/main/java/com/casic/br/operationsite/utils/netty/ISocketListener.kt deleted file mode 100644 index f718b89..0000000 --- a/app/src/main/java/com/casic/br/operationsite/utils/netty/ISocketListener.kt +++ /dev/null @@ -1,13 +0,0 @@ -package com.casic.br.operationsite.utils.netty - -interface ISocketListener { - /** - * 当接收到系统消息 - */ - fun onMessageResponse(data: ByteArray) - - /** - * 当连接状态发生变化时调用 - */ - fun onServiceStatusConnectChanged(statusCode: Int) -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/utils/netty/SocketChannelHandle.kt b/app/src/main/java/com/casic/br/operationsite/utils/netty/SocketChannelHandle.kt deleted file mode 100644 index 6f3d8f7..0000000 --- a/app/src/main/java/com/casic/br/operationsite/utils/netty/SocketChannelHandle.kt +++ /dev/null @@ -1,38 +0,0 @@ -package com.casic.br.operationsite.utils.netty - -import android.util.Log -import com.casic.br.operationsite.utils.LocaleConstant -import io.netty.channel.ChannelHandlerContext -import io.netty.channel.SimpleChannelInboundHandler - -class SocketChannelHandle(private val listener: ISocketListener) : - SimpleChannelInboundHandler() { - - private val kTag = "SocketChannelHandle" - - override fun channelActive(ctx: ChannelHandlerContext) { - super.channelActive(ctx) - Log.d(kTag, "channelActive ===> 连接成功") - listener.onServiceStatusConnectChanged(LocaleConstant.STATUS_CONNECT_SUCCESS) - } - - override fun channelInactive(ctx: ChannelHandlerContext) { - super.channelInactive(ctx) - Log.e(kTag, "channelInactive: 连接断开") - listener.onServiceStatusConnectChanged(LocaleConstant.STATUS_CONNECT_ERROR) - } - - override fun channelRead0(ctx: ChannelHandlerContext, data: ByteArray?) { - if (data == null) { - return - } - listener.onMessageResponse(data) - } - - override fun exceptionCaught(ctx: ChannelHandlerContext, cause: Throwable) { - super.exceptionCaught(ctx, cause) - listener.onServiceStatusConnectChanged(LocaleConstant.STATUS_CONNECT_ERROR) - cause.printStackTrace() - ctx.close() - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/utils/netty/SocketClient.kt b/app/src/main/java/com/casic/br/operationsite/utils/netty/SocketClient.kt deleted file mode 100644 index 30ce2b8..0000000 --- a/app/src/main/java/com/casic/br/operationsite/utils/netty/SocketClient.kt +++ /dev/null @@ -1,143 +0,0 @@ -package com.casic.br.operationsite.utils.netty - -import android.os.SystemClock -import android.util.Log -import com.casic.br.operationsite.utils.LocaleConstant -import io.netty.bootstrap.Bootstrap -import io.netty.channel.* -import io.netty.channel.nio.NioEventLoopGroup -import io.netty.channel.socket.SocketChannel -import io.netty.channel.socket.nio.NioSocketChannel -import io.netty.handler.codec.bytes.ByteArrayDecoder -import io.netty.handler.codec.bytes.ByteArrayEncoder -import io.netty.handler.timeout.IdleStateHandler - -class SocketClient { - - private val kTag = "SocketClient" - private lateinit var hostname: String - private var port = 0 - private var nioEventLoopGroup: NioEventLoopGroup? = null - private var channel: Channel? = null - private var listener: ISocketListener? = null - private var reconnectNum = Int.MAX_VALUE - private var isNeedReconnect = true - private var isConnecting = false - private var reconnectIntervalTime: Long = 15000 - var connectStatus = false - - fun setSocketListener(listener: ISocketListener?) { - this.listener = listener - } - - fun connect(hostname: String, port: Int) { - this.hostname = hostname - this.port = port - Log.d(kTag, "connect ===> 开始连接TCP服务器") - if (isConnecting) { - return - } - //起个线程 - val clientThread = object : Thread("client-Netty") { - override fun run() { - super.run() - isNeedReconnect = true - reconnectNum = Int.MAX_VALUE - connectServer() - } - } - clientThread.start() - } - - private fun connectServer() { - synchronized(this) { - var channelFuture: ChannelFuture? = null //连接管理对象 - if (!connectStatus) { - isConnecting = true - nioEventLoopGroup = NioEventLoopGroup() //设置的连接group - val bootstrap = Bootstrap() - bootstrap.group(nioEventLoopGroup) //设置的一系列连接参数操作等 - .channel(NioSocketChannel::class.java) - .option(ChannelOption.TCP_NODELAY, true) //无阻塞 - .option(ChannelOption.SO_KEEPALIVE, true) //长连接 - .option( - ChannelOption.RCVBUF_ALLOCATOR, - AdaptiveRecvByteBufAllocator(5000, 5000, 8000) - ) //接收缓冲区 最小值太小时数据接收不全 - .handler(object : ChannelInitializer() { - override fun initChannel(channel: SocketChannel) { - val pipeline = channel.pipeline() - pipeline.addLast(IdleStateHandler(60, 10, 0)) - pipeline.addLast(ByteArrayDecoder()) - pipeline.addLast(ByteArrayEncoder()) - pipeline.addLast(SocketChannelHandle(listener!!)) - } - }) - try { - //连接监听 - channelFuture = bootstrap.connect(hostname, port) - .addListener(object : ChannelFutureListener { - override fun operationComplete(channelFuture: ChannelFuture) { - if (channelFuture.isSuccess) { - connectStatus = true - channel = channelFuture.channel() - } else { - Log.e(kTag, "operationComplete: 连接失败") - connectStatus = false - } - isConnecting = false - } - }).sync() - // 等待连接关闭 - channelFuture.channel().closeFuture().sync() - } catch (e: Exception) { - e.printStackTrace() - } finally { - connectStatus = false - listener?.onServiceStatusConnectChanged(LocaleConstant.STATUS_CONNECT_CLOSED) - if (null != channelFuture) { - if (channelFuture.channel() != null && channelFuture.channel().isOpen) { - channelFuture.channel().close() - } - } - nioEventLoopGroup?.shutdownGracefully() - reconnect() //重新连接 - } - } - } - } - - //断开连接 - fun disconnect() { - Log.d(kTag, "disconnect ===> 断开连接") - isNeedReconnect = false - nioEventLoopGroup?.shutdownGracefully() - } - - //重新连接 - private fun reconnect() { - if (isNeedReconnect && reconnectNum > 0 && !connectStatus) { - reconnectNum-- - SystemClock.sleep(reconnectIntervalTime) - if (isNeedReconnect && reconnectNum > 0 && !connectStatus) { - Log.d(kTag, "reconnect ===> 重新连接") - connectServer() - } - } - } - - fun sendData(bytes: ByteArray) { - if (bytes.isNotEmpty()) { - channel?.writeAndFlush(bytes)?.addListener(ChannelFutureListener { future -> - if (future.isSuccess) { - Log.d(kTag, "sendData ===> 发送成功") - } else { - // 关闭连接,节约资源 - Log.d(kTag, "sendData ===> 关闭连接,节约资源") - future.channel().close() - nioEventLoopGroup?.shutdownGracefully() - } - }) - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/utils/netty/SocketManager.kt b/app/src/main/java/com/casic/br/operationsite/utils/netty/SocketManager.kt deleted file mode 100644 index c9ff455..0000000 --- a/app/src/main/java/com/casic/br/operationsite/utils/netty/SocketManager.kt +++ /dev/null @@ -1,55 +0,0 @@ -package com.casic.br.operationsite.utils.netty - -import android.util.Log -import com.casic.br.operationsite.utils.LocaleConstant -import com.casic.br.operationsite.view.MethaneActivity - -class SocketManager : ISocketListener { - - companion object { - //Kotlin委托模式双重锁单例 - val get: SocketManager by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) { - SocketManager() - } - } - - private val kTag = "SocketManager" - private val nettyClient by lazy { SocketClient() } - - fun connectNetty(hostname: String, port: Int) { - Thread { - if (!nettyClient.connectStatus) { - nettyClient.setSocketListener(this) - nettyClient.connect(hostname, port) - } else { - nettyClient.disconnect() - } - }.start() - } - - override fun onMessageResponse(data: ByteArray) { - Log.d(kTag, "onMessageResponse <=== " + data.contentToString()) - } - - override fun onServiceStatusConnectChanged(statusCode: Int) { - if (statusCode == LocaleConstant.STATUS_CONNECT_SUCCESS) { - if (nettyClient.connectStatus) { - Log.d(kTag, "连接成功") - MethaneActivity.weakReferenceHandler.sendEmptyMessage(LocaleConstant.CONNECT_SUCCESS) - } - } else { - if (!nettyClient.connectStatus) { - Log.e(kTag, "onServiceStatusConnectChanged:$statusCode,连接断开,正在重连") - MethaneActivity.weakReferenceHandler.sendEmptyMessage(LocaleConstant.RECONNECT) - } - } - } - - fun sendData(data: ByteArray) { - nettyClient.sendData(data) - } - - fun close() { - nettyClient.disconnect() - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/utils/netty/UdpChannelInboundHandler.kt b/app/src/main/java/com/casic/br/operationsite/utils/netty/UdpChannelInboundHandler.kt new file mode 100644 index 0000000..a7f9d27 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/utils/netty/UdpChannelInboundHandler.kt @@ -0,0 +1,36 @@ +package com.casic.br.operationsite.utils.netty + +import io.netty.channel.ChannelHandlerContext +import io.netty.channel.SimpleChannelInboundHandler +import io.netty.channel.socket.DatagramPacket +import io.netty.util.CharsetUtil + + +abstract class UdpChannelInboundHandler : SimpleChannelInboundHandler() { + + private var handlerContext: ChannelHandlerContext? = null + + override fun channelActive(ctx: ChannelHandlerContext?) { + super.channelActive(ctx) + handlerContext = ctx + } + + override fun channelInactive(ctx: ChannelHandlerContext?) { + super.channelInactive(ctx) + handlerContext?.close() + } + + fun sendDatagramPacket(obj: Any) { + handlerContext?.writeAndFlush(obj) + } + + fun releasePort() { + handlerContext?.close() + } + + override fun channelRead0(ctx: ChannelHandlerContext, datagramPacket: DatagramPacket) { + receivedMessage(datagramPacket.content().toString(CharsetUtil.UTF_8)) + } + + abstract fun receivedMessage(data: String) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/utils/netty/UdpChannelInitializer.kt b/app/src/main/java/com/casic/br/operationsite/utils/netty/UdpChannelInitializer.kt new file mode 100644 index 0000000..bcdeef1 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/utils/netty/UdpChannelInitializer.kt @@ -0,0 +1,17 @@ +package com.casic.br.operationsite.utils.netty + +import io.netty.channel.ChannelInitializer +import io.netty.channel.socket.DatagramChannel +import io.netty.handler.timeout.IdleStateHandler + + +open class UdpChannelInitializer(private val handler: UdpChannelInboundHandler) : + ChannelInitializer() { + + override fun initChannel(datagramChannel: DatagramChannel) { + val pipeline = datagramChannel.pipeline() + pipeline.addLast( + IdleStateHandler(12, 15, 0) + ).addLast(handler) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/extensions/Direction.kt b/app/src/main/java/com/casic/br/operationsite/extensions/Direction.kt index 4774c89..d0b247b 100644 --- a/app/src/main/java/com/casic/br/operationsite/extensions/Direction.kt +++ b/app/src/main/java/com/casic/br/operationsite/extensions/Direction.kt @@ -33,4 +33,12 @@ fun createStopCommand(): ByteArray { return byteArrayOf(0xFF.toByte(), 0x01, 0x00, 0x00, 0x00, 0x00, 0x01) +} + +fun createCloseLightCommand(): ByteArray { + return byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x91.toByte(), 0x00, 0x00, 0x92.toByte()) +} + +fun createOpenLightCommand(): ByteArray { + return byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x91.toByte(), 0x01, 0x00, 0x93.toByte()) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt b/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt index e6a213a..c76f73b 100644 --- a/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt +++ b/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt @@ -32,11 +32,6 @@ const val HK_NET_USERNAME = "admin" const val HK_NET_PASSWORD = "1234qwer" const val WIFI_PASSWORD = "zhsz20311hw" - - const val STATUS_CONNECT_SUCCESS = 1 //连接成功 - const val STATUS_CONNECT_CLOSED = 0 //关闭连接 - const val STATUS_CONNECT_ERROR = 0 //连接失败 - - const val CONNECT_SUCCESS = 2023042501 - const val RECONNECT = 2023042502 + const val UDP_HOST = "192.168.31.233" + const val UDP_PORT = 9000 } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/utils/netty/ISocketListener.kt b/app/src/main/java/com/casic/br/operationsite/utils/netty/ISocketListener.kt deleted file mode 100644 index f718b89..0000000 --- a/app/src/main/java/com/casic/br/operationsite/utils/netty/ISocketListener.kt +++ /dev/null @@ -1,13 +0,0 @@ -package com.casic.br.operationsite.utils.netty - -interface ISocketListener { - /** - * 当接收到系统消息 - */ - fun onMessageResponse(data: ByteArray) - - /** - * 当连接状态发生变化时调用 - */ - fun onServiceStatusConnectChanged(statusCode: Int) -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/utils/netty/SocketChannelHandle.kt b/app/src/main/java/com/casic/br/operationsite/utils/netty/SocketChannelHandle.kt deleted file mode 100644 index 6f3d8f7..0000000 --- a/app/src/main/java/com/casic/br/operationsite/utils/netty/SocketChannelHandle.kt +++ /dev/null @@ -1,38 +0,0 @@ -package com.casic.br.operationsite.utils.netty - -import android.util.Log -import com.casic.br.operationsite.utils.LocaleConstant -import io.netty.channel.ChannelHandlerContext -import io.netty.channel.SimpleChannelInboundHandler - -class SocketChannelHandle(private val listener: ISocketListener) : - SimpleChannelInboundHandler() { - - private val kTag = "SocketChannelHandle" - - override fun channelActive(ctx: ChannelHandlerContext) { - super.channelActive(ctx) - Log.d(kTag, "channelActive ===> 连接成功") - listener.onServiceStatusConnectChanged(LocaleConstant.STATUS_CONNECT_SUCCESS) - } - - override fun channelInactive(ctx: ChannelHandlerContext) { - super.channelInactive(ctx) - Log.e(kTag, "channelInactive: 连接断开") - listener.onServiceStatusConnectChanged(LocaleConstant.STATUS_CONNECT_ERROR) - } - - override fun channelRead0(ctx: ChannelHandlerContext, data: ByteArray?) { - if (data == null) { - return - } - listener.onMessageResponse(data) - } - - override fun exceptionCaught(ctx: ChannelHandlerContext, cause: Throwable) { - super.exceptionCaught(ctx, cause) - listener.onServiceStatusConnectChanged(LocaleConstant.STATUS_CONNECT_ERROR) - cause.printStackTrace() - ctx.close() - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/utils/netty/SocketClient.kt b/app/src/main/java/com/casic/br/operationsite/utils/netty/SocketClient.kt deleted file mode 100644 index 30ce2b8..0000000 --- a/app/src/main/java/com/casic/br/operationsite/utils/netty/SocketClient.kt +++ /dev/null @@ -1,143 +0,0 @@ -package com.casic.br.operationsite.utils.netty - -import android.os.SystemClock -import android.util.Log -import com.casic.br.operationsite.utils.LocaleConstant -import io.netty.bootstrap.Bootstrap -import io.netty.channel.* -import io.netty.channel.nio.NioEventLoopGroup -import io.netty.channel.socket.SocketChannel -import io.netty.channel.socket.nio.NioSocketChannel -import io.netty.handler.codec.bytes.ByteArrayDecoder -import io.netty.handler.codec.bytes.ByteArrayEncoder -import io.netty.handler.timeout.IdleStateHandler - -class SocketClient { - - private val kTag = "SocketClient" - private lateinit var hostname: String - private var port = 0 - private var nioEventLoopGroup: NioEventLoopGroup? = null - private var channel: Channel? = null - private var listener: ISocketListener? = null - private var reconnectNum = Int.MAX_VALUE - private var isNeedReconnect = true - private var isConnecting = false - private var reconnectIntervalTime: Long = 15000 - var connectStatus = false - - fun setSocketListener(listener: ISocketListener?) { - this.listener = listener - } - - fun connect(hostname: String, port: Int) { - this.hostname = hostname - this.port = port - Log.d(kTag, "connect ===> 开始连接TCP服务器") - if (isConnecting) { - return - } - //起个线程 - val clientThread = object : Thread("client-Netty") { - override fun run() { - super.run() - isNeedReconnect = true - reconnectNum = Int.MAX_VALUE - connectServer() - } - } - clientThread.start() - } - - private fun connectServer() { - synchronized(this) { - var channelFuture: ChannelFuture? = null //连接管理对象 - if (!connectStatus) { - isConnecting = true - nioEventLoopGroup = NioEventLoopGroup() //设置的连接group - val bootstrap = Bootstrap() - bootstrap.group(nioEventLoopGroup) //设置的一系列连接参数操作等 - .channel(NioSocketChannel::class.java) - .option(ChannelOption.TCP_NODELAY, true) //无阻塞 - .option(ChannelOption.SO_KEEPALIVE, true) //长连接 - .option( - ChannelOption.RCVBUF_ALLOCATOR, - AdaptiveRecvByteBufAllocator(5000, 5000, 8000) - ) //接收缓冲区 最小值太小时数据接收不全 - .handler(object : ChannelInitializer() { - override fun initChannel(channel: SocketChannel) { - val pipeline = channel.pipeline() - pipeline.addLast(IdleStateHandler(60, 10, 0)) - pipeline.addLast(ByteArrayDecoder()) - pipeline.addLast(ByteArrayEncoder()) - pipeline.addLast(SocketChannelHandle(listener!!)) - } - }) - try { - //连接监听 - channelFuture = bootstrap.connect(hostname, port) - .addListener(object : ChannelFutureListener { - override fun operationComplete(channelFuture: ChannelFuture) { - if (channelFuture.isSuccess) { - connectStatus = true - channel = channelFuture.channel() - } else { - Log.e(kTag, "operationComplete: 连接失败") - connectStatus = false - } - isConnecting = false - } - }).sync() - // 等待连接关闭 - channelFuture.channel().closeFuture().sync() - } catch (e: Exception) { - e.printStackTrace() - } finally { - connectStatus = false - listener?.onServiceStatusConnectChanged(LocaleConstant.STATUS_CONNECT_CLOSED) - if (null != channelFuture) { - if (channelFuture.channel() != null && channelFuture.channel().isOpen) { - channelFuture.channel().close() - } - } - nioEventLoopGroup?.shutdownGracefully() - reconnect() //重新连接 - } - } - } - } - - //断开连接 - fun disconnect() { - Log.d(kTag, "disconnect ===> 断开连接") - isNeedReconnect = false - nioEventLoopGroup?.shutdownGracefully() - } - - //重新连接 - private fun reconnect() { - if (isNeedReconnect && reconnectNum > 0 && !connectStatus) { - reconnectNum-- - SystemClock.sleep(reconnectIntervalTime) - if (isNeedReconnect && reconnectNum > 0 && !connectStatus) { - Log.d(kTag, "reconnect ===> 重新连接") - connectServer() - } - } - } - - fun sendData(bytes: ByteArray) { - if (bytes.isNotEmpty()) { - channel?.writeAndFlush(bytes)?.addListener(ChannelFutureListener { future -> - if (future.isSuccess) { - Log.d(kTag, "sendData ===> 发送成功") - } else { - // 关闭连接,节约资源 - Log.d(kTag, "sendData ===> 关闭连接,节约资源") - future.channel().close() - nioEventLoopGroup?.shutdownGracefully() - } - }) - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/utils/netty/SocketManager.kt b/app/src/main/java/com/casic/br/operationsite/utils/netty/SocketManager.kt deleted file mode 100644 index c9ff455..0000000 --- a/app/src/main/java/com/casic/br/operationsite/utils/netty/SocketManager.kt +++ /dev/null @@ -1,55 +0,0 @@ -package com.casic.br.operationsite.utils.netty - -import android.util.Log -import com.casic.br.operationsite.utils.LocaleConstant -import com.casic.br.operationsite.view.MethaneActivity - -class SocketManager : ISocketListener { - - companion object { - //Kotlin委托模式双重锁单例 - val get: SocketManager by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) { - SocketManager() - } - } - - private val kTag = "SocketManager" - private val nettyClient by lazy { SocketClient() } - - fun connectNetty(hostname: String, port: Int) { - Thread { - if (!nettyClient.connectStatus) { - nettyClient.setSocketListener(this) - nettyClient.connect(hostname, port) - } else { - nettyClient.disconnect() - } - }.start() - } - - override fun onMessageResponse(data: ByteArray) { - Log.d(kTag, "onMessageResponse <=== " + data.contentToString()) - } - - override fun onServiceStatusConnectChanged(statusCode: Int) { - if (statusCode == LocaleConstant.STATUS_CONNECT_SUCCESS) { - if (nettyClient.connectStatus) { - Log.d(kTag, "连接成功") - MethaneActivity.weakReferenceHandler.sendEmptyMessage(LocaleConstant.CONNECT_SUCCESS) - } - } else { - if (!nettyClient.connectStatus) { - Log.e(kTag, "onServiceStatusConnectChanged:$statusCode,连接断开,正在重连") - MethaneActivity.weakReferenceHandler.sendEmptyMessage(LocaleConstant.RECONNECT) - } - } - } - - fun sendData(data: ByteArray) { - nettyClient.sendData(data) - } - - fun close() { - nettyClient.disconnect() - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/utils/netty/UdpChannelInboundHandler.kt b/app/src/main/java/com/casic/br/operationsite/utils/netty/UdpChannelInboundHandler.kt new file mode 100644 index 0000000..a7f9d27 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/utils/netty/UdpChannelInboundHandler.kt @@ -0,0 +1,36 @@ +package com.casic.br.operationsite.utils.netty + +import io.netty.channel.ChannelHandlerContext +import io.netty.channel.SimpleChannelInboundHandler +import io.netty.channel.socket.DatagramPacket +import io.netty.util.CharsetUtil + + +abstract class UdpChannelInboundHandler : SimpleChannelInboundHandler() { + + private var handlerContext: ChannelHandlerContext? = null + + override fun channelActive(ctx: ChannelHandlerContext?) { + super.channelActive(ctx) + handlerContext = ctx + } + + override fun channelInactive(ctx: ChannelHandlerContext?) { + super.channelInactive(ctx) + handlerContext?.close() + } + + fun sendDatagramPacket(obj: Any) { + handlerContext?.writeAndFlush(obj) + } + + fun releasePort() { + handlerContext?.close() + } + + override fun channelRead0(ctx: ChannelHandlerContext, datagramPacket: DatagramPacket) { + receivedMessage(datagramPacket.content().toString(CharsetUtil.UTF_8)) + } + + abstract fun receivedMessage(data: String) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/utils/netty/UdpChannelInitializer.kt b/app/src/main/java/com/casic/br/operationsite/utils/netty/UdpChannelInitializer.kt new file mode 100644 index 0000000..bcdeef1 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/utils/netty/UdpChannelInitializer.kt @@ -0,0 +1,17 @@ +package com.casic.br.operationsite.utils.netty + +import io.netty.channel.ChannelInitializer +import io.netty.channel.socket.DatagramChannel +import io.netty.handler.timeout.IdleStateHandler + + +open class UdpChannelInitializer(private val handler: UdpChannelInboundHandler) : + ChannelInitializer() { + + override fun initChannel(datagramChannel: DatagramChannel) { + val pipeline = datagramChannel.pipeline() + pipeline.addLast( + IdleStateHandler(12, 15, 0) + ).addLast(handler) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/utils/netty/UdpClient.kt b/app/src/main/java/com/casic/br/operationsite/utils/netty/UdpClient.kt new file mode 100644 index 0000000..d9753e0 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/utils/netty/UdpClient.kt @@ -0,0 +1,81 @@ +package com.casic.br.operationsite.utils.netty + +import com.casic.br.operationsite.utils.LocaleConstant +import io.netty.bootstrap.Bootstrap +import io.netty.buffer.ByteBuf +import io.netty.buffer.Unpooled +import io.netty.channel.ChannelFuture +import io.netty.channel.ChannelOption +import io.netty.channel.nio.NioEventLoopGroup +import io.netty.channel.socket.DatagramPacket +import io.netty.channel.socket.nio.NioDatagramChannel +import io.netty.util.CharsetUtil +import java.net.InetSocketAddress +import java.util.concurrent.ExecutorService +import java.util.concurrent.Executors + + +class UdpClient() : UdpChannelInboundHandler(), Runnable { + + private val bootStrap by lazy { Bootstrap() } + private val eventLoopGroup by lazy { NioEventLoopGroup() } + private val udpChannelInitializer by lazy { UdpChannelInitializer(this) } + private var executorService: ExecutorService + + init { + bootStrap.group(eventLoopGroup) + bootStrap.channel(NioDatagramChannel::class.java) + .option(ChannelOption.SO_RCVBUF, 1024) + .option(ChannelOption.SO_SNDBUF, 1024) + bootStrap.handler(udpChannelInitializer) + + executorService = Executors.newSingleThreadExecutor() + executorService.execute(this) + } + + override fun run() { + try { + val channelFuture: ChannelFuture = bootStrap.bind(LocaleConstant.UDP_PORT).sync() + channelFuture.channel().closeFuture().sync() + } catch (e: InterruptedException) { + e.printStackTrace() + } finally { + eventLoopGroup.shutdownGracefully() + } + } + + fun send(value: String) { + val datagramPacket = DatagramPacket( + Unpooled.copiedBuffer(value, CharsetUtil.UTF_8), + InetSocketAddress(LocaleConstant.UDP_HOST, LocaleConstant.UDP_PORT) + ) + + sendDatagramPacket(datagramPacket) + } + + fun send(value: ByteArray) { + val datagramPacket = DatagramPacket( + Unpooled.copiedBuffer(value), + InetSocketAddress(LocaleConstant.UDP_HOST, LocaleConstant.UDP_PORT) + ) + + sendDatagramPacket(datagramPacket) + } + + fun send(value: ByteBuf) { + val datagramPacket = DatagramPacket( + Unpooled.copiedBuffer(value), + InetSocketAddress(LocaleConstant.UDP_HOST, LocaleConstant.UDP_PORT) + ) + + sendDatagramPacket(datagramPacket) + } + + fun release() { + releasePort() + } + + override fun receivedMessage(data: String) { + + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/extensions/Direction.kt b/app/src/main/java/com/casic/br/operationsite/extensions/Direction.kt index 4774c89..d0b247b 100644 --- a/app/src/main/java/com/casic/br/operationsite/extensions/Direction.kt +++ b/app/src/main/java/com/casic/br/operationsite/extensions/Direction.kt @@ -33,4 +33,12 @@ fun createStopCommand(): ByteArray { return byteArrayOf(0xFF.toByte(), 0x01, 0x00, 0x00, 0x00, 0x00, 0x01) +} + +fun createCloseLightCommand(): ByteArray { + return byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x91.toByte(), 0x00, 0x00, 0x92.toByte()) +} + +fun createOpenLightCommand(): ByteArray { + return byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x91.toByte(), 0x01, 0x00, 0x93.toByte()) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt b/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt index e6a213a..c76f73b 100644 --- a/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt +++ b/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt @@ -32,11 +32,6 @@ const val HK_NET_USERNAME = "admin" const val HK_NET_PASSWORD = "1234qwer" const val WIFI_PASSWORD = "zhsz20311hw" - - const val STATUS_CONNECT_SUCCESS = 1 //连接成功 - const val STATUS_CONNECT_CLOSED = 0 //关闭连接 - const val STATUS_CONNECT_ERROR = 0 //连接失败 - - const val CONNECT_SUCCESS = 2023042501 - const val RECONNECT = 2023042502 + const val UDP_HOST = "192.168.31.233" + const val UDP_PORT = 9000 } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/utils/netty/ISocketListener.kt b/app/src/main/java/com/casic/br/operationsite/utils/netty/ISocketListener.kt deleted file mode 100644 index f718b89..0000000 --- a/app/src/main/java/com/casic/br/operationsite/utils/netty/ISocketListener.kt +++ /dev/null @@ -1,13 +0,0 @@ -package com.casic.br.operationsite.utils.netty - -interface ISocketListener { - /** - * 当接收到系统消息 - */ - fun onMessageResponse(data: ByteArray) - - /** - * 当连接状态发生变化时调用 - */ - fun onServiceStatusConnectChanged(statusCode: Int) -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/utils/netty/SocketChannelHandle.kt b/app/src/main/java/com/casic/br/operationsite/utils/netty/SocketChannelHandle.kt deleted file mode 100644 index 6f3d8f7..0000000 --- a/app/src/main/java/com/casic/br/operationsite/utils/netty/SocketChannelHandle.kt +++ /dev/null @@ -1,38 +0,0 @@ -package com.casic.br.operationsite.utils.netty - -import android.util.Log -import com.casic.br.operationsite.utils.LocaleConstant -import io.netty.channel.ChannelHandlerContext -import io.netty.channel.SimpleChannelInboundHandler - -class SocketChannelHandle(private val listener: ISocketListener) : - SimpleChannelInboundHandler() { - - private val kTag = "SocketChannelHandle" - - override fun channelActive(ctx: ChannelHandlerContext) { - super.channelActive(ctx) - Log.d(kTag, "channelActive ===> 连接成功") - listener.onServiceStatusConnectChanged(LocaleConstant.STATUS_CONNECT_SUCCESS) - } - - override fun channelInactive(ctx: ChannelHandlerContext) { - super.channelInactive(ctx) - Log.e(kTag, "channelInactive: 连接断开") - listener.onServiceStatusConnectChanged(LocaleConstant.STATUS_CONNECT_ERROR) - } - - override fun channelRead0(ctx: ChannelHandlerContext, data: ByteArray?) { - if (data == null) { - return - } - listener.onMessageResponse(data) - } - - override fun exceptionCaught(ctx: ChannelHandlerContext, cause: Throwable) { - super.exceptionCaught(ctx, cause) - listener.onServiceStatusConnectChanged(LocaleConstant.STATUS_CONNECT_ERROR) - cause.printStackTrace() - ctx.close() - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/utils/netty/SocketClient.kt b/app/src/main/java/com/casic/br/operationsite/utils/netty/SocketClient.kt deleted file mode 100644 index 30ce2b8..0000000 --- a/app/src/main/java/com/casic/br/operationsite/utils/netty/SocketClient.kt +++ /dev/null @@ -1,143 +0,0 @@ -package com.casic.br.operationsite.utils.netty - -import android.os.SystemClock -import android.util.Log -import com.casic.br.operationsite.utils.LocaleConstant -import io.netty.bootstrap.Bootstrap -import io.netty.channel.* -import io.netty.channel.nio.NioEventLoopGroup -import io.netty.channel.socket.SocketChannel -import io.netty.channel.socket.nio.NioSocketChannel -import io.netty.handler.codec.bytes.ByteArrayDecoder -import io.netty.handler.codec.bytes.ByteArrayEncoder -import io.netty.handler.timeout.IdleStateHandler - -class SocketClient { - - private val kTag = "SocketClient" - private lateinit var hostname: String - private var port = 0 - private var nioEventLoopGroup: NioEventLoopGroup? = null - private var channel: Channel? = null - private var listener: ISocketListener? = null - private var reconnectNum = Int.MAX_VALUE - private var isNeedReconnect = true - private var isConnecting = false - private var reconnectIntervalTime: Long = 15000 - var connectStatus = false - - fun setSocketListener(listener: ISocketListener?) { - this.listener = listener - } - - fun connect(hostname: String, port: Int) { - this.hostname = hostname - this.port = port - Log.d(kTag, "connect ===> 开始连接TCP服务器") - if (isConnecting) { - return - } - //起个线程 - val clientThread = object : Thread("client-Netty") { - override fun run() { - super.run() - isNeedReconnect = true - reconnectNum = Int.MAX_VALUE - connectServer() - } - } - clientThread.start() - } - - private fun connectServer() { - synchronized(this) { - var channelFuture: ChannelFuture? = null //连接管理对象 - if (!connectStatus) { - isConnecting = true - nioEventLoopGroup = NioEventLoopGroup() //设置的连接group - val bootstrap = Bootstrap() - bootstrap.group(nioEventLoopGroup) //设置的一系列连接参数操作等 - .channel(NioSocketChannel::class.java) - .option(ChannelOption.TCP_NODELAY, true) //无阻塞 - .option(ChannelOption.SO_KEEPALIVE, true) //长连接 - .option( - ChannelOption.RCVBUF_ALLOCATOR, - AdaptiveRecvByteBufAllocator(5000, 5000, 8000) - ) //接收缓冲区 最小值太小时数据接收不全 - .handler(object : ChannelInitializer() { - override fun initChannel(channel: SocketChannel) { - val pipeline = channel.pipeline() - pipeline.addLast(IdleStateHandler(60, 10, 0)) - pipeline.addLast(ByteArrayDecoder()) - pipeline.addLast(ByteArrayEncoder()) - pipeline.addLast(SocketChannelHandle(listener!!)) - } - }) - try { - //连接监听 - channelFuture = bootstrap.connect(hostname, port) - .addListener(object : ChannelFutureListener { - override fun operationComplete(channelFuture: ChannelFuture) { - if (channelFuture.isSuccess) { - connectStatus = true - channel = channelFuture.channel() - } else { - Log.e(kTag, "operationComplete: 连接失败") - connectStatus = false - } - isConnecting = false - } - }).sync() - // 等待连接关闭 - channelFuture.channel().closeFuture().sync() - } catch (e: Exception) { - e.printStackTrace() - } finally { - connectStatus = false - listener?.onServiceStatusConnectChanged(LocaleConstant.STATUS_CONNECT_CLOSED) - if (null != channelFuture) { - if (channelFuture.channel() != null && channelFuture.channel().isOpen) { - channelFuture.channel().close() - } - } - nioEventLoopGroup?.shutdownGracefully() - reconnect() //重新连接 - } - } - } - } - - //断开连接 - fun disconnect() { - Log.d(kTag, "disconnect ===> 断开连接") - isNeedReconnect = false - nioEventLoopGroup?.shutdownGracefully() - } - - //重新连接 - private fun reconnect() { - if (isNeedReconnect && reconnectNum > 0 && !connectStatus) { - reconnectNum-- - SystemClock.sleep(reconnectIntervalTime) - if (isNeedReconnect && reconnectNum > 0 && !connectStatus) { - Log.d(kTag, "reconnect ===> 重新连接") - connectServer() - } - } - } - - fun sendData(bytes: ByteArray) { - if (bytes.isNotEmpty()) { - channel?.writeAndFlush(bytes)?.addListener(ChannelFutureListener { future -> - if (future.isSuccess) { - Log.d(kTag, "sendData ===> 发送成功") - } else { - // 关闭连接,节约资源 - Log.d(kTag, "sendData ===> 关闭连接,节约资源") - future.channel().close() - nioEventLoopGroup?.shutdownGracefully() - } - }) - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/utils/netty/SocketManager.kt b/app/src/main/java/com/casic/br/operationsite/utils/netty/SocketManager.kt deleted file mode 100644 index c9ff455..0000000 --- a/app/src/main/java/com/casic/br/operationsite/utils/netty/SocketManager.kt +++ /dev/null @@ -1,55 +0,0 @@ -package com.casic.br.operationsite.utils.netty - -import android.util.Log -import com.casic.br.operationsite.utils.LocaleConstant -import com.casic.br.operationsite.view.MethaneActivity - -class SocketManager : ISocketListener { - - companion object { - //Kotlin委托模式双重锁单例 - val get: SocketManager by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) { - SocketManager() - } - } - - private val kTag = "SocketManager" - private val nettyClient by lazy { SocketClient() } - - fun connectNetty(hostname: String, port: Int) { - Thread { - if (!nettyClient.connectStatus) { - nettyClient.setSocketListener(this) - nettyClient.connect(hostname, port) - } else { - nettyClient.disconnect() - } - }.start() - } - - override fun onMessageResponse(data: ByteArray) { - Log.d(kTag, "onMessageResponse <=== " + data.contentToString()) - } - - override fun onServiceStatusConnectChanged(statusCode: Int) { - if (statusCode == LocaleConstant.STATUS_CONNECT_SUCCESS) { - if (nettyClient.connectStatus) { - Log.d(kTag, "连接成功") - MethaneActivity.weakReferenceHandler.sendEmptyMessage(LocaleConstant.CONNECT_SUCCESS) - } - } else { - if (!nettyClient.connectStatus) { - Log.e(kTag, "onServiceStatusConnectChanged:$statusCode,连接断开,正在重连") - MethaneActivity.weakReferenceHandler.sendEmptyMessage(LocaleConstant.RECONNECT) - } - } - } - - fun sendData(data: ByteArray) { - nettyClient.sendData(data) - } - - fun close() { - nettyClient.disconnect() - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/utils/netty/UdpChannelInboundHandler.kt b/app/src/main/java/com/casic/br/operationsite/utils/netty/UdpChannelInboundHandler.kt new file mode 100644 index 0000000..a7f9d27 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/utils/netty/UdpChannelInboundHandler.kt @@ -0,0 +1,36 @@ +package com.casic.br.operationsite.utils.netty + +import io.netty.channel.ChannelHandlerContext +import io.netty.channel.SimpleChannelInboundHandler +import io.netty.channel.socket.DatagramPacket +import io.netty.util.CharsetUtil + + +abstract class UdpChannelInboundHandler : SimpleChannelInboundHandler() { + + private var handlerContext: ChannelHandlerContext? = null + + override fun channelActive(ctx: ChannelHandlerContext?) { + super.channelActive(ctx) + handlerContext = ctx + } + + override fun channelInactive(ctx: ChannelHandlerContext?) { + super.channelInactive(ctx) + handlerContext?.close() + } + + fun sendDatagramPacket(obj: Any) { + handlerContext?.writeAndFlush(obj) + } + + fun releasePort() { + handlerContext?.close() + } + + override fun channelRead0(ctx: ChannelHandlerContext, datagramPacket: DatagramPacket) { + receivedMessage(datagramPacket.content().toString(CharsetUtil.UTF_8)) + } + + abstract fun receivedMessage(data: String) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/utils/netty/UdpChannelInitializer.kt b/app/src/main/java/com/casic/br/operationsite/utils/netty/UdpChannelInitializer.kt new file mode 100644 index 0000000..bcdeef1 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/utils/netty/UdpChannelInitializer.kt @@ -0,0 +1,17 @@ +package com.casic.br.operationsite.utils.netty + +import io.netty.channel.ChannelInitializer +import io.netty.channel.socket.DatagramChannel +import io.netty.handler.timeout.IdleStateHandler + + +open class UdpChannelInitializer(private val handler: UdpChannelInboundHandler) : + ChannelInitializer() { + + override fun initChannel(datagramChannel: DatagramChannel) { + val pipeline = datagramChannel.pipeline() + pipeline.addLast( + IdleStateHandler(12, 15, 0) + ).addLast(handler) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/utils/netty/UdpClient.kt b/app/src/main/java/com/casic/br/operationsite/utils/netty/UdpClient.kt new file mode 100644 index 0000000..d9753e0 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/utils/netty/UdpClient.kt @@ -0,0 +1,81 @@ +package com.casic.br.operationsite.utils.netty + +import com.casic.br.operationsite.utils.LocaleConstant +import io.netty.bootstrap.Bootstrap +import io.netty.buffer.ByteBuf +import io.netty.buffer.Unpooled +import io.netty.channel.ChannelFuture +import io.netty.channel.ChannelOption +import io.netty.channel.nio.NioEventLoopGroup +import io.netty.channel.socket.DatagramPacket +import io.netty.channel.socket.nio.NioDatagramChannel +import io.netty.util.CharsetUtil +import java.net.InetSocketAddress +import java.util.concurrent.ExecutorService +import java.util.concurrent.Executors + + +class UdpClient() : UdpChannelInboundHandler(), Runnable { + + private val bootStrap by lazy { Bootstrap() } + private val eventLoopGroup by lazy { NioEventLoopGroup() } + private val udpChannelInitializer by lazy { UdpChannelInitializer(this) } + private var executorService: ExecutorService + + init { + bootStrap.group(eventLoopGroup) + bootStrap.channel(NioDatagramChannel::class.java) + .option(ChannelOption.SO_RCVBUF, 1024) + .option(ChannelOption.SO_SNDBUF, 1024) + bootStrap.handler(udpChannelInitializer) + + executorService = Executors.newSingleThreadExecutor() + executorService.execute(this) + } + + override fun run() { + try { + val channelFuture: ChannelFuture = bootStrap.bind(LocaleConstant.UDP_PORT).sync() + channelFuture.channel().closeFuture().sync() + } catch (e: InterruptedException) { + e.printStackTrace() + } finally { + eventLoopGroup.shutdownGracefully() + } + } + + fun send(value: String) { + val datagramPacket = DatagramPacket( + Unpooled.copiedBuffer(value, CharsetUtil.UTF_8), + InetSocketAddress(LocaleConstant.UDP_HOST, LocaleConstant.UDP_PORT) + ) + + sendDatagramPacket(datagramPacket) + } + + fun send(value: ByteArray) { + val datagramPacket = DatagramPacket( + Unpooled.copiedBuffer(value), + InetSocketAddress(LocaleConstant.UDP_HOST, LocaleConstant.UDP_PORT) + ) + + sendDatagramPacket(datagramPacket) + } + + fun send(value: ByteBuf) { + val datagramPacket = DatagramPacket( + Unpooled.copiedBuffer(value), + InetSocketAddress(LocaleConstant.UDP_HOST, LocaleConstant.UDP_PORT) + ) + + sendDatagramPacket(datagramPacket) + } + + fun release() { + releasePort() + } + + override fun receivedMessage(data: String) { + + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/view/MethaneActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/MethaneActivity.kt index 000392e..c0919d9 100644 --- a/app/src/main/java/com/casic/br/operationsite/view/MethaneActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/view/MethaneActivity.kt @@ -7,24 +7,19 @@ import android.net.wifi.WifiManager import android.net.wifi.WifiNetworkSpecifier import android.os.Build -import android.view.View import androidx.lifecycle.ViewModelProvider import com.casic.br.operationsite.R -import com.casic.br.operationsite.extensions.createStartCommand -import com.casic.br.operationsite.extensions.createStopCommand -import com.casic.br.operationsite.extensions.initLayoutImmersionBar -import com.casic.br.operationsite.extensions.splitGasParam +import com.casic.br.operationsite.extensions.* import com.casic.br.operationsite.utils.DeviceType import com.casic.br.operationsite.utils.LocaleConstant import com.casic.br.operationsite.utils.RuntimeCache -import com.casic.br.operationsite.utils.netty.SocketManager +import com.casic.br.operationsite.utils.netty.UdpClient import com.casic.br.operationsite.vm.DeviceViewModel import com.gyf.immersionbar.ImmersionBar import com.pengxh.kt.lite.base.KotlinBaseActivity import com.pengxh.kt.lite.extensions.convertColor import com.pengxh.kt.lite.extensions.getSystemService import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.WeakReferenceHandler import com.pengxh.kt.lite.widget.SteeringWheelController import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import kotlinx.android.synthetic.main.activity_methane.* @@ -33,16 +28,12 @@ class MethaneActivity : KotlinBaseActivity() { - companion object { - lateinit var weakReferenceHandler: WeakReferenceHandler - } - private val kTag = "MethaneActivity" private val context = this@MethaneActivity private val wifiManager by lazy { applicationContext.getSystemService() } + private val udpClient by lazy { UdpClient() } private val wifiSsids = ArrayList() private val gasTreeItems = ArrayList() - private var isConnectSuccess = false private var connectivityManager: ConnectivityManager? = null private lateinit var deviceViewModel: DeviceViewModel @@ -60,21 +51,6 @@ } } - weakReferenceHandler = WeakReferenceHandler { - when (it.what) { - LocaleConstant.CONNECT_SUCCESS -> { - notConnectedLayout.visibility = View.GONE - "激光甲烷控制云台连接成功".show(this) - isConnectSuccess = true - } - LocaleConstant.RECONNECT -> { - notConnectedLayout.visibility = View.VISIBLE - isConnectSuccess = false - } - } - true - } - //获取wifi列表 wifiSsids.clear() wifiManager?.scanResults?.forEach { res -> @@ -102,11 +78,6 @@ override fun initEvent() { leftBackView.setOnClickListener { finish() } - rightOptionView.setOnClickListener { - val gasParam = configSelectView.text.toString().splitGasParam() - SocketManager.get.connectNetty(gasParam[0], gasParam[1].toInt()) - } - configSelectView.setOnClickListener { BottomActionSheet.Builder() .setContext(this) @@ -167,16 +138,14 @@ dir == SteeringWheelController.Direction.RIGHT || dir == SteeringWheelController.Direction.BOTTOM ) { - SocketManager.get.sendData(createStopCommand()) + udpClient.send(createStopCommand()) isActionUp = true } else { - if (isConnectSuccess) { - clickCount++ - if (clickCount % 2 == 0) { - openInstructionsLight() - } else { - closeInstructionsLight() - } + clickCount++ + if (clickCount % 2 == 0) { + openInstructionsLight() + } else { + closeInstructionsLight() } } } @@ -186,29 +155,29 @@ } override fun onLeftTurn() { - if (isConnectSuccess && isActionUp) { - SocketManager.get.sendData(SteeringWheelController.Direction.LEFT.createStartCommand()) + if (isActionUp) { + udpClient.send(SteeringWheelController.Direction.LEFT.createStartCommand()) isActionUp = false } } override fun onTopTurn() { - if (isConnectSuccess && isActionUp) { - SocketManager.get.sendData(SteeringWheelController.Direction.TOP.createStartCommand()) + if (isActionUp) { + udpClient.send(SteeringWheelController.Direction.TOP.createStartCommand()) isActionUp = false } } override fun onRightTurn() { - if (isConnectSuccess && isActionUp) { - SocketManager.get.sendData(SteeringWheelController.Direction.RIGHT.createStartCommand()) + if (isActionUp) { + udpClient.send(SteeringWheelController.Direction.RIGHT.createStartCommand()) isActionUp = false } } override fun onBottomTurn() { - if (isConnectSuccess && isActionUp) { - SocketManager.get.sendData(SteeringWheelController.Direction.BOTTOM.createStartCommand()) + if (isActionUp) { + udpClient.send(SteeringWheelController.Direction.BOTTOM.createStartCommand()) isActionUp = false } } @@ -216,28 +185,17 @@ } private fun closeInstructionsLight() { - SocketManager.get.sendData( - byteArrayOf( - 0xAA.toByte(), 0x01, 0x00, 0x91.toByte(), 0x00, 0x00, 0x92.toByte() - ) - ) + udpClient.send(createCloseLightCommand()) } private fun openInstructionsLight() { - SocketManager.get.sendData( - byteArrayOf( - 0xAA.toByte(), 0x01, 0x00, 0x91.toByte(), 0x01, 0x00, 0x93.toByte() - ) - ) + udpClient.send(createOpenLightCommand()) } private val networkCallback = object : ConnectivityManager.NetworkCallback() { override fun onAvailable(network: Network) { super.onAvailable(network) connectivityManager?.bindProcessToNetwork(network) - //连接成功后自动连接TCP - val gasParam = configSelectView.text.toString().splitGasParam() - SocketManager.get.connectNetty(gasParam[0], gasParam[1].toInt()) } override fun onUnavailable() { @@ -261,7 +219,7 @@ override fun onDestroy() { super.onDestroy() - SocketManager.get.close() + udpClient.release() connectivityManager?.bindProcessToNetwork(null) connectivityManager?.unregisterNetworkCallback(networkCallback) } diff --git a/app/src/main/java/com/casic/br/operationsite/extensions/Direction.kt b/app/src/main/java/com/casic/br/operationsite/extensions/Direction.kt index 4774c89..d0b247b 100644 --- a/app/src/main/java/com/casic/br/operationsite/extensions/Direction.kt +++ b/app/src/main/java/com/casic/br/operationsite/extensions/Direction.kt @@ -33,4 +33,12 @@ fun createStopCommand(): ByteArray { return byteArrayOf(0xFF.toByte(), 0x01, 0x00, 0x00, 0x00, 0x00, 0x01) +} + +fun createCloseLightCommand(): ByteArray { + return byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x91.toByte(), 0x00, 0x00, 0x92.toByte()) +} + +fun createOpenLightCommand(): ByteArray { + return byteArrayOf(0xAA.toByte(), 0x01, 0x00, 0x91.toByte(), 0x01, 0x00, 0x93.toByte()) } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt b/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt index e6a213a..c76f73b 100644 --- a/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt +++ b/app/src/main/java/com/casic/br/operationsite/utils/LocaleConstant.kt @@ -32,11 +32,6 @@ const val HK_NET_USERNAME = "admin" const val HK_NET_PASSWORD = "1234qwer" const val WIFI_PASSWORD = "zhsz20311hw" - - const val STATUS_CONNECT_SUCCESS = 1 //连接成功 - const val STATUS_CONNECT_CLOSED = 0 //关闭连接 - const val STATUS_CONNECT_ERROR = 0 //连接失败 - - const val CONNECT_SUCCESS = 2023042501 - const val RECONNECT = 2023042502 + const val UDP_HOST = "192.168.31.233" + const val UDP_PORT = 9000 } \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/utils/netty/ISocketListener.kt b/app/src/main/java/com/casic/br/operationsite/utils/netty/ISocketListener.kt deleted file mode 100644 index f718b89..0000000 --- a/app/src/main/java/com/casic/br/operationsite/utils/netty/ISocketListener.kt +++ /dev/null @@ -1,13 +0,0 @@ -package com.casic.br.operationsite.utils.netty - -interface ISocketListener { - /** - * 当接收到系统消息 - */ - fun onMessageResponse(data: ByteArray) - - /** - * 当连接状态发生变化时调用 - */ - fun onServiceStatusConnectChanged(statusCode: Int) -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/utils/netty/SocketChannelHandle.kt b/app/src/main/java/com/casic/br/operationsite/utils/netty/SocketChannelHandle.kt deleted file mode 100644 index 6f3d8f7..0000000 --- a/app/src/main/java/com/casic/br/operationsite/utils/netty/SocketChannelHandle.kt +++ /dev/null @@ -1,38 +0,0 @@ -package com.casic.br.operationsite.utils.netty - -import android.util.Log -import com.casic.br.operationsite.utils.LocaleConstant -import io.netty.channel.ChannelHandlerContext -import io.netty.channel.SimpleChannelInboundHandler - -class SocketChannelHandle(private val listener: ISocketListener) : - SimpleChannelInboundHandler() { - - private val kTag = "SocketChannelHandle" - - override fun channelActive(ctx: ChannelHandlerContext) { - super.channelActive(ctx) - Log.d(kTag, "channelActive ===> 连接成功") - listener.onServiceStatusConnectChanged(LocaleConstant.STATUS_CONNECT_SUCCESS) - } - - override fun channelInactive(ctx: ChannelHandlerContext) { - super.channelInactive(ctx) - Log.e(kTag, "channelInactive: 连接断开") - listener.onServiceStatusConnectChanged(LocaleConstant.STATUS_CONNECT_ERROR) - } - - override fun channelRead0(ctx: ChannelHandlerContext, data: ByteArray?) { - if (data == null) { - return - } - listener.onMessageResponse(data) - } - - override fun exceptionCaught(ctx: ChannelHandlerContext, cause: Throwable) { - super.exceptionCaught(ctx, cause) - listener.onServiceStatusConnectChanged(LocaleConstant.STATUS_CONNECT_ERROR) - cause.printStackTrace() - ctx.close() - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/utils/netty/SocketClient.kt b/app/src/main/java/com/casic/br/operationsite/utils/netty/SocketClient.kt deleted file mode 100644 index 30ce2b8..0000000 --- a/app/src/main/java/com/casic/br/operationsite/utils/netty/SocketClient.kt +++ /dev/null @@ -1,143 +0,0 @@ -package com.casic.br.operationsite.utils.netty - -import android.os.SystemClock -import android.util.Log -import com.casic.br.operationsite.utils.LocaleConstant -import io.netty.bootstrap.Bootstrap -import io.netty.channel.* -import io.netty.channel.nio.NioEventLoopGroup -import io.netty.channel.socket.SocketChannel -import io.netty.channel.socket.nio.NioSocketChannel -import io.netty.handler.codec.bytes.ByteArrayDecoder -import io.netty.handler.codec.bytes.ByteArrayEncoder -import io.netty.handler.timeout.IdleStateHandler - -class SocketClient { - - private val kTag = "SocketClient" - private lateinit var hostname: String - private var port = 0 - private var nioEventLoopGroup: NioEventLoopGroup? = null - private var channel: Channel? = null - private var listener: ISocketListener? = null - private var reconnectNum = Int.MAX_VALUE - private var isNeedReconnect = true - private var isConnecting = false - private var reconnectIntervalTime: Long = 15000 - var connectStatus = false - - fun setSocketListener(listener: ISocketListener?) { - this.listener = listener - } - - fun connect(hostname: String, port: Int) { - this.hostname = hostname - this.port = port - Log.d(kTag, "connect ===> 开始连接TCP服务器") - if (isConnecting) { - return - } - //起个线程 - val clientThread = object : Thread("client-Netty") { - override fun run() { - super.run() - isNeedReconnect = true - reconnectNum = Int.MAX_VALUE - connectServer() - } - } - clientThread.start() - } - - private fun connectServer() { - synchronized(this) { - var channelFuture: ChannelFuture? = null //连接管理对象 - if (!connectStatus) { - isConnecting = true - nioEventLoopGroup = NioEventLoopGroup() //设置的连接group - val bootstrap = Bootstrap() - bootstrap.group(nioEventLoopGroup) //设置的一系列连接参数操作等 - .channel(NioSocketChannel::class.java) - .option(ChannelOption.TCP_NODELAY, true) //无阻塞 - .option(ChannelOption.SO_KEEPALIVE, true) //长连接 - .option( - ChannelOption.RCVBUF_ALLOCATOR, - AdaptiveRecvByteBufAllocator(5000, 5000, 8000) - ) //接收缓冲区 最小值太小时数据接收不全 - .handler(object : ChannelInitializer() { - override fun initChannel(channel: SocketChannel) { - val pipeline = channel.pipeline() - pipeline.addLast(IdleStateHandler(60, 10, 0)) - pipeline.addLast(ByteArrayDecoder()) - pipeline.addLast(ByteArrayEncoder()) - pipeline.addLast(SocketChannelHandle(listener!!)) - } - }) - try { - //连接监听 - channelFuture = bootstrap.connect(hostname, port) - .addListener(object : ChannelFutureListener { - override fun operationComplete(channelFuture: ChannelFuture) { - if (channelFuture.isSuccess) { - connectStatus = true - channel = channelFuture.channel() - } else { - Log.e(kTag, "operationComplete: 连接失败") - connectStatus = false - } - isConnecting = false - } - }).sync() - // 等待连接关闭 - channelFuture.channel().closeFuture().sync() - } catch (e: Exception) { - e.printStackTrace() - } finally { - connectStatus = false - listener?.onServiceStatusConnectChanged(LocaleConstant.STATUS_CONNECT_CLOSED) - if (null != channelFuture) { - if (channelFuture.channel() != null && channelFuture.channel().isOpen) { - channelFuture.channel().close() - } - } - nioEventLoopGroup?.shutdownGracefully() - reconnect() //重新连接 - } - } - } - } - - //断开连接 - fun disconnect() { - Log.d(kTag, "disconnect ===> 断开连接") - isNeedReconnect = false - nioEventLoopGroup?.shutdownGracefully() - } - - //重新连接 - private fun reconnect() { - if (isNeedReconnect && reconnectNum > 0 && !connectStatus) { - reconnectNum-- - SystemClock.sleep(reconnectIntervalTime) - if (isNeedReconnect && reconnectNum > 0 && !connectStatus) { - Log.d(kTag, "reconnect ===> 重新连接") - connectServer() - } - } - } - - fun sendData(bytes: ByteArray) { - if (bytes.isNotEmpty()) { - channel?.writeAndFlush(bytes)?.addListener(ChannelFutureListener { future -> - if (future.isSuccess) { - Log.d(kTag, "sendData ===> 发送成功") - } else { - // 关闭连接,节约资源 - Log.d(kTag, "sendData ===> 关闭连接,节约资源") - future.channel().close() - nioEventLoopGroup?.shutdownGracefully() - } - }) - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/utils/netty/SocketManager.kt b/app/src/main/java/com/casic/br/operationsite/utils/netty/SocketManager.kt deleted file mode 100644 index c9ff455..0000000 --- a/app/src/main/java/com/casic/br/operationsite/utils/netty/SocketManager.kt +++ /dev/null @@ -1,55 +0,0 @@ -package com.casic.br.operationsite.utils.netty - -import android.util.Log -import com.casic.br.operationsite.utils.LocaleConstant -import com.casic.br.operationsite.view.MethaneActivity - -class SocketManager : ISocketListener { - - companion object { - //Kotlin委托模式双重锁单例 - val get: SocketManager by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) { - SocketManager() - } - } - - private val kTag = "SocketManager" - private val nettyClient by lazy { SocketClient() } - - fun connectNetty(hostname: String, port: Int) { - Thread { - if (!nettyClient.connectStatus) { - nettyClient.setSocketListener(this) - nettyClient.connect(hostname, port) - } else { - nettyClient.disconnect() - } - }.start() - } - - override fun onMessageResponse(data: ByteArray) { - Log.d(kTag, "onMessageResponse <=== " + data.contentToString()) - } - - override fun onServiceStatusConnectChanged(statusCode: Int) { - if (statusCode == LocaleConstant.STATUS_CONNECT_SUCCESS) { - if (nettyClient.connectStatus) { - Log.d(kTag, "连接成功") - MethaneActivity.weakReferenceHandler.sendEmptyMessage(LocaleConstant.CONNECT_SUCCESS) - } - } else { - if (!nettyClient.connectStatus) { - Log.e(kTag, "onServiceStatusConnectChanged:$statusCode,连接断开,正在重连") - MethaneActivity.weakReferenceHandler.sendEmptyMessage(LocaleConstant.RECONNECT) - } - } - } - - fun sendData(data: ByteArray) { - nettyClient.sendData(data) - } - - fun close() { - nettyClient.disconnect() - } -} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/utils/netty/UdpChannelInboundHandler.kt b/app/src/main/java/com/casic/br/operationsite/utils/netty/UdpChannelInboundHandler.kt new file mode 100644 index 0000000..a7f9d27 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/utils/netty/UdpChannelInboundHandler.kt @@ -0,0 +1,36 @@ +package com.casic.br.operationsite.utils.netty + +import io.netty.channel.ChannelHandlerContext +import io.netty.channel.SimpleChannelInboundHandler +import io.netty.channel.socket.DatagramPacket +import io.netty.util.CharsetUtil + + +abstract class UdpChannelInboundHandler : SimpleChannelInboundHandler() { + + private var handlerContext: ChannelHandlerContext? = null + + override fun channelActive(ctx: ChannelHandlerContext?) { + super.channelActive(ctx) + handlerContext = ctx + } + + override fun channelInactive(ctx: ChannelHandlerContext?) { + super.channelInactive(ctx) + handlerContext?.close() + } + + fun sendDatagramPacket(obj: Any) { + handlerContext?.writeAndFlush(obj) + } + + fun releasePort() { + handlerContext?.close() + } + + override fun channelRead0(ctx: ChannelHandlerContext, datagramPacket: DatagramPacket) { + receivedMessage(datagramPacket.content().toString(CharsetUtil.UTF_8)) + } + + abstract fun receivedMessage(data: String) +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/utils/netty/UdpChannelInitializer.kt b/app/src/main/java/com/casic/br/operationsite/utils/netty/UdpChannelInitializer.kt new file mode 100644 index 0000000..bcdeef1 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/utils/netty/UdpChannelInitializer.kt @@ -0,0 +1,17 @@ +package com.casic.br.operationsite.utils.netty + +import io.netty.channel.ChannelInitializer +import io.netty.channel.socket.DatagramChannel +import io.netty.handler.timeout.IdleStateHandler + + +open class UdpChannelInitializer(private val handler: UdpChannelInboundHandler) : + ChannelInitializer() { + + override fun initChannel(datagramChannel: DatagramChannel) { + val pipeline = datagramChannel.pipeline() + pipeline.addLast( + IdleStateHandler(12, 15, 0) + ).addLast(handler) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/utils/netty/UdpClient.kt b/app/src/main/java/com/casic/br/operationsite/utils/netty/UdpClient.kt new file mode 100644 index 0000000..d9753e0 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/utils/netty/UdpClient.kt @@ -0,0 +1,81 @@ +package com.casic.br.operationsite.utils.netty + +import com.casic.br.operationsite.utils.LocaleConstant +import io.netty.bootstrap.Bootstrap +import io.netty.buffer.ByteBuf +import io.netty.buffer.Unpooled +import io.netty.channel.ChannelFuture +import io.netty.channel.ChannelOption +import io.netty.channel.nio.NioEventLoopGroup +import io.netty.channel.socket.DatagramPacket +import io.netty.channel.socket.nio.NioDatagramChannel +import io.netty.util.CharsetUtil +import java.net.InetSocketAddress +import java.util.concurrent.ExecutorService +import java.util.concurrent.Executors + + +class UdpClient() : UdpChannelInboundHandler(), Runnable { + + private val bootStrap by lazy { Bootstrap() } + private val eventLoopGroup by lazy { NioEventLoopGroup() } + private val udpChannelInitializer by lazy { UdpChannelInitializer(this) } + private var executorService: ExecutorService + + init { + bootStrap.group(eventLoopGroup) + bootStrap.channel(NioDatagramChannel::class.java) + .option(ChannelOption.SO_RCVBUF, 1024) + .option(ChannelOption.SO_SNDBUF, 1024) + bootStrap.handler(udpChannelInitializer) + + executorService = Executors.newSingleThreadExecutor() + executorService.execute(this) + } + + override fun run() { + try { + val channelFuture: ChannelFuture = bootStrap.bind(LocaleConstant.UDP_PORT).sync() + channelFuture.channel().closeFuture().sync() + } catch (e: InterruptedException) { + e.printStackTrace() + } finally { + eventLoopGroup.shutdownGracefully() + } + } + + fun send(value: String) { + val datagramPacket = DatagramPacket( + Unpooled.copiedBuffer(value, CharsetUtil.UTF_8), + InetSocketAddress(LocaleConstant.UDP_HOST, LocaleConstant.UDP_PORT) + ) + + sendDatagramPacket(datagramPacket) + } + + fun send(value: ByteArray) { + val datagramPacket = DatagramPacket( + Unpooled.copiedBuffer(value), + InetSocketAddress(LocaleConstant.UDP_HOST, LocaleConstant.UDP_PORT) + ) + + sendDatagramPacket(datagramPacket) + } + + fun send(value: ByteBuf) { + val datagramPacket = DatagramPacket( + Unpooled.copiedBuffer(value), + InetSocketAddress(LocaleConstant.UDP_HOST, LocaleConstant.UDP_PORT) + ) + + sendDatagramPacket(datagramPacket) + } + + fun release() { + releasePort() + } + + override fun receivedMessage(data: String) { + + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/view/MethaneActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/MethaneActivity.kt index 000392e..c0919d9 100644 --- a/app/src/main/java/com/casic/br/operationsite/view/MethaneActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/view/MethaneActivity.kt @@ -7,24 +7,19 @@ import android.net.wifi.WifiManager import android.net.wifi.WifiNetworkSpecifier import android.os.Build -import android.view.View import androidx.lifecycle.ViewModelProvider import com.casic.br.operationsite.R -import com.casic.br.operationsite.extensions.createStartCommand -import com.casic.br.operationsite.extensions.createStopCommand -import com.casic.br.operationsite.extensions.initLayoutImmersionBar -import com.casic.br.operationsite.extensions.splitGasParam +import com.casic.br.operationsite.extensions.* import com.casic.br.operationsite.utils.DeviceType import com.casic.br.operationsite.utils.LocaleConstant import com.casic.br.operationsite.utils.RuntimeCache -import com.casic.br.operationsite.utils.netty.SocketManager +import com.casic.br.operationsite.utils.netty.UdpClient import com.casic.br.operationsite.vm.DeviceViewModel import com.gyf.immersionbar.ImmersionBar import com.pengxh.kt.lite.base.KotlinBaseActivity import com.pengxh.kt.lite.extensions.convertColor import com.pengxh.kt.lite.extensions.getSystemService import com.pengxh.kt.lite.extensions.show -import com.pengxh.kt.lite.utils.WeakReferenceHandler import com.pengxh.kt.lite.widget.SteeringWheelController import com.pengxh.kt.lite.widget.dialog.BottomActionSheet import kotlinx.android.synthetic.main.activity_methane.* @@ -33,16 +28,12 @@ class MethaneActivity : KotlinBaseActivity() { - companion object { - lateinit var weakReferenceHandler: WeakReferenceHandler - } - private val kTag = "MethaneActivity" private val context = this@MethaneActivity private val wifiManager by lazy { applicationContext.getSystemService() } + private val udpClient by lazy { UdpClient() } private val wifiSsids = ArrayList() private val gasTreeItems = ArrayList() - private var isConnectSuccess = false private var connectivityManager: ConnectivityManager? = null private lateinit var deviceViewModel: DeviceViewModel @@ -60,21 +51,6 @@ } } - weakReferenceHandler = WeakReferenceHandler { - when (it.what) { - LocaleConstant.CONNECT_SUCCESS -> { - notConnectedLayout.visibility = View.GONE - "激光甲烷控制云台连接成功".show(this) - isConnectSuccess = true - } - LocaleConstant.RECONNECT -> { - notConnectedLayout.visibility = View.VISIBLE - isConnectSuccess = false - } - } - true - } - //获取wifi列表 wifiSsids.clear() wifiManager?.scanResults?.forEach { res -> @@ -102,11 +78,6 @@ override fun initEvent() { leftBackView.setOnClickListener { finish() } - rightOptionView.setOnClickListener { - val gasParam = configSelectView.text.toString().splitGasParam() - SocketManager.get.connectNetty(gasParam[0], gasParam[1].toInt()) - } - configSelectView.setOnClickListener { BottomActionSheet.Builder() .setContext(this) @@ -167,16 +138,14 @@ dir == SteeringWheelController.Direction.RIGHT || dir == SteeringWheelController.Direction.BOTTOM ) { - SocketManager.get.sendData(createStopCommand()) + udpClient.send(createStopCommand()) isActionUp = true } else { - if (isConnectSuccess) { - clickCount++ - if (clickCount % 2 == 0) { - openInstructionsLight() - } else { - closeInstructionsLight() - } + clickCount++ + if (clickCount % 2 == 0) { + openInstructionsLight() + } else { + closeInstructionsLight() } } } @@ -186,29 +155,29 @@ } override fun onLeftTurn() { - if (isConnectSuccess && isActionUp) { - SocketManager.get.sendData(SteeringWheelController.Direction.LEFT.createStartCommand()) + if (isActionUp) { + udpClient.send(SteeringWheelController.Direction.LEFT.createStartCommand()) isActionUp = false } } override fun onTopTurn() { - if (isConnectSuccess && isActionUp) { - SocketManager.get.sendData(SteeringWheelController.Direction.TOP.createStartCommand()) + if (isActionUp) { + udpClient.send(SteeringWheelController.Direction.TOP.createStartCommand()) isActionUp = false } } override fun onRightTurn() { - if (isConnectSuccess && isActionUp) { - SocketManager.get.sendData(SteeringWheelController.Direction.RIGHT.createStartCommand()) + if (isActionUp) { + udpClient.send(SteeringWheelController.Direction.RIGHT.createStartCommand()) isActionUp = false } } override fun onBottomTurn() { - if (isConnectSuccess && isActionUp) { - SocketManager.get.sendData(SteeringWheelController.Direction.BOTTOM.createStartCommand()) + if (isActionUp) { + udpClient.send(SteeringWheelController.Direction.BOTTOM.createStartCommand()) isActionUp = false } } @@ -216,28 +185,17 @@ } private fun closeInstructionsLight() { - SocketManager.get.sendData( - byteArrayOf( - 0xAA.toByte(), 0x01, 0x00, 0x91.toByte(), 0x00, 0x00, 0x92.toByte() - ) - ) + udpClient.send(createCloseLightCommand()) } private fun openInstructionsLight() { - SocketManager.get.sendData( - byteArrayOf( - 0xAA.toByte(), 0x01, 0x00, 0x91.toByte(), 0x01, 0x00, 0x93.toByte() - ) - ) + udpClient.send(createOpenLightCommand()) } private val networkCallback = object : ConnectivityManager.NetworkCallback() { override fun onAvailable(network: Network) { super.onAvailable(network) connectivityManager?.bindProcessToNetwork(network) - //连接成功后自动连接TCP - val gasParam = configSelectView.text.toString().splitGasParam() - SocketManager.get.connectNetty(gasParam[0], gasParam[1].toInt()) } override fun onUnavailable() { @@ -261,7 +219,7 @@ override fun onDestroy() { super.onDestroy() - SocketManager.get.close() + udpClient.release() connectivityManager?.bindProcessToNetwork(null) connectivityManager?.unregisterNetworkCallback(networkCallback) } diff --git a/app/src/main/res/layout/activity_methane.xml b/app/src/main/res/layout/activity_methane.xml index 771bcda..ee17a35 100644 --- a/app/src/main/res/layout/activity_methane.xml +++ b/app/src/main/res/layout/activity_methane.xml @@ -7,32 +7,7 @@ android:background="@color/mainBackColor" android:orientation="vertical"> - - - - - - - - +