api-fixbug修改数据类型,fix存储links线程问题
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -34,7 +34,7 @@ public class Constant {
|
||||
/**
|
||||
* 哪些接口不需要增加 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"});
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@ import com.sv.dto.app.VenueLessonStatus;
|
||||
import com.sv.entity.Venue;
|
||||
import com.sv.service.api.VenueLessonService;
|
||||
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.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
package com.sv.netty.controller;
|
||||
|
||||
import com.enums.DeviceType;
|
||||
import com.enums.VenueTypeEnum;
|
||||
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.netty.message.MessageDTO;
|
||||
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.ydd.framework.core.common.dto.ResponseDTO;
|
||||
import com.ydd.framework.core.controller.BaseApiController;
|
||||
import com.ydd.framework.core.exception.ServiceException;
|
||||
import io.netty.channel.Channel;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -42,13 +38,12 @@ public class QREnterController extends BaseApiController {
|
||||
DeviceType enterOrOut = getEnterOrOut(deviceId);
|
||||
Venue venue = qrCodeService.initEnter(venueId, deviceName,enterOrOut);
|
||||
if (venue!=null){
|
||||
Channel channel = ClientChannelCache.getCurrentChannel(deviceName,venueId ,enterOrOut);
|
||||
if (DeviceType.OUT == enterOrOut){
|
||||
// 出场
|
||||
messageService.outVenue(deviceName,venueId,memberId,venue,channel);
|
||||
messageService.outVenue(deviceName,venueId,memberId,venue);
|
||||
}else{
|
||||
// 进场
|
||||
messageService.enterVenue(deviceName,venueId,memberId,venue,channel);
|
||||
messageService.enterVenue(deviceName,venueId,memberId,venue);
|
||||
}
|
||||
}
|
||||
return ResponseDTO.ok();
|
||||
@@ -65,8 +60,7 @@ public class QREnterController extends BaseApiController {
|
||||
String deviceName = getDeviceName(deviceId);
|
||||
DeviceType enterOrOut = getEnterOrOut(deviceId);
|
||||
Venue venue = qrCodeService.initEnter(venueId, deviceName,enterOrOut);
|
||||
Channel channel = ClientChannelCache.getCurrentChannel(deviceName,venueId ,enterOrOut);
|
||||
messageService.sendLoading(channel,memberId);
|
||||
messageService.sendLoading(deviceName,venueId ,enterOrOut,memberId);
|
||||
return ResponseDTO.ok().addAttribute("venueInit", venue);
|
||||
}
|
||||
|
||||
@@ -122,14 +116,11 @@ public class QREnterController extends BaseApiController {
|
||||
*/
|
||||
@RequestMapping("/checkAlive")
|
||||
public ResponseDTO checkAlive(@RequestParam String id) {
|
||||
System.out.println(ClientChannelCache.channel.size());
|
||||
Integer venueId = getVenueId(id);
|
||||
String deviceName = getDeviceName(id);
|
||||
DeviceType enterOrOut = getEnterOrOut(id);
|
||||
Channel channel = ClientChannelCache.getCurrentChannel(deviceName,venueId,enterOrOut);
|
||||
logger.info("验证设备"+ id + "通讯情况");
|
||||
MessageDTO messageDTO = new MessageDTO(MessageType.LOAD,"测试信息123");
|
||||
channel.writeAndFlush(messageDTO);
|
||||
messageService.testLoad(deviceName,venueId,enterOrOut);
|
||||
return ResponseDTO.ok();
|
||||
}
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ public class ServerHandler extends SimpleChannelInboundHandler<String> {
|
||||
logger.info("客户端" + hb.getDeviceName() + "&" + hb.getVenueId() + "【" + clientIp + "】上报心跳...");
|
||||
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().setDeviceType(hb.getEnterOrOut());
|
||||
ctx.channel().attr(Constant.CHANNEL_PARAM).get().setDeviceType(DeviceType.valueOf(hb.getDeviceType()));
|
||||
messageService.online(clientIp,ctx.channel(), hb);
|
||||
} catch (Exception e) {
|
||||
logger.error("[" + clientIp + "] host unknown error",e);
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
package com.sv.netty.netty.message;
|
||||
|
||||
|
||||
import com.enums.DeviceType;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 客户端心跳数据包
|
||||
* HeartBeat.java
|
||||
@@ -17,7 +14,7 @@ public class HeartBeat implements Serializable {
|
||||
|
||||
private String deviceName; //设备号
|
||||
|
||||
private DeviceType EnterOrOut; //出入标志
|
||||
private String deviceType; //出入标志
|
||||
|
||||
public Integer getVenueId() {
|
||||
return venueId;
|
||||
@@ -35,11 +32,11 @@ public class HeartBeat implements Serializable {
|
||||
this.deviceName = deviceName;
|
||||
}
|
||||
|
||||
public DeviceType getEnterOrOut() {
|
||||
return EnterOrOut;
|
||||
public String getDeviceType() {
|
||||
return deviceType;
|
||||
}
|
||||
|
||||
public void setEnterOrOut(DeviceType enterOrOut) {
|
||||
EnterOrOut = enterOrOut;
|
||||
public void setDeviceType(String deviceType) {
|
||||
this.deviceType = deviceType;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ public interface MessageService {
|
||||
*/
|
||||
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 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 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);
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ import com.enums.DeviceType;
|
||||
import com.sv.entity.Member;
|
||||
import com.sv.entity.MemberEnterVenueLog;
|
||||
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.netty.message.HeartBeat;
|
||||
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.ydd.oms.entity.sys.Config;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.util.internal.PlatformDependent;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.stereotype.Service;
|
||||
@@ -25,6 +26,7 @@ import org.springframework.web.client.RestTemplate;
|
||||
import javax.annotation.Resource;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@@ -40,6 +42,13 @@ public class AppMessageHandlerAdapter implements MessageService {
|
||||
|
||||
private Logger logger = LoggerFactory.getLogger(AppMessageHandlerAdapter.class);
|
||||
|
||||
/**
|
||||
* 存储设备通道类型
|
||||
* 此处存储客户端的channel 信息key 为 【deviceId + venueId】
|
||||
* value: 1Tcp 2WebSocket
|
||||
*/
|
||||
private ConcurrentMap<String, Channel> links = PlatformDependent.newConcurrentHashMap();
|
||||
|
||||
@Resource
|
||||
private MemberService memberService;
|
||||
|
||||
@@ -69,15 +78,16 @@ public class AppMessageHandlerAdapter implements MessageService {
|
||||
*/
|
||||
@Override
|
||||
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
|
||||
Venue thisVenue = venueService.findById(heartBeat.getVenueId());
|
||||
if (thisVenue == null ){
|
||||
logger.error("this client choose venue Error! venueId == " + heartBeat.getVenueId());
|
||||
} else {
|
||||
deviceService.online(heartBeat.getDeviceName(),heartBeat.getVenueId(),heartBeat.getEnterOrOut(),thisVenue.getType(),clientId);
|
||||
ClientChannelCache.putChannelType(heartBeat.getDeviceName(),heartBeat.getVenueId(),heartBeat.getEnterOrOut(),channel);
|
||||
deviceService.online(heartBeat.getDeviceName(),heartBeat.getVenueId(),deviceType,thisVenue.getType(),clientId);
|
||||
putChannelType(heartBeat.getDeviceName(),heartBeat.getVenueId(),deviceType,channel);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -90,40 +100,43 @@ public class AppMessageHandlerAdapter implements MessageService {
|
||||
@Override
|
||||
public void Offline(String deviceName, Integer venueId,DeviceType deviceType) {
|
||||
if (deviceName != null && venueId != null){
|
||||
ClientChannelCache.removeChannelType(deviceName,venueId,deviceType);
|
||||
removeChannelType(deviceName,venueId,deviceType);
|
||||
deviceService.offline(deviceName,venueId,deviceType);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 统计目前有多少链接数
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public Set<String> countConnection() {
|
||||
return ClientChannelCache.channel.keySet();
|
||||
}
|
||||
|
||||
/**
|
||||
* 通知客户端进入加载页面
|
||||
* @param memberId
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public boolean sendLoading(Channel channel, Integer memberId) {
|
||||
public boolean sendLoading(String deviceName, Integer venueId,DeviceType deviceType, Integer memberId) {
|
||||
Member thisMember = memberService.findByMember(memberId);
|
||||
if (thisMember!=null){
|
||||
String nickname = thisMember.getNickname();
|
||||
MessageDTO messageDTO = new MessageDTO(MessageType.LOAD,"欢迎光临!" + nickname);
|
||||
sendMessage(channel,messageDTO);
|
||||
Channel currentChannel = getCurrentChannel(deviceName, venueId, deviceType);
|
||||
sendMessage(currentChannel,messageDTO);
|
||||
return true;
|
||||
}
|
||||
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
|
||||
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);
|
||||
if (member != null) {
|
||||
//出场 不用判断直接出
|
||||
@@ -164,9 +177,10 @@ public class AppMessageHandlerAdapter implements MessageService {
|
||||
* @param venue
|
||||
*/
|
||||
@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);
|
||||
// 校验入场时间是否正常
|
||||
Channel channel = getCurrentChannel(deviceName, venueId, DeviceType.ENTER);
|
||||
// 校验入场时间是否正常
|
||||
if (checkInterval(member,venueId)) {
|
||||
if(venueService.qrCodeEnterVenue(memberId,deviceName,venueId,venue)){
|
||||
// 可以进场
|
||||
@@ -250,4 +264,47 @@ public class AppMessageHandlerAdapter implements MessageService {
|
||||
// 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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package com.test.netty.client;
|
||||
|
||||
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.MessageDTO;
|
||||
import io.netty.channel.Channel;
|
||||
@@ -92,7 +91,7 @@ public class ClientHandler extends SimpleChannelInboundHandler<String> {
|
||||
// hb.setDeviceName("DeviceIdUtil.generateDeviceId(mContext)");
|
||||
hb.setDeviceName("shebeiweiyishibiehao");
|
||||
hb.setVenueId(32); // TODO
|
||||
hb.setEnterOrOut(DeviceType.ENTER);
|
||||
hb.setDeviceType("ENTER");
|
||||
return hb;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.test.netty.client;
|
||||
|
||||
import com.sv.netty.config.Constant;
|
||||
import com.sv.netty.netty.message.HeartBeat;
|
||||
import com.sv.netty.utils.JsonUtils;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
@@ -26,5 +27,11 @@ public class MessageEncoder extends MessageToByteEncoder {
|
||||
byte[] content = message.getBytes(charset.name());
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -19,7 +19,7 @@ public class HeartBeat implements Serializable {
|
||||
private String deviceName; //设备号
|
||||
|
||||
@Expose
|
||||
private DeviceType EnterOrOut; //出入标志
|
||||
private String deviceType; //出入标志
|
||||
|
||||
public Integer getVenueId() {
|
||||
return venueId;
|
||||
@@ -37,11 +37,11 @@ public class HeartBeat implements Serializable {
|
||||
this.deviceName = deviceName;
|
||||
}
|
||||
|
||||
public DeviceType getEnterOrOut() {
|
||||
return EnterOrOut;
|
||||
public String getDeviceType() {
|
||||
return deviceType;
|
||||
}
|
||||
|
||||
public void setEnterOrOut(DeviceType enterOrOut) {
|
||||
EnterOrOut = enterOrOut;
|
||||
public void setDeviceType(String deviceType) {
|
||||
this.deviceType = deviceType;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -422,7 +422,7 @@ public class VenueService extends BaseServiceImpl {
|
||||
log.setVeneuType(device.getVenueType());
|
||||
log.setVenueId(device.getVenueId());
|
||||
log.setPlatformId(member.getPlatformId());
|
||||
log.setType(DeviceType.ENTER.getCode());
|
||||
log.setType(0);
|
||||
//进场之前 查看是否有会员卡
|
||||
List<MemberCard> cards = memberCardService.findByMemberId(device.getVenueId(), member.getId());
|
||||
if (cards.size() > 0) {
|
||||
|
||||
Reference in New Issue
Block a user