公司弄了个货柜需要TCP连接,然后我就搭建了netty框架用于tcp连接,突然某一天又来了好几个货柜,不同的货柜不同的IP,启动程序全部都进行连接了,但是发送指令就是错乱的,同一个指令一会儿开开这个柜子,一会儿开开那个柜子,然后对接得人说我应该要指定某个连接,后来看看自己的代码有了灵感
netty有个客户端连接就会请求的方法,我在方法里把所有的连接存储到全局变量里
/**
* 当客户端主动链接服务端的链接后,这个通道就是活跃的了。也就是客户端与服务端建立了通信通道并且可以传输数据
*/
@Override
public void channelActive(ChannelHandlerContext ctx) {
try {
SocketChannel channel = (SocketChannel) ctx.channel();
InetSocketAddress inetSocketAddress = channel.remoteAddress();
String clientIP = inetSocketAddress.getAddress().getHostAddress();
logger.info("客户端连接上服务端: IP地址是:" + clientIP);
// 存储不同的ip的SocketChannel
// 根据标识不同存储不同的key,用来区分不同的连接
Map<String, ChannelHandlerContext> map = new HashMap();
if (IpCabinetBind.IP_34.getIp().equals(clientIP)) {
map.put(IpCabinetBind.IP_34.getOrderNo(), ctx);
}
if (IpCabinetBind.IP_30.getIp().equals(clientIP)) {
map.put(IpCabinetBind.IP_30.getOrderNo(), ctx);
}
if (IpCabinetBind.IP_31.getIp().equals(clientIP)) {
map.put(IpCabinetBind.IP_31.getOrderNo(), ctx);
}
if (IpCabinetBind.IP_32.getIp().equals(clientIP)) {
map.put(IpCabinetBind.IP_32.getOrderNo(), ctx);
}
if (IpCabinetBind.IP_33.getIp().equals(clientIP)) {
map.put(IpCabinetBind.IP_33.getOrderNo(), ctx);
}
// 将连接存储起来
if (map != null) {
ctxMaps.add(map);
}
channel.read();
} catch (Exception e) {
e.printStackTrace();
}
}
附带枚举类
public enum IpCabinetBind {
IP_34("192.168.1.34", "编号001", "04"),
IP_30("192.168.1.30", "编号002", "00"),
IP_31("192.168.1.31", "编号004", "01"),
IP_32("192.168.1.32", "编号005", "02"),
IP_33("192.168.1.33", "编号003", "03");
String ip;
String cabinetNo;
String orderNo;
IpCabinetBind(String ip, String cabinetNo, String orderNo) {
this.ip = ip;
this.cabinetNo = cabinetNo;
this.orderNo = orderNo;
}
public String getIp() {
return ip;
}
public String getCabinetNo() {
return cabinetNo;
}
public String getOrderNo() {
return orderNo;
}
// 根据ip查询命令指令
public static String findIpByOrderNo(String ip) {
for (IpCabinetBind ipCabinetBind : IpCabinetBind.values()) {
if (ipCabinetBind.ip.equals(ip)) {
return ipCabinetBind.orderNo;
}
}
return "";
}
//根据命令指令查询ip地址
public static String findOrderNoByIp(String CabinetNo) {
for (IpCabinetBind ipCabinetBind : IpCabinetBind.values()) {
if (ipCabinetBind.cabinetNo.equals(CabinetNo)) {
return ipCabinetBind.ip;
}
}
return "";
}
}
把不同的连接存储完毕,要发送指令需要某个连接时,for循环并判断是否匹配,匹配从集合里取出对象进行发送消息操作
/*
* @Author df
* @Description 发送消息
* @Date 15:28 2021/1/14
**/
public AjaxResult sendMessage(byte[] byteData, String orderNo) {
logger.info("进入发送message方法(),命令号是:" + orderNo);
try {
// 指定不同的连接请求发送不同的命令
for (Map<String, ChannelHandlerContext> ctxMap : ServerHandler.ctxMaps) {
// 判断匹配的连接
if (ctxMap.containsKey(orderNo)) {
// 获取匹配的连接
ChannelHandlerContext ctx = ctxMap.get(orderNo);
if (ctx == null) {
return AjaxResult.error("请确保打开TCP连接操作!");
}
// netty需要转换ByteBuf才可使用
ByteBuf bytebuf = Unpooled.buffer();
bytebuf.writeBytes(byteData);
ServerHandler.isAccess = true;
// 根据获取到的连接发送消息
ctx.writeAndFlush(bytebuf);
String ip = IpCabinetBind.findOrderNoByIp(orderNo);
String msg = "给Ip为:" + ip + "发送了命令号是" + orderNo + "指令";
logger.info(msg);
Session session = WebSocketServer.sessionPools.get("android");
if (session != null) {
boolean isSucc = WebSocketServer.sendMessage(session, msg);
}
}
}
} catch (Exception e) {
e.printStackTrace();
ServerHandler.isAccess = false;
return AjaxResult.error("服务器报错!发送指令失败!");
}
return null;
}