Ver código fonte

Merge branch 'huangyuan-user' of lift-manager/lift-server into develop

huangyuan 5 anos atrás
pai
commit
1a2b563585

+ 5 - 0
lift-common/src/main/java/cn.com.ty.lift.common/constants/ApiConstants.java

@@ -35,6 +35,11 @@ public class ApiConstants {
      */
     public static final String CURRENT_USER = "currentUser";
 
+    /**
+     * 用户id字段
+     */
+    public static final String CURRENT_USER_ID = "userId";
+
     /**
      * 已删除
      */

+ 17 - 0
lift-push/pom.xml

@@ -11,5 +11,22 @@
 
     <artifactId>lift-push</artifactId>
 
+    <!--添加依赖 -->
+    <dependencies>
+        <!-- 添加websocket依赖 -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-websocket</artifactId>
+        </dependency>
+
+        <!-- 添加公共模块依赖 -->
+        <dependency>
+            <groupId>cn.com.ty</groupId>
+            <artifactId>lift-common</artifactId>
+            <version>1.0-SNAPSHOT</version>
+        </dependency>
+
+    </dependencies>
+
 
 </project>

+ 45 - 0
lift-push/src/main/java/cn/com/ty/lift/push/websocket/config/WebSocketConfig.java

@@ -0,0 +1,45 @@
+package cn.com.ty.lift.push.websocket.config;
+
+import cn.com.ty.lift.push.websocket.handler.TimeyMessageHandler;
+import cn.com.ty.lift.push.websocket.service.TimeyMessageService;
+import cn.com.ty.lift.push.websocket.service.UserService;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.scheduling.TaskScheduler;
+import org.springframework.scheduling.concurrent.ConcurrentTaskScheduler;
+import org.springframework.web.socket.config.annotation.EnableWebSocket;
+import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
+import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
+
+import javax.annotation.Resource;
+import java.util.concurrent.Executors;
+
+/**
+ * @ClassName WebSocketConfig
+ * @Description 消息推动配置
+ * @Author huangyuan
+ * @Date 2019-04-19 22:53
+ **/
+@Configuration
+@EnableWebSocket
+public class WebSocketConfig implements WebSocketConfigurer {
+
+    @Resource
+    private TimeyMessageService timeyMessageService;
+
+    @Resource
+    private UserService userService;
+
+
+    @Bean
+    public TaskScheduler taskScheduler() {
+        return new ConcurrentTaskScheduler(Executors.newSingleThreadScheduledExecutor());
+    }
+
+    @Override
+    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
+        registry.addHandler(new TimeyMessageHandler(timeyMessageService, userService), "/myHandler")
+                .setAllowedOrigins("*")
+                .addInterceptors(new WebSocketInterceptor());
+    }
+}

+ 47 - 0
lift-push/src/main/java/cn/com/ty/lift/push/websocket/config/WebSocketInterceptor.java

@@ -0,0 +1,47 @@
+package cn.com.ty.lift.push.websocket.config;
+
+import cn.com.ty.lift.common.constants.ApiConstants;
+import cn.com.ty.lift.push.websocket.dao.entity.User;
+import org.springframework.http.server.ServerHttpRequest;
+import org.springframework.http.server.ServerHttpResponse;
+import org.springframework.http.server.ServletServerHttpRequest;
+import org.springframework.web.socket.WebSocketHandler;
+import org.springframework.web.socket.server.HandshakeInterceptor;
+
+import javax.servlet.http.HttpSession;
+import java.util.Map;
+
+public class WebSocketInterceptor implements HandshakeInterceptor {
+	
+	/**
+	 * 进入handler之前的拦截
+	 */
+	@Override
+	public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response,
+                                   WebSocketHandler wsHandler, Map<String, Object> map) {
+
+	    if(request instanceof ServletServerHttpRequest) {
+            ServletServerHttpRequest serverHttpRequest = (ServletServerHttpRequest) request;
+	    	HttpSession session = serverHttpRequest.getServletRequest().getSession();
+            User user = (User) session.getAttribute(ApiConstants.CURRENT_USER);
+            if(user != null) {
+            	map.put(ApiConstants.CURRENT_USER_ID, user.getId());
+            }
+	    }
+	    return true;
+	}
+
+	@Override
+	public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,
+                               Exception exception) {
+        ServletServerHttpRequest serverHttpRequest = (ServletServerHttpRequest) request;
+    	HttpSession session = serverHttpRequest.getServletRequest().getSession();
+        User user = (User) session.getAttribute(ApiConstants.CURRENT_USER);
+        if(user != null) {
+        	System.out.println("用户"+ user.getName() +"连接进入系统");
+		} else {
+			System.out.println("当前连接为空");
+		}
+	}
+
+}

+ 27 - 0
lift-push/src/main/java/cn/com/ty/lift/push/websocket/dao/entity/TimeyMessage.java

@@ -0,0 +1,27 @@
+package cn.com.ty.lift.push.websocket.dao.entity;
+
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+/**
+ * @author huangyuan
+ * @date 2019-12-22
+ * @description
+ */
+@Data
+public class TimeyMessage {
+    private Long id;
+
+    private Long userId;//用户id
+
+    private String content;//内容
+
+    private String type;//类型
+
+    private String viewFlag;//查看标识:1:已经查看, 0:未查看
+
+    private Long createUserId;//创建者id
+
+    private LocalDateTime createTime;//创建时间
+}

+ 14 - 0
lift-push/src/main/java/cn/com/ty/lift/push/websocket/dao/entity/User.java

@@ -0,0 +1,14 @@
+package cn.com.ty.lift.push.websocket.dao.entity;
+
+import lombok.Data;
+
+/**
+ * @author huangyuan
+ * @date 2019-12-22
+ * @description
+ */
+@Data
+public class User {
+    private Long id;
+    private String name;//用户昵称
+}

+ 26 - 0
lift-push/src/main/java/cn/com/ty/lift/push/websocket/dao/entity/model/RealTimeMessage.java

@@ -0,0 +1,26 @@
+package cn.com.ty.lift.push.websocket.dao.entity.model;
+
+import lombok.Data;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 用于实时消息的推送
+ * @author huangy
+ * @date 2018年9月19日
+ */
+@Data
+public class RealTimeMessage {
+	
+	private Long size;//消息数量
+	private String msgType;//消息类型
+	private List<TimeyMessageVo> msgList = new ArrayList<>();//及时消息列表
+	
+	public RealTimeMessage() {}
+	
+	public RealTimeMessage(List<TimeyMessageVo> msgList) {
+		this.msgList = msgList;
+	}
+	
+}

+ 49 - 0
lift-push/src/main/java/cn/com/ty/lift/push/websocket/dao/entity/model/TimeyMessageVo.java

@@ -0,0 +1,49 @@
+package cn.com.ty.lift.push.websocket.dao.entity.model;
+
+import cn.com.ty.lift.push.websocket.dao.entity.TimeyMessage;
+import lombok.Data;
+import org.apache.commons.beanutils.BeanUtils;
+import org.apache.commons.beanutils.ConvertUtils;
+import org.apache.commons.beanutils.converters.DateConverter;
+
+import java.lang.reflect.InvocationTargetException;
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * @ClassName TimeyMessageVo
+ * @Description
+ * @Author huangyuan
+ * @Date 2019-04-19 14:39
+ **/
+@Data
+public class TimeyMessageVo {
+    private String id;
+
+    private String userId;//用户id
+
+    private String content;//内容
+
+    private String type;//类型
+
+    private String objectId;//主体id
+
+    private String viewFlag;//查看标识:1:已经查看, 0:未查看
+
+    private Date createTime;
+
+    public TimeyMessageVo(){}
+
+    public TimeyMessageVo(TimeyMessage timeyMessage) {
+        try {
+            //info:进行beans拷贝,解决时间出现了空值而无法进行复制
+            ConvertUtils.register(new DateConverter(null), Date.class);
+            ConvertUtils.register(new DateConverter(null), BigDecimal.class);
+            BeanUtils.copyProperties(this, timeyMessage);
+        } catch (IllegalAccessException e) {
+            e.printStackTrace();
+        } catch (InvocationTargetException e) {
+            e.printStackTrace();
+        }
+    }
+}

+ 12 - 0
lift-push/src/main/java/cn/com/ty/lift/push/websocket/dao/mapper/TimeyMessageMapper.java

@@ -0,0 +1,12 @@
+package cn.com.ty.lift.push.websocket.dao.mapper;
+
+import cn.com.ty.lift.push.websocket.dao.entity.TimeyMessage;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * @author huangyuan
+ * @date 2019-12-22
+ * @description
+ */
+public interface TimeyMessageMapper extends BaseMapper<TimeyMessage> {
+}

+ 160 - 0
lift-push/src/main/java/cn/com/ty/lift/push/websocket/handler/TimeyMessageHandler.java

@@ -0,0 +1,160 @@
+package cn.com.ty.lift.push.websocket.handler;
+
+import cn.com.ty.lift.common.constants.ApiConstants;
+import cn.com.ty.lift.push.websocket.dao.entity.TimeyMessage;
+import cn.com.ty.lift.push.websocket.dao.entity.model.RealTimeMessage;
+import cn.com.ty.lift.push.websocket.dao.entity.model.TimeyMessageVo;
+import cn.com.ty.lift.push.websocket.service.TimeyMessageService;
+import cn.com.ty.lift.push.websocket.service.UserService;
+import cn.hutool.json.JSONUtil;
+import org.springframework.web.socket.*;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class TimeyMessageHandler implements WebSocketHandler {
+	
+	private TimeyMessageService timeyMessageService;
+
+	private UserService userService;
+	
+	public TimeyMessageHandler(){}
+	
+	public TimeyMessageHandler(TimeyMessageService timeyMessageService, UserService userService) {
+		this.timeyMessageService = timeyMessageService;
+		this.userService = userService;
+	}
+	
+	//在线用户列表
+    private static final Map<Long, WebSocketSession> users;
+   
+    static {
+        users = new HashMap<>();
+    }
+    
+    //新增socket
+    @Override
+    public void afterConnectionEstablished(WebSocketSession session){
+    	 Long userId = getCurrentUser(session);
+    	 users.put(userId, session);
+         if (userId != null) ;
+    }
+ 
+    //接收socket信息
+    @Override
+	public void handleMessage(WebSocketSession webSocketSession, WebSocketMessage<?> webSocketMessage) throws Exception {
+    	try{
+    		Long userId = getCurrentUser(webSocketSession);
+    		TimeyMessage timeyMessage = new TimeyMessage();
+    		timeyMessage.setUserId(userId);
+    		List<TimeyMessageVo> voList = new ArrayList<>();
+    		pushMessageToUser(userId, voList);
+    	 }catch(Exception e){
+      	   e.printStackTrace();
+         }		
+	}
+    /**
+     *@Author huangyuan
+     *@Description 给多个用户推送消息
+     *@Date 21:36 2019-04-19
+     *@Param [userIds, timeyMessages, count]
+     *@return boolean
+     **/
+	public static boolean pushMessageToUsers(List<Long> userIds, List<TimeyMessageVo> timeyMessages){
+        try{
+            if(userIds != null && userIds.size() > 0) {
+                for(Long userId : userIds) {
+                    WebSocketSession session = users.get(userId);
+                    if(session != null) {
+                        //新建消息体
+                        RealTimeMessage realTimeMessage;
+                        if(timeyMessages == null || timeyMessages.size() > 0){
+                            TimeyMessageVo vo = timeyMessages.get(0);
+                            realTimeMessage = new RealTimeMessage(timeyMessages);
+                            realTimeMessage.setSize((long) timeyMessages.size());
+                            realTimeMessage.setMsgType(vo.getType());
+                        } else {
+                            realTimeMessage = new RealTimeMessage();
+                            realTimeMessage.setSize(0L);
+                        }
+                        session.sendMessage(new TextMessage(JSONUtil.parseObj(realTimeMessage).toString()));
+                    }
+                }
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            return false;
+        }
+        return true;
+    }
+
+
+    /**
+     *@Author huangyuan
+     *@Description 把消息推给单个用户
+     *@Date 21:35 2019-04-19
+     *@Param [userId, timeyMessages]
+     *@return boolean
+     **/
+    public static boolean pushMessageToUser(Long userId, List<TimeyMessageVo> timeyMessages){
+        List<Long> userIds = new ArrayList<>();
+        userIds.add(userId);
+        return pushMessageToUsers(userIds, timeyMessages);
+    }
+
+    /**
+     *@Author huangyuan
+     *@Description 给单独用户推送信息
+     *@Date 00:35 2019-04-20
+     *@Param [userId, timeyMessage]
+     *@return boolean
+     **/
+    public static boolean pushMessageToUser(Long userId, TimeyMessage timeyMessage){
+        TimeyMessageVo vo = new TimeyMessageVo(timeyMessage);
+        List<TimeyMessageVo> voList = new ArrayList<>();
+        voList.add(vo);
+        return pushMessageToUser(userId, voList);
+    }
+ 
+    @Override
+    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
+        if (session.isOpen()) {
+            session.close();
+        }
+        System.out.println("连接出错");
+        users.remove(getCurrentUser(session));
+    }
+ 
+    @Override
+    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
+        System.out.println("连接已关闭:" + status);
+        users.remove(getCurrentUser(session));
+    }
+ 
+    @Override
+    public boolean supportsPartialMessages() {
+        return false;
+    }
+    
+    /**
+     * 获取用户id,作为标识
+     *@author huangy
+     *@date 2018年9月18日
+     *@param session
+     *@return Long
+     *@throws
+     */
+    private Long getCurrentUser(WebSocketSession session) {
+    	Long userId;
+    	try {
+    		userId  = (Long) session.getAttributes().get(ApiConstants.CURRENT_USER_ID);
+    	} catch (Exception e) {
+    		e.printStackTrace();
+    		return null;
+    	}
+    	return userId;
+    }
+
+}

+ 12 - 0
lift-push/src/main/java/cn/com/ty/lift/push/websocket/service/TimeyMessageService.java

@@ -0,0 +1,12 @@
+package cn.com.ty.lift.push.websocket.service;
+
+import cn.com.ty.lift.push.websocket.dao.entity.TimeyMessage;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ * @author huangyuan
+ * @date 2019-12-22
+ * @description
+ */
+public interface TimeyMessageService extends IService<TimeyMessage> {
+}

+ 12 - 0
lift-push/src/main/java/cn/com/ty/lift/push/websocket/service/UserService.java

@@ -0,0 +1,12 @@
+package cn.com.ty.lift.push.websocket.service;
+
+import org.springframework.stereotype.Service;
+
+/**
+ * @author huangyuan
+ * @date 2019-12-22
+ * @description 用户
+ */
+@Service
+public class UserService {
+}

+ 16 - 0
lift-push/src/main/java/cn/com/ty/lift/push/websocket/service/impl/TimeyMessageServiceImpl.java

@@ -0,0 +1,16 @@
+package cn.com.ty.lift.push.websocket.service.impl;
+
+import cn.com.ty.lift.push.websocket.dao.entity.TimeyMessage;
+import cn.com.ty.lift.push.websocket.dao.mapper.TimeyMessageMapper;
+import cn.com.ty.lift.push.websocket.service.TimeyMessageService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+/**
+ * @author huangyuan
+ * @date 2019-12-22
+ * @description
+ */
+@Service
+public class TimeyMessageServiceImpl extends ServiceImpl<TimeyMessageMapper, TimeyMessage> implements TimeyMessageService {
+}