| | |
| | | package com.example.agvcontroller.socket; |
| | | |
| | | import java.nio.charset.StandardCharsets; |
| | | |
| | | |
| | | 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.util.Log; |
| | | |
| | | import com.example.agvcontroller.Item; |
| | | 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.AGV_F0_UP8; |
| | | import com.example.agvcontroller.protocol.AgvAction; |
| | | import com.example.agvcontroller.protocol.AgvPackage; |
| | | import com.example.agvcontroller.protocol.ProtocolType; |
| | | |
| | | |
| | | import org.greenrobot.eventbus.EventBus; |
| | | |
| | | 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<>(); |
| | | |
| | | |
| | | @Override |
| | | public void channelActive(ChannelHandlerContext ctx) throws Exception { |
| | | String clientId = ctx.channel().remoteAddress().toString(); |
| | | channelMap.put(clientId, ctx.channel()); |
| | | Log.d(TAG, "Client connected: " + clientId); |
| | | // String clientId = ctx.channel().remoteAddress().toString(); |
| | | // channelMap.put(clientId, ctx.channel()); |
| | | // EventBus.getDefault().post(new Item("",clientId,"3")); |
| | | // Log.d(TAG, "Client connected: " + clientId); |
| | | } |
| | | |
| | | @Override |
| | | public void channelInactive(ChannelHandlerContext ctx) throws Exception { |
| | | String clientId = ctx.channel().remoteAddress().toString(); |
| | | channelMap.remove(clientId); |
| | | EventBus.getDefault().post(clientId); |
| | | Log.d(TAG, "Client disconnected: " + clientId); |
| | | } |
| | | |
| | | @Override |
| | | public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { |
| | | // 处理接收到的消息 |
| | | ByteBuf byteBuf = (ByteBuf) msg; |
| | | //byte[] data = new byte[byteBuf.readableBytes()]; |
| | | //byteBuf.readBytes(data); |
| | | //String received = new String(data, StandardCharsets.UTF_8); |
| | | //System.out.println("Received from client: " + received); |
| | | // |
| | | //// 回复消息 |
| | | ////ByteBuf response = Unpooled.copiedBuffer("Response from server", StandardCharsets.UTF_8); |
| | | ////ctx.writeAndFlush(response); |
| | | // |
| | | //byte[] responseHex = hexStringToByteArray("48656c6c6f20576f726c64"); // "Hello World" in hex |
| | | //ByteBuf response = Unpooled.wrappedBuffer(responseHex); |
| | | //ctx.writeAndFlush(response); |
| | | // @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信息 添加到list中 |
| | | // Log.d(TAG, "ctx: " + ctx.channel().remoteAddress().toString() ); |
| | | // Log.d(TAG, "Received: " + hexString); |
| | | // } |
| | | // } finally { |
| | | // byteBuf.release(); |
| | | // } |
| | | // } |
| | | |
| | | try { |
| | | while (byteBuf.isReadable()) { |
| | | byte[] bytes = new byte[byteBuf.readableBytes()]; |
| | | byteBuf.readBytes(bytes); |
| | | String hexString = bytesToHex(bytes); |
| | | // 获取agv信息 添加到list中 |
| | | 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(); |
| | | 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 Item("",clientId,agvNo)); |
| | | 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 Item("",clientId,agvNo)); |
| | | 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 Item("",clientId,agvNo)); |
| | | break label; |
| | | |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | private String bytesToHex(byte[] bytes) { |
| | |
| | | Channel channel = channelMap.get(clientId); |
| | | if (channel != null && channel.isActive()) { |
| | | ByteBuf buf = Unpooled.wrappedBuffer(message); |
| | | String upperCase = ByteBufUtil.hexDump(buf).toUpperCase(); |
| | | Log.d(TAG, "upperCase " + upperCase); |
| | | channel.writeAndFlush(buf); |
| | | } else { |
| | | Log.d(TAG, "Client " + clientId + " is not connected"); |
| | | } |
| | | } |
| | | |
| | | 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"); |
| | | } |
| | |
| | | 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; |
| | | } |
| | | } |
| | | |
| | | } |