update websocket 链接限制变为同ip可以多个用户登录,单用户只能登录一个
This commit is contained in:
parent
c596d9ab30
commit
889189e726
|
@ -78,6 +78,7 @@ public class GlobalExceptionHandler {
|
|||
@ExceptionHandler(ServiceException.class)
|
||||
public AjaxResult handleServiceException(ServiceException e, HttpServletRequest request)
|
||||
{
|
||||
|
||||
log.error(e.getMessage(), e);
|
||||
Integer code = e.getCode();
|
||||
return StringUtils.isNotNull(code) ? AjaxResult.error(code, e.getMessage()) : AjaxResult.error(e.getMessage());
|
||||
|
@ -89,9 +90,10 @@ public class GlobalExceptionHandler {
|
|||
@ExceptionHandler(RuntimeException.class)
|
||||
public AjaxResult handleRuntimeException(RuntimeException e, HttpServletRequest request)
|
||||
{
|
||||
System.out.println("异常抛出时间"+System.currentTimeMillis());
|
||||
String requestURI = request.getRequestURI();
|
||||
log.error("请求地址'{}',发生未知异常.", requestURI, e);
|
||||
return AjaxResult.error(e.getMessage());
|
||||
return AjaxResult.error(HttpStatus.BAD_REQUEST,e.getMessage());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -54,8 +54,4 @@ public class ChatMessageController {
|
|||
public AjaxResult readMessage(@RequestBody MessagePageVo pageVo) {
|
||||
return chatMessageService.readMessage(pageVo.getRoomId());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -2,7 +2,7 @@ package com.m2pool.chat.controller;
|
|||
|
||||
import com.m2pool.chat.service.ChatRoomService;
|
||||
import com.m2pool.chat.vo.CharRoomVo;
|
||||
import com.m2pool.chat.vo.MessagePageVo;
|
||||
import com.m2pool.chat.vo.RoomPageVo;
|
||||
import com.m2pool.common.core.web.Result.AjaxResult;
|
||||
import com.m2pool.common.core.web.page.TableDataInfo;
|
||||
import com.m2pool.common.security.annotation.RequiresLogin;
|
||||
|
@ -11,6 +11,8 @@ import io.swagger.annotations.ApiOperation;
|
|||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Api(tags = "聊天室相关接口")
|
||||
@RestController
|
||||
@RequestMapping("/rooms")
|
||||
|
@ -23,8 +25,13 @@ public class ChatRoomController {
|
|||
@PostMapping("/find/room/list")
|
||||
@ApiOperation(value = "查询客服人员的聊天室列表")
|
||||
@RequiresLogin
|
||||
public TableDataInfo findRoomList(@RequestBody MessagePageVo messagePageVo) {
|
||||
return chatRoomService.findRoomList(messagePageVo.getSendDateTime());
|
||||
public TableDataInfo findRoomList(@RequestBody(required = false) RoomPageVo roomPageVo) {
|
||||
// 如果请求体为空,初始化一个默认的 RoomPageVo 对象
|
||||
if (roomPageVo == null) {
|
||||
roomPageVo = new RoomPageVo();
|
||||
roomPageVo.setSendDateTime(LocalDateTime.now());
|
||||
}
|
||||
return chatRoomService.findRoomList(roomPageVo);
|
||||
}
|
||||
|
||||
@GetMapping("/find/room/by/userid")
|
||||
|
|
|
@ -17,7 +17,7 @@ public class ChatMessage {
|
|||
@TableId(value = "id", type = IdType.AUTO)
|
||||
private Long id;
|
||||
private Integer type;
|
||||
private Integer read;
|
||||
private Integer isRead;
|
||||
private String sendEmail;
|
||||
private String content;
|
||||
private Long roomId;
|
||||
|
|
|
@ -15,6 +15,7 @@ public class ChatMessageHistory {
|
|||
@TableId(value = "id", type = IdType.AUTO)
|
||||
private Long id;
|
||||
private Integer type;
|
||||
private Integer isRead;
|
||||
private String sendEmail;
|
||||
private String content;
|
||||
private Long roomId;
|
||||
|
|
|
@ -23,7 +23,8 @@ import java.util.concurrent.ConcurrentHashMap;
|
|||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import static com.m2pool.chat.constant.CustomHeader.*;
|
||||
import static com.m2pool.chat.constant.UserType.CUSTOMER;
|
||||
import static com.m2pool.chat.constant.UserType.LOGIN_USER;
|
||||
import static com.m2pool.chat.constant.UserType.TOURIST;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -37,9 +38,9 @@ public class WebsocketChannelInterceptor implements ChannelInterceptor {
|
|||
private static final Logger LOGGER = LoggerFactory.getLogger(WebsocketChannelInterceptor.class);
|
||||
|
||||
/**
|
||||
* 当前加入链接的ip
|
||||
* 当前加入链接的ip ,key 为 ip ,VALUE 为用户邮箱
|
||||
*/
|
||||
private static final ConcurrentHashMap<String, Boolean> ipConnectionCountMap = new ConcurrentHashMap<>();
|
||||
private static final ConcurrentHashMap<String,String> ipConnectionCountMap = new ConcurrentHashMap<>();
|
||||
|
||||
|
||||
/**
|
||||
|
@ -78,7 +79,7 @@ public class WebsocketChannelInterceptor implements ChannelInterceptor {
|
|||
//最大链接数限制
|
||||
maxConnectionsLimit();
|
||||
//根据客服端ip + 用户类型限制连接数
|
||||
ipLimit(accessor,type);
|
||||
ipLimit(accessor,type,email);
|
||||
|
||||
|
||||
//链接请求头中用户信息存入stomp中
|
||||
|
@ -117,14 +118,23 @@ public class WebsocketChannelInterceptor implements ChannelInterceptor {
|
|||
* ip 链接个数限制
|
||||
* @param accessor
|
||||
*/
|
||||
private void ipLimit(StompHeaderAccessor accessor,int type){
|
||||
private void ipLimit(StompHeaderAccessor accessor,int type,String email){
|
||||
Map<String, Object> sessionAttributes = accessor.getSessionAttributes();
|
||||
if (sessionAttributes != null) {
|
||||
String ipAddr = (String) sessionAttributes.get(IPADDR);
|
||||
if(type != CUSTOMER && ipConnectionCountMap.get(ipAddr) != null){
|
||||
System.out.println(accessor.getSessionId());
|
||||
String hasConnectionEmail = ipConnectionCountMap.get(ipAddr);
|
||||
//两种ip限制情况
|
||||
//本次链接为游客 且ip上已经有人链接直接拒绝本次链接
|
||||
if(type == TOURIST && hasConnectionEmail != null){
|
||||
throw new MessageDeliveryException(ExceptionEnum.fromCode(ExceptionEnum.IP_LIMIT_CONNECT));
|
||||
}
|
||||
ipConnectionCountMap.put(ipAddr,true);
|
||||
//本次链接为登录用户,并且已经链接.直接拒绝本次链接(多用户登录)
|
||||
if ( type == LOGIN_USER && email.equals(hasConnectionEmail)) {
|
||||
throw new MessageDeliveryException(ExceptionEnum.fromCode(ExceptionEnum.IP_LIMIT_CONNECT));
|
||||
}
|
||||
ipConnectionCountMap.put(ipAddr,email);
|
||||
|
||||
}else{
|
||||
throw new MessageDeliveryException(ExceptionEnum.fromCode(ExceptionEnum.GET_PRINCIPAL_FAIL));
|
||||
}
|
||||
|
@ -157,15 +167,12 @@ public class WebsocketChannelInterceptor implements ChannelInterceptor {
|
|||
Map<String, Object> sessionAttributes = accessor.getSessionAttributes();
|
||||
if (sessionAttributes != null) {
|
||||
String ipAddr = (String) sessionAttributes.get(IPADDR);
|
||||
if(ipConnectionCountMap.get(ipAddr) != null){
|
||||
ipConnectionCountMap.remove(ipAddr);
|
||||
}
|
||||
}else{
|
||||
throw new MessageDeliveryException(ExceptionEnum.fromCode(ExceptionEnum.GET_PRINCIPAL_FAIL));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void postSend(Message<?> message, MessageChannel channel, boolean sent) {
|
||||
LOGGER.info("------------WebsocketChannelInterceptor-postSend");
|
||||
|
|
|
@ -29,6 +29,6 @@ public interface ChatMessageMapper extends BaseMapper<ChatMessage> {
|
|||
* @return Map<String, Integer>,键为用户邮箱,值为未读消息条数
|
||||
*/
|
||||
@MapKey("userEmail")
|
||||
Map<String, Integer> findUnReadNums(@Param("userEmails") List<String> userEmails);
|
||||
Map<String, Map<String,Integer>> findUnReadNums(@Param("userEmails") List<String> userEmails);
|
||||
|
||||
}
|
|
@ -3,19 +3,18 @@ package com.m2pool.chat.service;
|
|||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.m2pool.chat.entity.ChatRoom;
|
||||
import com.m2pool.chat.vo.CharRoomVo;
|
||||
import com.m2pool.chat.vo.RoomPageVo;
|
||||
import com.m2pool.common.core.web.Result.AjaxResult;
|
||||
import com.m2pool.common.core.web.page.TableDataInfo;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
public interface ChatRoomService extends IService<ChatRoom> {
|
||||
|
||||
/**
|
||||
* 查询客服的聊天室列表
|
||||
* @param sendDateTime 最后一个发送者发送时间
|
||||
* @param roomPageVo
|
||||
* @return
|
||||
*/
|
||||
TableDataInfo findRoomList(LocalDateTime sendDateTime);
|
||||
TableDataInfo findRoomList(RoomPageVo roomPageVo);
|
||||
|
||||
/**
|
||||
* 根据当前用户邮箱查询聊天室
|
||||
|
|
|
@ -62,9 +62,11 @@ public class ChatMessageServiceImpl implements ChatMessageService {
|
|||
}else if (username.equals(chatRoom.getUserTwoEmail())) {
|
||||
updateUserEmail = chatRoom.getUserOneEmail();
|
||||
}
|
||||
int update = chatMessageMapper.update(ChatMessage.builder().read(1).build(),
|
||||
new LambdaUpdateWrapper<ChatMessage>().eq(ChatMessage::getSendEmail, updateUserEmail).eq(ChatMessage::getRoomId, roomId));
|
||||
return update > 0 ? AjaxResult.success("已读") : AjaxResult.error("消息读取失败");
|
||||
int update = chatMessageMapper.update(ChatMessage.builder().isRead(1).build(),
|
||||
new LambdaUpdateWrapper<ChatMessage>()
|
||||
.eq(ChatMessage::getSendEmail, updateUserEmail)
|
||||
.eq(ChatMessage::getRoomId, roomId));
|
||||
return update >= 0 ? AjaxResult.success("已读") : AjaxResult.error("消息读取失败");
|
||||
}
|
||||
return AjaxResult.error("聊天室不存在");
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package com.m2pool.chat.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.github.pagehelper.PageHelper;
|
||||
import com.github.pagehelper.PageInfo;
|
||||
import com.m2pool.chat.dto.ChatRoomDto;
|
||||
import com.m2pool.chat.entity.ChatRoom;
|
||||
|
@ -8,6 +9,7 @@ import com.m2pool.chat.mapper.ChatMessageMapper;
|
|||
import com.m2pool.chat.mapper.ChatRoomMapper;
|
||||
import com.m2pool.chat.service.ChatRoomService;
|
||||
import com.m2pool.chat.vo.CharRoomVo;
|
||||
import com.m2pool.chat.vo.RoomPageVo;
|
||||
import com.m2pool.common.core.constant.HttpStatus;
|
||||
import com.m2pool.common.core.utils.PageUtils;
|
||||
import com.m2pool.common.core.web.Result.AjaxResult;
|
||||
|
@ -21,7 +23,6 @@ import org.springframework.stereotype.Service;
|
|||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
|
@ -40,18 +41,20 @@ public class ChatRoomServiceImpl extends ServiceImpl<ChatRoomMapper, ChatRoom> i
|
|||
private RemoteUserService remoteUserService;
|
||||
|
||||
@Override
|
||||
public TableDataInfo findRoomList(LocalDateTime sendDateTime) {
|
||||
public TableDataInfo findRoomList(RoomPageVo roomPageVo) {
|
||||
String userEmail = SecurityUtils.getUsername();
|
||||
PageUtils.startPage();
|
||||
PageHelper.startPage(1, 20);
|
||||
System.out.println("-----时间"+roomPageVo.getSendDateTime()+"-----------用户"+userEmail + "-----当前时间"+ System.currentTimeMillis());
|
||||
//1.查找当前客服对应的聊天室
|
||||
List<ChatRoomDto> roomList = chatRoomMapper.findRoomList(userEmail,sendDateTime);
|
||||
List<ChatRoomDto> roomList = chatRoomMapper.findRoomList(userEmail,roomPageVo.getSendDateTime());
|
||||
List<String> userEmails = roomList.stream().map(ChatRoomDto::getUserEmail).collect(Collectors.toList());
|
||||
//2.查询未读数量
|
||||
if (!userEmails.isEmpty()){
|
||||
Map<String, Integer> unReadNums = chatMessageMapper.findUnReadNums(userEmails);
|
||||
Map<String, Map<String,Integer>> unReadNums = chatMessageMapper.findUnReadNums(userEmails);
|
||||
for (ChatRoomDto room : roomList) {
|
||||
Integer i = unReadNums.get(room.getUserEmail());
|
||||
room.setUnReadNumber(i == null ? 0 : i);
|
||||
Map<String, Integer> stringIntegerMap = unReadNums.get(room.getUserEmail());
|
||||
Integer i = stringIntegerMap != null ? stringIntegerMap.get("unReadNumber") : 0;
|
||||
room.setUnReadNumber(i);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,10 +1,7 @@
|
|||
package com.m2pool.chat.vo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* @ClassName MessagePageVo
|
||||
* @Description TODO
|
||||
|
@ -17,10 +14,6 @@ public class MessagePageVo {
|
|||
private Long id;
|
||||
private Integer pageNum;
|
||||
private Long roomId;
|
||||
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private LocalDateTime sendDateTime;
|
||||
|
||||
public MessagePageVo() {
|
||||
this.id = 1L;
|
||||
this.pageNum = 20;
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
package com.m2pool.chat.vo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import lombok.Data;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* @ClassName MessagePageVo
|
||||
* @Description TODO
|
||||
* @Author yyb
|
||||
* @Date 2025/4/22 17:09
|
||||
*/
|
||||
@Data
|
||||
public class RoomPageVo {
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private LocalDateTime sendDateTime;
|
||||
}
|
|
@ -15,14 +15,13 @@
|
|||
LIMIT #{pageNum}
|
||||
</select>
|
||||
<select id="findUnReadNums" resultType="java.util.Map">
|
||||
SELECT send_email as userEmail,
|
||||
count(*) as unReadNums
|
||||
SELECT send_email as userEmail,count(*) as unReadNums
|
||||
FROM chat_message
|
||||
WHERE send_email IN
|
||||
<foreach collection="userEmails" item="userEmail" open="(" separator="," close=")">
|
||||
#{userEmail}
|
||||
</foreach>
|
||||
AND `read` = false
|
||||
AND is_read = false
|
||||
GROUP BY send_email
|
||||
</select>
|
||||
|
||||
|
|
|
@ -11,9 +11,17 @@
|
|||
last_customer_send_time as lastCustomerSendTime
|
||||
FROM
|
||||
chat_room
|
||||
WHERE
|
||||
user_two_email = #{userEmail} AND last_user_send_time <![CDATA[ <= ]]> #{sendDateTime}
|
||||
AND del = FALSE
|
||||
<where>
|
||||
user_two_email = #{userEmail} AND del = FALSE
|
||||
<choose>
|
||||
<when test="sendDateTime != null">
|
||||
AND last_user_send_time <![CDATA[ <= ]]> #{sendDateTime}
|
||||
</when>
|
||||
<otherwise>
|
||||
AND last_user_send_time <![CDATA[ <= ]]> NOW()
|
||||
</otherwise>
|
||||
</choose>
|
||||
</where>
|
||||
ORDER BY
|
||||
flag DESC,
|
||||
last_user_send_time DESC
|
||||
|
|
Loading…
Reference in New Issue