api-设备唯一Id 修改为 设备号 + 场馆号 + 进场OR出场

This commit is contained in:
limqhz
2020-07-23 16:39:58 +08:00
parent ade7baaa6b
commit 16e2f04c38
17 changed files with 125 additions and 265 deletions

View File

@@ -17,7 +17,8 @@ public class ClientChannelCache {
/**
* 缓存通道
*/
public static void putChannelType(String clientId, Channel channel) {
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);
}
@@ -25,28 +26,24 @@ public class ClientChannelCache {
* 获取当前通道
*/
public static Channel getCurrentChannel(String deviceName, Integer venueId, DeviceType deviceType){
String clientId = deviceName + Constant.SPIT_WORD + venueId + Constant.SPIT_WORD + deviceType.getCode();
return getCurrentChannel(clientId);
String clientId = deviceName + Constant.SPIT_WORD + venueId + Constant.SPIT_WORD + deviceType;
return channel.get(clientId);
}
/**
* 获取通道
*/
public static Channel getCurrentChannel(String clientId) {
return channel.get(clientId);
}
/**
* 判断通道是否存在
*/
public static boolean contains(String 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 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

@@ -1,54 +0,0 @@
package com.sv.netty.controller;
import com.sv.netty.config.ClientChannelCache;
import com.sv.netty.config.ErrorCode;
import com.sv.netty.netty.message.MessageDTO;
import com.sv.netty.netty.message.MessageType;
import com.ydd.framework.core.common.dto.ResponseDTO;
import io.netty.channel.Channel;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class QRCodeControler {
/**
* 废弃
* @return
*/
@RequestMapping("/scanQRCode")
public ResponseDTO scanQRCode(@RequestParam String venueId,
@RequestParam String cardType,@RequestParam String memberId) {
// 1、获取到请求说明扫码成功预校验余额成功通知客户端(Android)进行加载状态。
// 2、进行预校验判断是否可以进行扫码通行 // TODO check余额方法
boolean checkResult = true;
if(checkResult){
// 如果是成功的 通知客户端(Android)进行开门
return ResponseDTO.ok();
}else {
return new ResponseDTO(ErrorCode.MEMBER_NOT_EXIST.getCode(),
ErrorCode.MEMBER_NOT_EXIST.getMsg(),System.currentTimeMillis());
}
}
/**
* 检验客户端读取能力
* @return
*/
@RequestMapping("/checkAlive")
public ResponseDTO checkAlive(@RequestParam String id) {
System.out.println(ClientChannelCache.channel.size());
Channel channel = ClientChannelCache.getCurrentChannel(id);
MessageDTO messageDTO = new MessageDTO();
messageDTO.setMessageType(MessageType.LOAD);
messageDTO.setMessage("欢迎光临张三" );
// sendMessage(channel,messageDTO);
// channel.writeAndFlush("check client alive ! ");
channel.writeAndFlush(messageDTO);
return ResponseDTO.ok();
}
}

View File

@@ -6,6 +6,8 @@ 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;
import com.sv.netty.netty.service.MessageService;
import com.sv.service.api.QRCodeService;
import com.ydd.framework.core.common.dto.ResponseDTO;
@@ -38,7 +40,7 @@ public class QREnterController extends BaseApiController {
Integer venueId = getVenueId(deviceId);
String deviceName = getDeviceName(deviceId);
DeviceType enterOrOut = getEnterOrOut(deviceId);
Venue venue = qrCodeService.initEnter(venueId, deviceName);
Venue venue = qrCodeService.initEnter(venueId, deviceName,enterOrOut);
if (venue!=null){
Channel channel = ClientChannelCache.getCurrentChannel(deviceName,venueId ,enterOrOut);
if (DeviceType.OUT == enterOrOut){
@@ -62,7 +64,7 @@ public class QREnterController extends BaseApiController {
Integer venueId = getVenueId(deviceId);
String deviceName = getDeviceName(deviceId);
DeviceType enterOrOut = getEnterOrOut(deviceId);
Venue venue = qrCodeService.initEnter(venueId, deviceName);
Venue venue = qrCodeService.initEnter(venueId, deviceName,enterOrOut);
Channel channel = ClientChannelCache.getCurrentChannel(deviceName,venueId ,enterOrOut);
messageService.sendLoading(channel,memberId);
return ResponseDTO.ok().addAttribute("venueInit", venue);
@@ -114,4 +116,21 @@ public class QREnterController extends BaseApiController {
return returnType;
}
/**
* 检验客户端读取能力
* @return
*/
@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);
return ResponseDTO.ok();
}
}

View File

@@ -1,5 +1,6 @@
package com.sv.netty.netty;
import com.enums.DeviceType;
import com.sv.netty.config.Constant;
import com.sv.netty.config.SpringContextHolder;
import com.sv.netty.netty.message.ChannelParam;
@@ -53,6 +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());
messageService.online(clientIp,ctx.channel(), hb);
} catch (Exception e) {
logger.error("[" + clientIp + "] host unknown error",e);
@@ -83,7 +85,8 @@ public class ServerHandler extends SimpleChannelInboundHandler<String> {
logger.error("Client ip [" + clientIP + "] has inactive");
Integer venueId = ctx.channel().attr(Constant.CHANNEL_PARAM).get().getVenueId();
String deviceName = ctx.channel().attr(Constant.CHANNEL_PARAM).get().getDeviceName();
messageService.Offline(deviceName,venueId);
DeviceType deviceType = ctx.channel().attr(Constant.CHANNEL_PARAM).get().getDeviceType();
messageService.Offline(deviceName,venueId,deviceType);
}
/**
@@ -98,7 +101,8 @@ public class ServerHandler extends SimpleChannelInboundHandler<String> {
Channel channel = ctx.channel();
Integer venueId = ctx.channel().attr(Constant.CHANNEL_PARAM).get().getVenueId();
String deviceName = ctx.channel().attr(Constant.CHANNEL_PARAM).get().getDeviceName();
messageService.Offline(deviceName,venueId);
DeviceType deviceType = ctx.channel().attr(Constant.CHANNEL_PARAM).get().getDeviceType();
messageService.Offline(deviceName,venueId,deviceType);
if(channel.isActive()) {
// 错误产生,关闭连接
ctx.close();

View File

@@ -1,5 +1,7 @@
package com.sv.netty.netty.message;
import com.enums.DeviceType;
/**
* 会话中存储的客户端对象
*
@@ -23,6 +25,12 @@ public class ChannelParam {
*/
private Integer venueId;
/**
* 设备进场出场类型
* @param clientIP
*/
private DeviceType deviceType;
public ChannelParam(String clientIP) {
this.clientIp = clientIP;
}
@@ -50,4 +58,12 @@ public class ChannelParam {
public void setVenueId(Integer venueId) {
this.venueId = venueId;
}
public DeviceType getDeviceType() {
return deviceType;
}
public void setDeviceType(DeviceType deviceType) {
this.deviceType = deviceType;
}
}

View File

@@ -1,8 +1,7 @@
package com.sv.netty.netty.message;
import com.google.gson.annotations.Expose;
import com.enums.DeviceType;
import java.io.Serializable;
/**
@@ -17,10 +16,8 @@ public class HeartBeat implements Serializable {
private Integer venueId; //场馆号
private String deviceName; //设备号
/**
* 进场 ENTER ; 出厂 OUT
*/
private String EnterOrOut; //出入标志
private DeviceType EnterOrOut; //出入标志
public Integer getVenueId() {
return venueId;
@@ -38,11 +35,11 @@ public class HeartBeat implements Serializable {
this.deviceName = deviceName;
}
public String getEnterOrOut() {
public DeviceType getEnterOrOut() {
return EnterOrOut;
}
public void setEnterOrOut(String enterOrOut) {
public void setEnterOrOut(DeviceType enterOrOut) {
EnterOrOut = enterOrOut;
}
}

View File

@@ -29,7 +29,7 @@ public interface MessageService {
* @param deviceName
* @param venueId
*/
void Offline(String deviceName, Integer venueId);
void Offline(String deviceName, Integer venueId,DeviceType deviceType);
/**
* 统计目前的链接数

View File

@@ -70,14 +70,14 @@ public class AppMessageHandlerAdapter implements MessageService {
@Override
public void online(String clientId, Channel channel, HeartBeat heartBeat) {
// 处理心跳信息
if (!ClientChannelCache.contains(heartBeat.getDeviceName()+heartBeat.getVenueId())){
if (!ClientChannelCache.contains(heartBeat.getDeviceName(),heartBeat.getVenueId(),heartBeat.getEnterOrOut())){
// 此处存储客户端的channel 信息key 为 deviceId + venueId
Venue thisVenue = venueService.findById(heartBeat.getVenueId());
if (thisVenue == null ){
logger.error("this client choose venue Error! venueId == " + heartBeat.getVenueId());
} else {
ClientChannelCache.putChannelType(heartBeat.getDeviceName()+heartBeat.getVenueId(),channel);
deviceService.online(heartBeat.getDeviceName(),heartBeat.getVenueId(),thisVenue.getType(),clientId);
ClientChannelCache.putChannelType(heartBeat.getDeviceName(),heartBeat.getVenueId(),heartBeat.getEnterOrOut(),channel);
deviceService.online(heartBeat.getDeviceName(),heartBeat.getVenueId(),heartBeat.getEnterOrOut(),thisVenue.getType(),clientId);
}
}
}
@@ -88,10 +88,10 @@ public class AppMessageHandlerAdapter implements MessageService {
* @param venueId
*/
@Override
public void Offline(String deviceName, Integer venueId) {
public void Offline(String deviceName, Integer venueId,DeviceType deviceType) {
if (deviceName != null && venueId != null){
ClientChannelCache.removeChannelType(deviceName+ venueId);
deviceService.offline(deviceName,venueId);
ClientChannelCache.removeChannelType(deviceName,venueId,deviceType);
deviceService.offline(deviceName,venueId,deviceType);
}
}

View File

@@ -0,0 +1,33 @@
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

@@ -1,8 +1,6 @@
package com.test.netty.client.message;
import com.google.gson.annotations.Expose;
import java.io.Serializable;
/**
@@ -21,10 +19,7 @@ public class HeartBeat implements Serializable {
private String deviceName; //设备号
@Expose
/**
* 进场 ENTER ; 出厂 OUT
*/
private String EnterOrOut; //出入标志
private DeviceType EnterOrOut; //出入标志
public Integer getVenueId() {
return venueId;
@@ -42,11 +37,11 @@ public class HeartBeat implements Serializable {
this.deviceName = deviceName;
}
public String getEnterOrOut() {
public DeviceType getEnterOrOut() {
return EnterOrOut;
}
public void setEnterOrOut(String enterOrOut) {
public void setEnterOrOut(DeviceType enterOrOut) {
EnterOrOut = enterOrOut;
}
}

View File

@@ -1,148 +0,0 @@
package com.test.netty.client.message;
import com.google.gson.annotations.Expose;
import java.io.Serializable;
import java.math.BigDecimal;
/**
* 会员基本信息
* MemberDto.java
*
* @author peakren
* @date 2018/12/20 8:39 PM
*/
public class MemberDto implements Serializable {
/**
* 头像
*/
@Expose
private String avatar;
/**
* 姓名
*/
@Expose
private String name;
/**
* 手机号码
*/
@Expose
private String mobile;
/**
* 余额
*/
@Expose
private BigDecimal amount;
/**
* 场地名称
*/
@Expose
private String placeName;
/**
* 会员卡名称
*/
@Expose
private String cardName;
@Expose
private String message;
/**
* 1成功进场 0不允许进场
*/
@Expose
private int code;
@Expose
private BigDecimal placePrice;
@Expose
private boolean first;
public BigDecimal getPlacePrice() {
return placePrice;
}
public void setPlacePrice(BigDecimal placePrice) {
this.placePrice = placePrice;
}
public boolean isFirst() {
return first;
}
public void setFirst(boolean first) {
this.first = first;
}
public String getAvatar() {
return avatar;
}
public void setAvatar(String avatar) {
this.avatar = avatar;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getMobile() {
return mobile;
}
public void setMobile(String mobile) {
this.mobile = mobile;
}
public BigDecimal getAmount() {
return amount;
}
public void setAmount(BigDecimal amount) {
this.amount = amount;
}
public String getPlaceName() {
return placeName;
}
public void setPlaceName(String placeName) {
this.placeName = placeName;
}
public String getCardName() {
return cardName;
}
public void setCardName(String cardName) {
this.cardName = cardName;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
}

View File

@@ -6,7 +6,11 @@ public class MessageDTO implements Serializable {
private MessageType messageType;
private String message;
private String clientId;
public MessageDTO(MessageType messageType, String message) {
this.messageType = messageType;
this.message = message;
}
public MessageType getMessageType() {
return messageType;
@@ -23,12 +27,4 @@ public class MessageDTO implements Serializable {
public void setMessage(String message) {
this.message = message;
}
public String getClientId() {
return clientId;
}
public void setClientId(String clientId) {
this.clientId = clientId;
}
}

View File

@@ -2,7 +2,8 @@ package com.test.netty.client.message;
public enum MessageType {
LOAD("加载"),
OPENDOOR("开门");
OPENDOOR("开门"),
FAILED("开门校验失败");
private String message;
MessageType(String message) {

View File

@@ -67,15 +67,15 @@ public interface DeviceMapper {
/**
* 更新设备状态为 0 - 未连接
*/
void offline(@Param("venueId") Integer venueId,@Param("deviceName") String deviceName);
void offline(@Param("venueId") Integer venueId,@Param("deviceName") String deviceName,@Param("deviceType")DeviceType deviceType);
/**
* 更新设备状态为 2 - 连接成功
*/
void online(@Param("venueId") Integer venueId,@Param("deviceName") String deviceName);
void online(@Param("venueId") Integer venueId, @Param("deviceName") String deviceName, @Param("deviceType")DeviceType deviceType);
Integer checkDevice(@Param("deviceName") String deviceName,@Param("venueId") Integer venueId);
Integer checkDevice(@Param("deviceName") String deviceName,@Param("venueId") Integer venueId, @Param("deviceType") DeviceType deviceType);
/**
* 根据记录找设备
@@ -84,5 +84,5 @@ public interface DeviceMapper {
* @param deviceType
* @return
*/
Device findByDevice(String deviceName, Integer venueId, DeviceType deviceType);
Device findByDevice(@Param("deviceName") String deviceName,@Param("venueId") Integer venueId,@Param("deviceType") DeviceType deviceType);
}

View File

@@ -26,8 +26,8 @@ public class QRCodeService {
@Resource
private DeviceMapper deviceMapper;
public Venue initEnter(Integer venueId,String deviceName) {
Integer integer = deviceMapper.checkDevice(deviceName, venueId);
public Venue initEnter(Integer venueId,String deviceName,DeviceType deviceType) {
Integer integer = deviceMapper.checkDevice(deviceName, venueId,deviceType);
if (integer != 1){
throw new ServiceException(com.sv.exception.api.ExceptionCodeTemplate.DEVICE_ERROR);
}

View File

@@ -135,24 +135,25 @@ public class DeviceService extends BaseServiceImpl {
* 设备连接断开
*/
@Transactional
public void offline(String deviceName, Integer venueId){
deviceMapper.offline(venueId,deviceName);
public void offline(String deviceName, Integer venueId,DeviceType deviceType){
deviceMapper.offline(venueId,deviceName,deviceType);
}
/**
* 新的设备注册的逻辑
*/
@Transactional
public void online(String deviceName,Integer venueId,Integer venueType,String deviceIp){
public void online(String deviceName,Integer venueId,DeviceType deviceType,Integer venueType,String deviceIp){
Device device = new Device();
device.setVenueId(venueId);
device.setVenueType(venueType);
device.setName(deviceName);
device.setStatus(DeviceStatusEnum.ONLINE.value);
device.setStream(deviceIp);
if(deviceMapper.checkDevice(deviceName,venueId) > 0){
device.setDeviceType(deviceType);
if(deviceMapper.checkDevice(deviceName,venueId,deviceType) > 0){
logger.info(deviceName + venueId + "设备已存在");
deviceMapper.online(venueId, deviceName);
deviceMapper.online(venueId, deviceName,deviceType);
}else {
logger.info("落地客户端信息clientId = " + deviceIp + "&deviceName = " + deviceName + "&venueId = " + venueId);
deviceMapper.insert(device);

View File

@@ -247,13 +247,16 @@
<update id="offline">
UPDATE sv_device set status = 0,modified_time = now()
WHERE name = #{deviceName} and venue_id=#{venueId}
<if test="venueType != null">
and venue_type = #{venueType}
</if>
</update>
<update id="online">
UPDATE sv_device set status = 2,modified_time = now()
WHERE name = #{deviceName} and venue_id=#{venueId}
<if test="venueType != null">
and venue_type = #{venueType},
and venue_type = #{venueType}
</if>
</update>
@@ -261,7 +264,7 @@
SELECT count(1) FROM sv_device
WHERE 1=1 AND name = #{deviceName} and venue_id=#{venueId} and deleted = 0
<if test="venueType != null">
and venue_type = #{venueType},
and venue_type = #{venueType}
</if>
</select>
@@ -270,7 +273,7 @@
<include refid="Field"></include> FROM sv_device
WHERE 1=1 AND name = #{deviceName} and venue_id=#{venueId} and deleted = 0
<if test="venueType != null">
and venue_type = #{venueType},
and venue_type = #{venueType}
</if>
</select>