From 17bb52d9337328323f5f8d2a806cf4f445673b4a Mon Sep 17 00:00:00 2001 From: whycq <913841844@qq.com> Date: 星期四, 06 二月 2025 09:20:55 +0800 Subject: [PATCH] # --- app/src/main/java/com/example/agvcontroller/socket/NettyServerHandler.java | 202 ++++++++++++++++++++++++++++++++++++++++++++----- 1 files changed, 179 insertions(+), 23 deletions(-) diff --git a/app/src/main/java/com/example/agvcontroller/socket/NettyServerHandler.java b/app/src/main/java/com/example/agvcontroller/socket/NettyServerHandler.java index 73271c0..9b07744 100644 --- a/app/src/main/java/com/example/agvcontroller/socket/NettyServerHandler.java +++ b/app/src/main/java/com/example/agvcontroller/socket/NettyServerHandler.java @@ -1,62 +1,190 @@ package com.example.agvcontroller.socket; -import java.nio.charset.StandardCharsets; + + +import static com.example.agvcontroller.utils.DateUtils.formatDate; import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import io.netty.channel.Channel; import io.netty.channel.ChannelHandlerContext; -import io.netty.channel.ChannelInboundHandlerAdapter; + +import android.os.Handler; +import android.os.Looper; +import android.os.Message; import android.util.Log; -import com.example.agvcontroller.Item; +import com.example.agvcontroller.AGVApplication; +import com.example.agvcontroller.AGVCar; +import com.example.agvcontroller.MainActivity; +import com.example.agvcontroller.action.AGV_11_UP; +import com.example.agvcontroller.action.AckMsgBuilder; +import com.example.agvcontroller.met.AbstractInboundHandler; +import com.example.agvcontroller.protocol.AGV_12_UP; +import com.example.agvcontroller.protocol.AGV_13_UP; +import com.example.agvcontroller.protocol.AGV_A1_DOWN; +import com.example.agvcontroller.protocol.AGV_F0_DOWN; +import com.example.agvcontroller.protocol.AGV_F0_UP; +import com.example.agvcontroller.protocol.AgvAction; +import com.example.agvcontroller.protocol.AgvPackage; +import com.example.agvcontroller.protocol.ProtocolType; +import com.example.agvcontroller.utils.DateUtils; import org.greenrobot.eventbus.EventBus; -import org.greenrobot.eventbus.Subscribe; -import org.greenrobot.eventbus.ThreadMode; -import java.util.Arrays; +import java.net.InetSocketAddress; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; import java.util.concurrent.ConcurrentHashMap; -public class NettyServerHandler extends ChannelInboundHandlerAdapter { +public class NettyServerHandler extends AbstractInboundHandler<AgvPackage> { private static final String TAG = "NettyServerHandler"; private static ConcurrentHashMap<String, Channel> channelMap = new ConcurrentHashMap<>(); + private Map<String, Runnable> pendingRemovals = new HashMap<>(); + private Handler handler = new Handler(Looper.getMainLooper()) { + @Override + public void handleMessage(Message msg) { + super.handleMessage(msg); + String clientId = (String) msg.obj; + removeItem(clientId); + } + }; + @Override public void channelActive(ChannelHandlerContext ctx) throws Exception { String clientId = ctx.channel().remoteAddress().toString(); + InetSocketAddress remoteAddress = (InetSocketAddress) ctx.channel().remoteAddress(); + String ip = remoteAddress.getAddress().getHostAddress(); + int port = remoteAddress.getPort(); channelMap.put(clientId, ctx.channel()); - EventBus.getDefault().post(new Item("1",clientId,"3")); + EventBus.getDefault().post(new AGVCar(clientId,ip,port,"--",0)); Log.d(TAG, "Client connected: " + clientId); + + // 鍙栨秷寤惰繜鍒犻櫎鎿嶄綔 + if (pendingRemovals.containsKey(clientId)) { + handler.removeCallbacks(pendingRemovals.get(clientId)); + pendingRemovals.remove(clientId); + } + } @Override public void channelInactive(ChannelHandlerContext ctx) throws Exception { String clientId = ctx.channel().remoteAddress().toString(); + InetSocketAddress remoteAddress = (InetSocketAddress) ctx.channel().remoteAddress(); + String ip = remoteAddress.getAddress().getHostAddress(); + int port = remoteAddress.getPort(); channelMap.remove(clientId); EventBus.getDefault().post(clientId); Log.d(TAG, "Client disconnected: " + clientId); + + // 鍚姩寤惰繜鍒犻櫎鎿嶄綔 + Runnable removalRunnable = new Runnable() { + @Override + public void run() { + removeItem(clientId); + } + }; + pendingRemovals.put(clientId, removalRunnable); + handler.postDelayed(removalRunnable, 20000); // 20绉掑悗鎵ц鍒犻櫎鎿嶄綔 + } - @Override - public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { - // 澶勭悊鎺ユ敹鍒扮殑娑堟伅 - ByteBuf byteBuf = (ByteBuf) msg; - try { - while (byteBuf.isReadable()) { - byte[] bytes = new byte[byteBuf.readableBytes()]; - byteBuf.readBytes(bytes); - String hexString = bytesToHex(bytes); - // 鑾峰彇agv淇℃伅 娣诲姞鍒發ist涓� - Log.d(TAG, "ctx: " + ctx.channel().remoteAddress().toString() ); - Log.d(TAG, "Received: " + hexString); - } - } finally { - byteBuf.release(); + + private void removeItem(String clientId) { + if (channelMap.remove(clientId) != null) { + Log.d(TAG, "Client removed after 20 seconds: " + clientId); + EventBus.getDefault().post(clientId); + } else { + Log.d(TAG, "Client already reconnected or not found: " + clientId); } + } + +// @Override +// public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { +// // 澶勭悊鎺ユ敹鍒扮殑娑堟伅 +// ByteBuf byteBuf = (ByteBuf) msg; +// try { +// while (byteBuf.isReadable()) { +// byte[] bytes = new byte[byteBuf.readableBytes()]; +// byteBuf.readBytes(bytes); +// String hexString = bytesToHex(bytes); +// // 鑾峰彇agv淇℃伅 娣诲姞鍒發ist涓� +// Log.d(TAG, "ctx: " + ctx.channel().remoteAddress().toString() ); +// Log.d(TAG, "Received: " + hexString); +// } +// } finally { +// byteBuf.release(); +// } +// } + + @Override + protected boolean channelRead0(ChannelHandlerContext ctx, AgvPackage pac) throws Exception { + String clientId = ctx.channel().remoteAddress().toString(); + InetSocketAddress remoteAddress = (InetSocketAddress) ctx.channel().remoteAddress(); + String ip = remoteAddress.getAddress().getHostAddress(); + int port = remoteAddress.getPort(); + Log.i("clientId--->",clientId); + Log.i("substring",pac.toString()); + String serialNum = pac.getBody().getMessageBody().getSerialNo(); + Log.i("substring",serialNum); + MainActivity.map.put(serialNum, Boolean.TRUE); + // ack + ProtocolType ackType = isNeedAck(pac); + final String uniqueNo = pac.getHeader().getUniqueNo(); + String agvNo; + label : switch (pac.getHeader().getProtocolType()){ + case ACTION_COMPLETE: // 鍔ㄤ綔瀹屾垚鏁版嵁鍖� + AGV_11_UP agv_11_up = (AGV_11_UP) pac.getBody().getMessageBody(); +// redis.push(RedisConstant.AGV_COMPLETE_FLAG, AgvProtocol.build(uniqueNo).setMessageBody(agv_11_up)); + // 鍔ㄤ綔瀹屾垚搴旂瓟 + if (null != ackType) { + AgvPackage ackPac = AckMsgBuilder.ofSuccess(pac, ackType); + AGV_A1_DOWN agv_a1_down = (AGV_A1_DOWN) ackPac.getBody().getMessageBody(); + agv_a1_down.setAckSign((byte) agv_11_up.getCompleteCode()); + ctx.writeAndFlush(ackPac); + } + break label; + case DATA_CODE_REPORT: + AGV_12_UP agv_12_up = (AGV_12_UP) pac.getBody().getMessageBody(); + agvNo = pac.getHeader().getUniqueNo(); + channelMap.put(clientId, ctx.channel()); + EventBus.getDefault().post(new AGVCar(clientId,ip,port,agvNo,1)); + break label; + case DATA_WITHOUT_CODE_REPORT: + AGV_13_UP agv_13_up = (AGV_13_UP) pac.getBody().getMessageBody(); + agvNo = pac.getHeader().getUniqueNo(); + channelMap.put(clientId, ctx.channel()); + EventBus.getDefault().post(new AGVCar(clientId,ip,port,agvNo,1)); + break label; + case LOGIN_REPORT: + AGV_F0_UP agv_f0_up = (AGV_F0_UP) pac.getBody().getMessageBody(); + if (null != ackType) { + AgvPackage ackPac = AckMsgBuilder.ofSuccess(pac, ackType); + AGV_F0_DOWN agv_f0_down = (AGV_F0_DOWN) ackPac.getBody().getMessageBody(); + String log = formatDate(new Date(), "yyyy-MM-dd HH:mm:ss") + " 涓婅: " + ip + "[鐧诲綍鍖匽>>>" + pac.getSourceHexStr(); + Log.d("updown", log); + AGVApplication.addLog(log); + +// EventBus.getDefault().post(log); + + ctx.writeAndFlush(ackPac); + } + final int battery = agv_f0_up.getBattery(); +// pac.getBody().getMessageBody() + agvNo = pac.getHeader().getUniqueNo(); + channelMap.put(clientId, ctx.channel()); + AGVCar agvCar = new AGVCar(clientId, ip, port, agvNo, 1, battery,0,0,0,0,0,0,0,0,0,0); + EventBus.getDefault().post(agvCar); + break label; + + } + return false; } private String bytesToHex(byte[] bytes) { @@ -66,6 +194,7 @@ } return sb.toString(); } + // 灏嗗崄鍏繘鍒跺瓧绗︿覆杞崲涓哄瓧鑺傛暟缁� private byte[] hexStringToByteArray(String s) { int len = s.length(); @@ -89,10 +218,37 @@ } } + public static void sendMessageToClient(String clientId, AgvAction<?> action) { + + + + Channel channel = channelMap.get(clientId); + if (channel != null && channel.isActive()) { + + channel.writeAndFlush(action); + } else { + Log.d(TAG, "Client " + clientId + " is not connected"); + } + } + @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception { cause.printStackTrace(); ctx.close(); } + /** + * 鏈嶅姟鍣ㄦ槸鍚﹂渶瑕佸簲绛� + */ + public static ProtocolType isNeedAck(AgvPackage pac) { + switch (pac.getHeader().getProtocolType()) { + case ACTION_COMPLETE: + return ProtocolType.ACTION_SUCCESS_ACK; + case LOGIN_REPORT: + return ProtocolType.LOGIN_ACK; + default: + return null; + } + } + } -- Gitblit v1.9.1