xinyb
2023-12-01 a7fe1dd769a13d4ac1fd8870100e6d56521b5e06
提交 | 用户 | age
9eb57f 1 package com.yc.phoneQRLogin.action;
X 2
3 import com.yc.action.grid.GridUtils;
4 import com.yc.factory.FactoryBean;
5 import com.yc.im.service.RedisDAO;
2c93fc 6 import com.yc.phoneQRLogin.entity.HttpSessionConfigurator;
X 7 import com.yc.phoneQRLogin.entity.WebSession;
9eb57f 8 import net.jodah.expiringmap.ExpirationPolicy;
X 9 import net.jodah.expiringmap.ExpiringMap;
2c93fc 10 import net.sf.json.JSONObject;
X 11 import org.apache.commons.lang3.StringUtils;
9eb57f 12 import org.springframework.web.bind.annotation.RestController;
X 13
2c93fc 14 import javax.servlet.http.HttpSession;
9eb57f 15 import javax.websocket.*;
X 16 import javax.websocket.server.PathParam;
17 import javax.websocket.server.ServerEndpoint;
2c93fc 18 import java.util.ArrayList;
9eb57f 19 import java.util.HashMap;
2c93fc 20 import java.util.List;
9eb57f 21 import java.util.Map;
2c93fc 22 import java.util.concurrent.ConcurrentHashMap;
9eb57f 23 import java.util.concurrent.TimeUnit;
X 24
25 /**
26  * @USER: xinyb_
27  * @DATE: 2022-01-15 11:03
28  */
29 @RestController
2c93fc 30 @ServerEndpoint(value = "/ws/qrLogin/{dbId}/{qrCode}/{state}", configurator = HttpSessionConfigurator.class)
9eb57f 31 public class LoginQRCodeWS {
X 32
2c93fc 33     private static ExpiringMap<String, String> exMap = null;
9eb57f 34     private static RedisDAO redisDao = null;
2c93fc 35     private static Map<String, List<WebSession>> clients = new ConcurrentHashMap<String, List<WebSession>>();
X 36
37     public static Map<String, List<WebSession>> getOnlineWebList() {
38         return clients;
39     }
40     public static void deleteWebSession(String qrcode) {
41         if (clients.get(qrcode) != null) {
42             clients.remove(qrcode);
43         }
44         if (exMap.get(qrcode) != null) {
45             exMap.remove(qrcode);
46         }
47     }
9eb57f 48
X 49     static {
50         redisDao = (RedisDAO) FactoryBean.getBean("redisDAO");
51         //创建ExpiringMap,最大容量:100,有效时间:60秒。
15fc6e 52         exMap = ExpiringMap.builder().maxSize(100).expiration(60, TimeUnit.SECONDS)
9eb57f 53                 .variableExpiration().expirationListener((key, value) -> {
X 54                     //监听过期处理
2c93fc 55                     subscribe(new WebSession(-1, (String) key, (String) value));
9eb57f 56                 }).expirationPolicy(ExpirationPolicy.CREATED).build();
X 57     }
58
59
60     /***
61      * 打开连接
62      */
63     @OnOpen
64     public void onOpen(@PathParam("dbId") String dbId, @PathParam("qrCode") String qrCode,
2c93fc 65                        @PathParam("state") int state, Session session, EndpointConfig config) {
X 66         List<WebSession> list = clients.get(qrCode);//获取关联二维码的对象集合
67         HttpSession httpSession = null;
68         if (list == null) {//第一次进来就创建(第一次基本为PC界面进入)
69             list = new ArrayList<WebSession>();
70             //获取PC页面的session(state等于0表示PC页面的)
71             if (state == 0) {
72                 httpSession = (HttpSession) config.getUserProperties().get(HttpSession.class.getName());
73             }
74         }
75         //进来一次添加一个对象
76         list.add(new WebSession(session, httpSession, dbId, qrCode,state));
77         clients.put(qrCode, list);
78         if (exMap.get(qrCode) == null && state == 0) {//第一次进来定时60秒删除的对象
79             exMap.put(qrCode, dbId);
80         }
81         if (state == 1) {//是app扫码过来就发布订阅
82             subscribe(new WebSession(state, qrCode, dbId));
83         }
84     }
85
86     /**
87      * 接收APP端信息
88      *
89      * @param message
90      * @param session
91      * @throws Exception
92      */
93     @SuppressWarnings("unchecked")
94     @OnMessage
95     public void onMessage(Session session, String message) {
9eb57f 96         Map<String, Object> map = new HashMap<>();
2c93fc 97         map.put("state", -1);
X 98         try {
99             JSONObject json = JSONObject.fromObject(message.replace(" ", ""));
100             Integer state = json.getInt("state");
101             String token = json.getString("token");
102             String qrCode = json.getString("qrCode");
103             if (StringUtils.isBlank(qrCode)) {
104                 map.put("msg", "qrCode唯一码不能为空");
105                 session.getAsyncRemote().sendText(GridUtils.toJson(map));
106                 return;
107             }
108             if (state == 1 && StringUtils.isNotBlank(token)) {
109                 //发布订阅(登录认证)
110                 redisDao.publishMessage("Onbus_Qrcode", GridUtils.toJson(json));
111             } else {
112                 map.put("msg", "检查参数是否正确或检查token是否为空");
113                 session.getAsyncRemote().sendText(GridUtils.toJson(map));
114             }
115         } catch (Exception e) {
116             map.put("msg", (e.getCause() != null ? e.getCause().getMessage() : e.getMessage()));
117             session.getAsyncRemote().sendText(GridUtils.toJson(map));
118         }
9eb57f 119     }
X 120
121     /**
122      * 断开连接
123      */
124     @OnClose
2c93fc 125     public void onClose(@PathParam("dbId") String dbId, @PathParam("qrCode") String qrCode, Session session) {
a7fe1d 126 //        subscribe(new WebSession(-1, qrCode, dbId));
9eb57f 127     }
X 128
129     /**
130      * 过期处理
2c93fc 131      *
9eb57f 132      * @param qrCode
X 133      */
2c93fc 134     private static void subscribe(WebSession webSession) {
X 135         //过期发布订阅
136         redisDao.publishMessage("Onbus_Qrcode", GridUtils.toJson(webSession));
9eb57f 137     }
X 138 }