api-fixbug修改数据类型,fix存储links线程问题

This commit is contained in:
limqhz
2020-08-01 21:55:05 +08:00
parent 393ef2ddd5
commit b51398129e
13 changed files with 106 additions and 136 deletions

View File

@@ -1,49 +0,0 @@
package com.sv.netty.config;
import com.enums.DeviceType;
import io.netty.channel.Channel;
import io.netty.util.internal.PlatformDependent;
import java.util.concurrent.ConcurrentMap;
public class ClientChannelCache {
/**
* 存储设备通道类型
* 此处存储客户端的channel 信息key 为 【deviceId + venueId】
* value: 1Tcp 2WebSocket
*/
public static final ConcurrentMap<String, Channel> channel = PlatformDependent.newConcurrentHashMap();
/**
* 缓存通道
*/
public static void putChannelType(String deviceName, Integer venueId, DeviceType deviceType, Channel channel) {
String clientId = deviceName + Constant.SPIT_WORD + venueId + Constant.SPIT_WORD + deviceType;
ClientChannelCache.channel.put(clientId, channel);
}
/**
* 获取当前通道
*/
public static Channel getCurrentChannel(String deviceName, Integer venueId, DeviceType deviceType){
String clientId = deviceName + Constant.SPIT_WORD + venueId + Constant.SPIT_WORD + deviceType;
return channel.get(clientId);
}
/**
* 获取通道
*/
public static boolean contains(String deviceName, Integer venueId, DeviceType deviceType) {
String clientId = deviceName + Constant.SPIT_WORD + venueId + Constant.SPIT_WORD + deviceType;
return channel.containsKey(clientId);
}
/**
* 移除通道
*/
public static void removeChannelType(String deviceName, Integer venueId, DeviceType deviceType) {
String clientId = deviceName + Constant.SPIT_WORD + venueId + Constant.SPIT_WORD + deviceType;
channel.remove(clientId);
}
}

View File

@@ -34,7 +34,7 @@ public class Constant {
/** /**
* 哪些接口不需要增加 platform 平台限制 * 哪些接口不需要增加 platform 平台限制
*/ */
public static final List<String> executeControllerList = Arrays.asList(new String [] {"/qrCode/init"}); public static final List<String> executeControllerList = Arrays.asList(new String [] {"/qrCode/init","/qrCode/enter"});
} }

View File

@@ -5,7 +5,6 @@ import com.sv.dto.app.VenueLessonStatus;
import com.sv.entity.Venue; import com.sv.entity.Venue;
import com.sv.service.api.VenueLessonService; import com.sv.service.api.VenueLessonService;
import com.sv.service.oms.VenueService; import com.sv.service.oms.VenueService;
import com.ydd.framework.core.common.dto.ResponseDTO;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestMethod;

View File

@@ -1,10 +1,7 @@
package com.sv.netty.controller; package com.sv.netty.controller;
import com.enums.DeviceType; import com.enums.DeviceType;
import com.enums.VenueTypeEnum;
import com.sv.entity.Venue; import com.sv.entity.Venue;
import com.sv.entity.VenueType;
import com.sv.netty.config.ClientChannelCache;
import com.sv.netty.config.Constant; import com.sv.netty.config.Constant;
import com.sv.netty.netty.message.MessageDTO; import com.sv.netty.netty.message.MessageDTO;
import com.sv.netty.netty.message.MessageType; import com.sv.netty.netty.message.MessageType;
@@ -12,7 +9,6 @@ import com.sv.netty.netty.service.MessageService;
import com.sv.service.api.QRCodeService; import com.sv.service.api.QRCodeService;
import com.ydd.framework.core.common.dto.ResponseDTO; import com.ydd.framework.core.common.dto.ResponseDTO;
import com.ydd.framework.core.controller.BaseApiController; import com.ydd.framework.core.controller.BaseApiController;
import com.ydd.framework.core.exception.ServiceException;
import io.netty.channel.Channel; import io.netty.channel.Channel;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@@ -42,13 +38,12 @@ public class QREnterController extends BaseApiController {
DeviceType enterOrOut = getEnterOrOut(deviceId); DeviceType enterOrOut = getEnterOrOut(deviceId);
Venue venue = qrCodeService.initEnter(venueId, deviceName,enterOrOut); Venue venue = qrCodeService.initEnter(venueId, deviceName,enterOrOut);
if (venue!=null){ if (venue!=null){
Channel channel = ClientChannelCache.getCurrentChannel(deviceName,venueId ,enterOrOut);
if (DeviceType.OUT == enterOrOut){ if (DeviceType.OUT == enterOrOut){
// 出场 // 出场
messageService.outVenue(deviceName,venueId,memberId,venue,channel); messageService.outVenue(deviceName,venueId,memberId,venue);
}else{ }else{
// 进场 // 进场
messageService.enterVenue(deviceName,venueId,memberId,venue,channel); messageService.enterVenue(deviceName,venueId,memberId,venue);
} }
} }
return ResponseDTO.ok(); return ResponseDTO.ok();
@@ -65,8 +60,7 @@ public class QREnterController extends BaseApiController {
String deviceName = getDeviceName(deviceId); String deviceName = getDeviceName(deviceId);
DeviceType enterOrOut = getEnterOrOut(deviceId); DeviceType enterOrOut = getEnterOrOut(deviceId);
Venue venue = qrCodeService.initEnter(venueId, deviceName,enterOrOut); Venue venue = qrCodeService.initEnter(venueId, deviceName,enterOrOut);
Channel channel = ClientChannelCache.getCurrentChannel(deviceName,venueId ,enterOrOut); messageService.sendLoading(deviceName,venueId ,enterOrOut,memberId);
messageService.sendLoading(channel,memberId);
return ResponseDTO.ok().addAttribute("venueInit", venue); return ResponseDTO.ok().addAttribute("venueInit", venue);
} }
@@ -122,14 +116,11 @@ public class QREnterController extends BaseApiController {
*/ */
@RequestMapping("/checkAlive") @RequestMapping("/checkAlive")
public ResponseDTO checkAlive(@RequestParam String id) { public ResponseDTO checkAlive(@RequestParam String id) {
System.out.println(ClientChannelCache.channel.size());
Integer venueId = getVenueId(id); Integer venueId = getVenueId(id);
String deviceName = getDeviceName(id); String deviceName = getDeviceName(id);
DeviceType enterOrOut = getEnterOrOut(id); DeviceType enterOrOut = getEnterOrOut(id);
Channel channel = ClientChannelCache.getCurrentChannel(deviceName,venueId,enterOrOut);
logger.info("验证设备"+ id + "通讯情况"); logger.info("验证设备"+ id + "通讯情况");
MessageDTO messageDTO = new MessageDTO(MessageType.LOAD,"测试信息123"); messageService.testLoad(deviceName,venueId,enterOrOut);
channel.writeAndFlush(messageDTO);
return ResponseDTO.ok(); return ResponseDTO.ok();
} }

View File

@@ -54,7 +54,7 @@ public class ServerHandler extends SimpleChannelInboundHandler<String> {
logger.info("客户端" + hb.getDeviceName() + "&" + hb.getVenueId() + "" + clientIp + "】上报心跳..."); logger.info("客户端" + hb.getDeviceName() + "&" + hb.getVenueId() + "" + clientIp + "】上报心跳...");
ctx.channel().attr(Constant.CHANNEL_PARAM).get().setVenueId(hb.getVenueId()); ctx.channel().attr(Constant.CHANNEL_PARAM).get().setVenueId(hb.getVenueId());
ctx.channel().attr(Constant.CHANNEL_PARAM).get().setDeviceName(hb.getDeviceName()); ctx.channel().attr(Constant.CHANNEL_PARAM).get().setDeviceName(hb.getDeviceName());
ctx.channel().attr(Constant.CHANNEL_PARAM).get().setDeviceType(hb.getEnterOrOut()); ctx.channel().attr(Constant.CHANNEL_PARAM).get().setDeviceType(DeviceType.valueOf(hb.getDeviceType()));
messageService.online(clientIp,ctx.channel(), hb); messageService.online(clientIp,ctx.channel(), hb);
} catch (Exception e) { } catch (Exception e) {
logger.error("[" + clientIp + "] host unknown error",e); logger.error("[" + clientIp + "] host unknown error",e);

View File

@@ -1,9 +1,6 @@
package com.sv.netty.netty.message; package com.sv.netty.netty.message;
import com.enums.DeviceType;
import java.io.Serializable; import java.io.Serializable;
/** /**
* 客户端心跳数据包 * 客户端心跳数据包
* HeartBeat.java * HeartBeat.java
@@ -17,7 +14,7 @@ public class HeartBeat implements Serializable {
private String deviceName; //设备号 private String deviceName; //设备号
private DeviceType EnterOrOut; //出入标志 private String deviceType; //出入标志
public Integer getVenueId() { public Integer getVenueId() {
return venueId; return venueId;
@@ -35,11 +32,11 @@ public class HeartBeat implements Serializable {
this.deviceName = deviceName; this.deviceName = deviceName;
} }
public DeviceType getEnterOrOut() { public String getDeviceType() {
return EnterOrOut; return deviceType;
} }
public void setEnterOrOut(DeviceType enterOrOut) { public void setDeviceType(String deviceType) {
EnterOrOut = enterOrOut; this.deviceType = deviceType;
} }
} }

View File

@@ -37,7 +37,7 @@ public interface MessageService {
*/ */
Set<String> countConnection(); Set<String> countConnection();
boolean sendLoading(Channel channel, Integer memberId); boolean sendLoading(String deviceName, Integer venueId,DeviceType deviceType, Integer memberId);
/** /**
* 出场 * 出场
@@ -46,7 +46,7 @@ public interface MessageService {
* @param memberId * @param memberId
* @param venue * @param venue
*/ */
void outVenue(String deviceName, Integer venueId, Integer memberId, Venue venue,Channel channel); void outVenue(String deviceName, Integer venueId, Integer memberId, Venue venue);
/** /**
* 进场 * 进场
@@ -55,5 +55,7 @@ public interface MessageService {
* @param memberId * @param memberId
* @param venue * @param venue
*/ */
void enterVenue(String deviceName, Integer venueId, Integer memberId, Venue venue,Channel channel); void enterVenue(String deviceName, Integer venueId, Integer memberId, Venue venue);
void testLoad(String deviceName, Integer venueId,DeviceType deviceType);
} }

View File

@@ -4,7 +4,7 @@ import com.enums.DeviceType;
import com.sv.entity.Member; import com.sv.entity.Member;
import com.sv.entity.MemberEnterVenueLog; import com.sv.entity.MemberEnterVenueLog;
import com.sv.entity.Venue; import com.sv.entity.Venue;
import com.sv.netty.config.ClientChannelCache; import com.sv.netty.config.Constant;
import com.sv.netty.config.ErrorCode; import com.sv.netty.config.ErrorCode;
import com.sv.netty.netty.message.HeartBeat; import com.sv.netty.netty.message.HeartBeat;
import com.sv.netty.netty.message.MessageDTO; import com.sv.netty.netty.message.MessageDTO;
@@ -17,6 +17,7 @@ import com.sv.service.oms.ConfigService;
import com.sv.service.oms.DeviceService; import com.sv.service.oms.DeviceService;
import com.ydd.oms.entity.sys.Config; import com.ydd.oms.entity.sys.Config;
import io.netty.channel.Channel; import io.netty.channel.Channel;
import io.netty.util.internal.PlatformDependent;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@@ -25,6 +26,7 @@ import org.springframework.web.client.RestTemplate;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.text.MessageFormat; import java.text.MessageFormat;
import java.util.*; import java.util.*;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@@ -40,6 +42,13 @@ public class AppMessageHandlerAdapter implements MessageService {
private Logger logger = LoggerFactory.getLogger(AppMessageHandlerAdapter.class); private Logger logger = LoggerFactory.getLogger(AppMessageHandlerAdapter.class);
/**
* 存储设备通道类型
* 此处存储客户端的channel 信息key 为 【deviceId + venueId】
* value: 1Tcp 2WebSocket
*/
private ConcurrentMap<String, Channel> links = PlatformDependent.newConcurrentHashMap();
@Resource @Resource
private MemberService memberService; private MemberService memberService;
@@ -69,15 +78,16 @@ public class AppMessageHandlerAdapter implements MessageService {
*/ */
@Override @Override
public void online(String clientId, Channel channel, HeartBeat heartBeat) { public void online(String clientId, Channel channel, HeartBeat heartBeat) {
DeviceType deviceType = DeviceType.valueOf(heartBeat.getDeviceType());
// 处理心跳信息 // 处理心跳信息
if (!ClientChannelCache.contains(heartBeat.getDeviceName(),heartBeat.getVenueId(),heartBeat.getEnterOrOut())){ if (!contains(heartBeat.getDeviceName(),heartBeat.getVenueId(),deviceType)){
// 此处存储客户端的channel 信息key 为 deviceId + venueId // 此处存储客户端的channel 信息key 为 deviceId + venueId
Venue thisVenue = venueService.findById(heartBeat.getVenueId()); Venue thisVenue = venueService.findById(heartBeat.getVenueId());
if (thisVenue == null ){ if (thisVenue == null ){
logger.error("this client choose venue Error! venueId == " + heartBeat.getVenueId()); logger.error("this client choose venue Error! venueId == " + heartBeat.getVenueId());
} else { } else {
deviceService.online(heartBeat.getDeviceName(),heartBeat.getVenueId(),heartBeat.getEnterOrOut(),thisVenue.getType(),clientId); deviceService.online(heartBeat.getDeviceName(),heartBeat.getVenueId(),deviceType,thisVenue.getType(),clientId);
ClientChannelCache.putChannelType(heartBeat.getDeviceName(),heartBeat.getVenueId(),heartBeat.getEnterOrOut(),channel); putChannelType(heartBeat.getDeviceName(),heartBeat.getVenueId(),deviceType,channel);
} }
} }
} }
@@ -90,40 +100,43 @@ public class AppMessageHandlerAdapter implements MessageService {
@Override @Override
public void Offline(String deviceName, Integer venueId,DeviceType deviceType) { public void Offline(String deviceName, Integer venueId,DeviceType deviceType) {
if (deviceName != null && venueId != null){ if (deviceName != null && venueId != null){
ClientChannelCache.removeChannelType(deviceName,venueId,deviceType); removeChannelType(deviceName,venueId,deviceType);
deviceService.offline(deviceName,venueId,deviceType); deviceService.offline(deviceName,venueId,deviceType);
} }
} }
/**
* 统计目前有多少链接数
* @return
*/
@Override
public Set<String> countConnection() {
return ClientChannelCache.channel.keySet();
}
/** /**
* 通知客户端进入加载页面 * 通知客户端进入加载页面
* @param memberId * @param memberId
* @return * @return
*/ */
@Override @Override
public boolean sendLoading(Channel channel, Integer memberId) { public boolean sendLoading(String deviceName, Integer venueId,DeviceType deviceType, Integer memberId) {
Member thisMember = memberService.findByMember(memberId); Member thisMember = memberService.findByMember(memberId);
if (thisMember!=null){ if (thisMember!=null){
String nickname = thisMember.getNickname(); String nickname = thisMember.getNickname();
MessageDTO messageDTO = new MessageDTO(MessageType.LOAD,"欢迎光临!" + nickname); MessageDTO messageDTO = new MessageDTO(MessageType.LOAD,"欢迎光临!" + nickname);
sendMessage(channel,messageDTO); Channel currentChannel = getCurrentChannel(deviceName, venueId, deviceType);
sendMessage(currentChannel,messageDTO);
return true; return true;
} }
return false; return false;
} }
/**
* 测试客户端连接
* @return
*/
@Override
public void testLoad(String deviceName, Integer venueId,DeviceType deviceType) {
Channel currentChannel = getCurrentChannel(deviceName, venueId, deviceType);
currentChannel.writeAndFlush("Test Links" + deviceName + venueId + deviceType);
}
@Override @Override
public void outVenue(String deviceName, Integer venueId, Integer memberId, Venue venue,Channel channel) { public void outVenue(String deviceName, Integer venueId, Integer memberId, Venue venue) {
Channel channel = getCurrentChannel(deviceName,venueId,DeviceType.OUT);
Member member = memberService.findByMember(memberId); Member member = memberService.findByMember(memberId);
if (member != null) { if (member != null) {
//出场 不用判断直接出 //出场 不用判断直接出
@@ -164,9 +177,10 @@ public class AppMessageHandlerAdapter implements MessageService {
* @param venue * @param venue
*/ */
@Override @Override
public void enterVenue(String deviceName, Integer venueId, Integer memberId, Venue venue,Channel channel) { public void enterVenue(String deviceName, Integer venueId, Integer memberId, Venue venue) {
Member member = memberService.findByMember(memberId); Member member = memberService.findByMember(memberId);
// 校验入场时间是否正常 Channel channel = getCurrentChannel(deviceName, venueId, DeviceType.ENTER);
// 校验入场时间是否正常
if (checkInterval(member,venueId)) { if (checkInterval(member,venueId)) {
if(venueService.qrCodeEnterVenue(memberId,deviceName,venueId,venue)){ if(venueService.qrCodeEnterVenue(memberId,deviceName,venueId,venue)){
// 可以进场 // 可以进场
@@ -250,4 +264,47 @@ public class AppMessageHandlerAdapter implements MessageService {
// logger.info("灯光结果" + JsonMapper.nonDefaultMapper().toJson(result)); // logger.info("灯光结果" + JsonMapper.nonDefaultMapper().toJson(result));
} }
/**
* 操作连接
*/
/**
* 缓存通道
*/
public void putChannelType(String deviceName, Integer venueId, DeviceType deviceType, Channel channel) {
String clientId = deviceName + Constant.SPIT_WORD + venueId + Constant.SPIT_WORD + deviceType;
links.put(clientId, channel);
}
/**
* 获取当前通道
*/
public Channel getCurrentChannel(String deviceName, Integer venueId, DeviceType deviceType){
String clientId = deviceName + Constant.SPIT_WORD + venueId + Constant.SPIT_WORD + deviceType;
return links.get(clientId);
}
/**
* 获取通道
*/
public boolean contains(String deviceName, Integer venueId, DeviceType deviceType) {
String clientId = deviceName + Constant.SPIT_WORD + venueId + Constant.SPIT_WORD + deviceType;
return links.containsKey(clientId);
}
/**
* 移除通道
*/
public void removeChannelType(String deviceName, Integer venueId, DeviceType deviceType) {
String clientId = deviceName + Constant.SPIT_WORD + venueId + Constant.SPIT_WORD + deviceType;
links.remove(clientId);
}
/**
* 统计目前有多少链接数
* @return
*/
@Override
public Set<String> countConnection() {
return links.keySet();
}
} }

View File

@@ -1,7 +1,6 @@
package com.test.netty.client; package com.test.netty.client;
import com.sv.netty.utils.JsonUtils; import com.sv.netty.utils.JsonUtils;
import com.test.netty.client.message.DeviceType;
import com.test.netty.client.message.HeartBeat; import com.test.netty.client.message.HeartBeat;
import com.test.netty.client.message.MessageDTO; import com.test.netty.client.message.MessageDTO;
import io.netty.channel.Channel; import io.netty.channel.Channel;
@@ -92,7 +91,7 @@ public class ClientHandler extends SimpleChannelInboundHandler<String> {
// hb.setDeviceName("DeviceIdUtil.generateDeviceId(mContext)"); // hb.setDeviceName("DeviceIdUtil.generateDeviceId(mContext)");
hb.setDeviceName("shebeiweiyishibiehao"); hb.setDeviceName("shebeiweiyishibiehao");
hb.setVenueId(32); // TODO hb.setVenueId(32); // TODO
hb.setEnterOrOut(DeviceType.ENTER); hb.setDeviceType("ENTER");
return hb; return hb;
} }

View File

@@ -1,6 +1,7 @@
package com.test.netty.client; package com.test.netty.client;
import com.sv.netty.config.Constant; import com.sv.netty.config.Constant;
import com.sv.netty.netty.message.HeartBeat;
import com.sv.netty.utils.JsonUtils; import com.sv.netty.utils.JsonUtils;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
@@ -26,5 +27,11 @@ public class MessageEncoder extends MessageToByteEncoder {
byte[] content = message.getBytes(charset.name()); byte[] content = message.getBytes(charset.name());
out.writeBytes(content); //发送消息内容 out.writeBytes(content); //发送消息内容
} }
public static void main(String[] args) {
String hello = "{\"deviceType\":\"ENTER\",\"deviceName\":\"MGX5T17907001718\",\"venueId\":41}";
HeartBeat hb = JsonUtils.decode(hello,HeartBeat.class);
System.out.println(hb);
}
} }

View File

@@ -1,33 +0,0 @@
package com.test.netty.client.message;
/**
* 设备属性,控制入场还是控制出场
*/
public enum DeviceType {
ENTER(0,"进场"),
OUT(1,"出场");
private int code;
private String name;
DeviceType(int code, String name) {
this.code = code;
this.name = name;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

View File

@@ -19,7 +19,7 @@ public class HeartBeat implements Serializable {
private String deviceName; //设备号 private String deviceName; //设备号
@Expose @Expose
private DeviceType EnterOrOut; //出入标志 private String deviceType; //出入标志
public Integer getVenueId() { public Integer getVenueId() {
return venueId; return venueId;
@@ -37,11 +37,11 @@ public class HeartBeat implements Serializable {
this.deviceName = deviceName; this.deviceName = deviceName;
} }
public DeviceType getEnterOrOut() { public String getDeviceType() {
return EnterOrOut; return deviceType;
} }
public void setEnterOrOut(DeviceType enterOrOut) { public void setDeviceType(String deviceType) {
EnterOrOut = enterOrOut; this.deviceType = deviceType;
} }
} }

View File

@@ -422,7 +422,7 @@ public class VenueService extends BaseServiceImpl {
log.setVeneuType(device.getVenueType()); log.setVeneuType(device.getVenueType());
log.setVenueId(device.getVenueId()); log.setVenueId(device.getVenueId());
log.setPlatformId(member.getPlatformId()); log.setPlatformId(member.getPlatformId());
log.setType(DeviceType.ENTER.getCode()); log.setType(0);
//进场之前 查看是否有会员卡 //进场之前 查看是否有会员卡
List<MemberCard> cards = memberCardService.findByMemberId(device.getVenueId(), member.getId()); List<MemberCard> cards = memberCardService.findByMemberId(device.getVenueId(), member.getId());
if (cards.size() > 0) { if (cards.size() > 0) {