api-新增通知客户端的逻辑【扫码之后先进行加载】

This commit is contained in:
limqhz
2020-07-20 14:37:19 +08:00
parent 759a0764be
commit 7d61e74b02
16 changed files with 282 additions and 43 deletions

View File

@@ -1,6 +1,7 @@
package com.sv.api.interceptor;
import com.sv.api.context.PlatformContext;
import com.sv.netty.config.Constant;
import com.ydd.framework.core.common.utils.ReflectUtil;
import com.ydd.framework.core.common.utils.RequestUtils;
import org.apache.commons.lang.StringUtils;
@@ -29,7 +30,6 @@ public class PlatformIdInterceptor implements Interceptor {
private static final Logger logger = LoggerFactory.getLogger(PlatformIdInterceptor.class);
private static final List<String> executeControllerList = Arrays.asList(new String [] {"/qrCode/init"});
/**
* 搜索前缀
*/
@@ -93,9 +93,7 @@ public class PlatformIdInterceptor implements Interceptor {
}
private boolean checkUrl(HttpServletRequest request) {
logger.error("request.getRequestURI()===========" + request.getRequestURI());
System.err.println(executeControllerList.toString());
return executeControllerList.contains(request.getRequestURI());
return Constant.executeControllerList.contains(request.getRequestURI());
}

View File

@@ -1,5 +1,6 @@
package com.sv.netty.config;
import com.enums.DeviceType;
import io.netty.channel.Channel;
import io.netty.util.internal.PlatformDependent;
@@ -11,33 +12,41 @@ public class ClientChannelCache {
* 此处存储客户端的channel 信息key 为 【deviceId + venueId】
* value: 1Tcp 2WebSocket
*/
public static final ConcurrentMap<String, Channel> channelTypes = PlatformDependent.newConcurrentHashMap();
public static final ConcurrentMap<String, Channel> channel = PlatformDependent.newConcurrentHashMap();
/**
* 缓存通道
*/
public static void putChannelType(String clientId, Channel channel) {
channelTypes.put(clientId, channel);
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.getCode();
return getCurrentChannel(clientId);
}
/**
* 获取通道
*/
public static Channel getChannelType(String clientId) {
return channelTypes.get(clientId);
public static Channel getCurrentChannel(String clientId) {
return channel.get(clientId);
}
/**
* 判断通道是否存在
*/
public static boolean contains(String clientId) {
return channelTypes.containsKey(clientId);
return channel.containsKey(clientId);
}
/**
* 移除通道
*/
public static void removeChannelType(String clientId) {
channelTypes.remove(clientId);
channel.remove(clientId);
}
}

View File

@@ -3,6 +3,9 @@ package com.sv.netty.config;
import com.sv.netty.netty.message.ChannelParam;
import io.netty.util.AttributeKey;
import java.util.Arrays;
import java.util.List;
/**
* Created by ranfi on 2/22/16.
*/
@@ -28,4 +31,10 @@ public class Constant {
public final static String SPIT_WORD = "#";
/**
* 哪些接口不需要增加 platform 平台限制
*/
public static final List<String> executeControllerList = Arrays.asList(new String [] {"/qrCode/init"});
}

View File

@@ -2,6 +2,8 @@ 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;
@@ -12,7 +14,7 @@ import org.springframework.web.bind.annotation.RestController;
public class QRCodeControler {
/**
* 微信小程序扫码之后,通知对应的线程进入加载界面,然后随即开始判断逻辑
* 废弃
* @return
*/
@RequestMapping("/scanQRCode")
@@ -38,9 +40,14 @@ public class QRCodeControler {
*/
@RequestMapping("/checkAlive")
public ResponseDTO checkAlive(@RequestParam String id) {
System.out.println(ClientChannelCache.channelTypes.size());
Channel channel = ClientChannelCache.getChannelType(id);
channel.writeAndFlush("check client alive ! ");
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

@@ -1,9 +1,14 @@
package com.sv.netty.controller;
import com.enums.DeviceType;
import com.sv.entity.Venue;
import com.sv.netty.config.ClientChannelCache;
import com.sv.netty.config.Constant;
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 io.netty.channel.Channel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.*;
@@ -19,14 +24,18 @@ public class QREnterController extends BaseApiController {
private final Logger logger = LoggerFactory.getLogger(QREnterController.class);
@Resource
private QRCodeService qrCodeService;
@Resource
private MessageService messageService;
/**
* 进场指令发布
*/
@RequestMapping(value = "/qrCode/enter", method = RequestMethod.GET)
public ResponseDTO enter(@RequestParam("deviceId") String deviceId,@RequestParam("memberId") String memberId) {
public ResponseDTO enter(@RequestParam("deviceId") String deviceId) {
Integer memberId = getMemberIdByAccessToken();
Integer venueId = getVenueId(deviceId);
String deviceName = getDeviceName(deviceId);
qrCodeService.enter(venueId,deviceName);
DeviceType enterOrOut = getEnterOrOut(deviceId);
qrCodeService.enter(venueId,deviceName,enterOrOut,memberId);
return ResponseDTO.ok();
}
@@ -36,9 +45,16 @@ public class QREnterController extends BaseApiController {
*/
@RequestMapping(value = "/qrCode/init", method = RequestMethod.GET)
public ResponseDTO initEnter(@RequestParam("deviceId")String deviceId) {
Integer memberId = getMemberIdByAccessToken();
Integer venueId = getVenueId(deviceId);
String deviceName = getDeviceName(deviceId);
return ResponseDTO.ok().addAttribute("init",qrCodeService.initEnter(venueId,deviceName));
DeviceType enterOrOut = getEnterOrOut(deviceId);
Venue venue = qrCodeService.initEnter(venueId, deviceName);
if (venue!=null){
Channel channel = ClientChannelCache.getCurrentChannel(deviceName,venueId ,enterOrOut);
messageService.sendLoading(channel,memberId);
}
return ResponseDTO.ok().addAttribute("venueInit", venue);
}
@@ -61,4 +77,15 @@ public class QREnterController extends BaseApiController {
return null;
}
private DeviceType getEnterOrOut(String deviceId){
DeviceType returnType = DeviceType.ENTER;
if (deviceId!=null && deviceId.contains(Constant.SPIT_WORD)){
String temp = deviceId.split(Constant.SPIT_WORD)[1];
if (temp!=null && temp.contains(Constant.SPIT_WORD)){
returnType = DeviceType.valueOf(temp.split(Constant.SPIT_WORD)[1]);
}
}
return returnType;
}
}

View File

@@ -17,6 +17,10 @@ public class HeartBeat implements Serializable {
private Integer venueId; //场馆号
private String deviceName; //设备号
/**
* 进场 ENTER ; 出厂 OUT
*/
private String EnterOrOut; //出入标志
public Integer getVenueId() {
return venueId;
@@ -33,4 +37,12 @@ public class HeartBeat implements Serializable {
public void setDeviceName(String deviceName) {
this.deviceName = deviceName;
}
public String getEnterOrOut() {
return EnterOrOut;
}
public void setEnterOrOut(String enterOrOut) {
EnterOrOut = enterOrOut;
}
}

View File

@@ -0,0 +1,25 @@
package com.sv.netty.netty.message;
import java.io.Serializable;
public class MessageDTO implements Serializable {
private MessageType messageType;
private String message;
public MessageType getMessageType() {
return messageType;
}
public void setMessageType(MessageType messageType) {
this.messageType = messageType;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}

View File

@@ -0,0 +1,19 @@
package com.sv.netty.netty.message;
public enum MessageType {
LOAD("加载"),
OPENDOOR("开门");
private String message;
MessageType(String message) {
this.message = message;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}

View File

@@ -1,5 +1,6 @@
package com.sv.netty.netty.service;
import com.enums.DeviceType;
import com.sv.netty.netty.message.HeartBeat;
import io.netty.channel.Channel;
@@ -34,4 +35,6 @@ public interface MessageService {
* @return
*/
Set<String> countConnection();
boolean sendLoading(Channel channel, Integer memberId);
}

View File

@@ -8,9 +8,9 @@ import com.sv.entity.Venue;
import com.sv.entity.face.FaceRecognizeResponse;
import com.sv.netty.config.ClientChannelCache;
import com.sv.netty.netty.message.HeartBeat;
import com.sv.netty.netty.message.Result;
import com.sv.netty.netty.message.MessageDTO;
import com.sv.netty.netty.message.MessageType;
import com.sv.netty.netty.service.MessageService;
import com.sv.netty.utils.JsonMapper;
import com.sv.service.api.MemberEnterVenueLogService;
import com.sv.service.api.MemberService;
import com.sv.service.api.VenueService;
@@ -20,10 +20,7 @@ import com.ydd.oms.entity.sys.Config;
import io.netty.channel.Channel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import javax.annotation.Resource;
@@ -117,7 +114,30 @@ public class TcpMessageHandlerAdapter implements MessageService {
*/
@Override
public Set<String> countConnection() {
return ClientChannelCache.channelTypes.keySet();
return ClientChannelCache.channel.keySet();
}
/**
* 通知客户端进入加载页面
* @param memberId
* @return
*/
@Override
public boolean sendLoading(Channel channel, Integer memberId) {
Member thisMember = memberService.findByMember(memberId);
if (thisMember!=null){
String nickname = thisMember.getNickname();
MessageDTO messageDTO = new MessageDTO();
messageDTO.setMessageType(MessageType.LOAD);
messageDTO.setMessage("欢迎光临" + nickname);
sendMessage(channel,messageDTO);
return true;
}
return false;
}
private void sendMessage(Channel channel, MessageDTO messageDTO) {
channel.writeAndFlush(messageDTO);
}
public void enter(Device device, FaceRecognizeResponse response, Venue venue) {
@@ -201,8 +221,8 @@ public class TcpMessageHandlerAdapter implements MessageService {
}
// memberMessageDto.setMessage("门禁已开,请入门");
venueService.addNumber(venue.getId(), 1, member.getId());
venue = venueService.findById(venue.getId());
sendNumberChange(venue.getNumber());
// venue = venueService.findById(venue.getId());
// sendNumberChange(venue.getNumber());
} else {
logger.info(member.getId() + "入场失败:" + member.getMoney().toString());
// memberMessageDto.setCode(-1);
@@ -251,24 +271,24 @@ public class TcpMessageHandlerAdapter implements MessageService {
// 校验玩就可以出场了
// sendMessage(memberMessageDto, device.getId());
venueService.addNumber(venue.getId(), -1, member.getId());
venue = venueService.findById(venue.getId());
sendNumberChange(venue.getNumber());
// venue = venueService.findById(venue.getId());
// sendNumberChange(venue.getNumber());
}
}
/**
* 控制硬件,门禁灯光控制
* @param number
*/
public void sendNumberChange(Integer number) {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
MultiValueMap<String, Object> param = new LinkedMultiValueMap<>();
param.add("LingtekID", "5d14229fcb1f5c1a9046f429");
param.add("Number", number.toString());
HttpEntity<MultiValueMap<String, Object>> request = new HttpEntity<>(param, headers);
ResponseEntity<Result> result = restTemplate.exchange("http://lingtek.jalasmart.com/api/v1/lingtek/number", HttpMethod.PUT, request, Result.class);
logger.info("灯光结果" + JsonMapper.nonDefaultMapper().toJson(result));
}
// /**
// * 控制硬件,门禁灯光控制
// * @param number
// */
// public void sendNumberChange(Integer number) {
// HttpHeaders headers = new HttpHeaders();
// headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
// MultiValueMap<String, Object> param = new LinkedMultiValueMap<>();
// param.add("LingtekID", "5d14229fcb1f5c1a9046f429");
// param.add("Number", number.toString());
// HttpEntity<MultiValueMap<String, Object>> request = new HttpEntity<>(param, headers);
// ResponseEntity<Result> result = restTemplate.exchange("http://lingtek.jalasmart.com/api/v1/lingtek/number", HttpMethod.PUT, request, Result.class);
// logger.info("灯光结果" + JsonMapper.nonDefaultMapper().toJson(result));
// }
}

View File

@@ -1,6 +1,8 @@
package com.test.netty.client;
import com.sv.netty.utils.JsonUtils;
import com.test.netty.client.message.HeartBeat;
import com.test.netty.client.message.MessageDTO;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
@@ -54,7 +56,14 @@ public class ClientHandler extends SimpleChannelInboundHandler<String> {
// TODO 安卓获取通知加载页面
// TODO 安卓获取通知开门失败消息 (进入一个页面,然后显示倒计时,回到主页(二维码页面))
// TODO 安卓获取通知开门的消息 (无需校验,直接操作开门)
// Message message = JsonMapper.fromJson(msg, Message.class);
MessageDTO message = JsonUtils.decode(msg, MessageDTO.class);
switch (message.getMessageType()){
case LOAD:
System.out.println("LOADING" + message.getMessage());
break;
default:
System.out.println("default");
}
// MessageService.getInstance().execute(message);
}

View File

@@ -20,6 +20,12 @@ public class HeartBeat implements Serializable {
@Expose
private String deviceName; //设备号
@Expose
/**
* 进场 ENTER ; 出厂 OUT
*/
private String EnterOrOut; //出入标志
public Integer getVenueId() {
return venueId;
}
@@ -35,4 +41,12 @@ public class HeartBeat implements Serializable {
public void setDeviceName(String deviceName) {
this.deviceName = deviceName;
}
public String getEnterOrOut() {
return EnterOrOut;
}
public void setEnterOrOut(String enterOrOut) {
EnterOrOut = enterOrOut;
}
}

View File

@@ -0,0 +1,34 @@
package com.test.netty.client.message;
import java.io.Serializable;
public class MessageDTO implements Serializable {
private MessageType messageType;
private String message;
private String clientId;
public MessageType getMessageType() {
return messageType;
}
public void setMessageType(MessageType messageType) {
this.messageType = messageType;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public String getClientId() {
return clientId;
}
public void setClientId(String clientId) {
this.clientId = clientId;
}
}

View File

@@ -0,0 +1,19 @@
package com.test.netty.client.message;
public enum MessageType {
LOAD("加载"),
OPENDOOR("开门");
private String message;
MessageType(String message) {
this.message = message;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}

View File

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

View File

@@ -1,5 +1,6 @@
package com.sv.service.api;
import com.enums.DeviceType;
import com.sv.entity.Venue;
import com.sv.mapper.DeviceMapper;
import com.sv.mapper.VenueMapper;
@@ -24,7 +25,8 @@ public class QRCodeService {
@Resource
private DeviceMapper deviceMapper;
public void enter(Integer venueId,String deviceName) {
public void enter(Integer venueId, String deviceName, DeviceType enterOrOut, Integer memberId) throws ServiceException{
return;
}
public Venue initEnter(Integer venueId,String deviceName) {