#
whycq
2025-01-21 9c414520fd00319683a0021bb512f5003aff2800
app/src/main/java/com/example/agvcontroller/socket/NettyServerHandler.java
@@ -7,14 +7,22 @@
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
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.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;
@@ -22,28 +30,74 @@
import org.greenrobot.eventbus.EventBus;
import java.net.InetSocketAddress;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
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秒后执行删除操作
    }
    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
@@ -66,31 +120,55 @@
    @Override
    protected boolean channelRead0(ChannelHandlerContext ctx, AgvPackage pac) throws Exception {
        String serialNum = pac.getHeader().getSerialNum();
        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);
                }
                MainActivity.map.put(serialNum, Boolean.TRUE);
                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();
                    ctx.writeAndFlush(ackPac);
                }
                agvNo = pac.getHeader().getUniqueNo();
                channelMap.put(clientId, ctx.channel());
                EventBus.getDefault().post(new AGVCar(clientId,ip,port,agvNo,1));
                break label;
        }
        return false;
    }