package com.cloudyoung.wx.comet.server; import java.io.IOException; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArrayList; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang.StringUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.web.socket.CloseStatus; import org.springframework.web.socket.TextMessage; import org.springframework.web.socket.WebSocketHandler; import org.springframework.web.socket.WebSocketMessage; import org.springframework.web.socket.WebSocketSession; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.cloudyoung.common.enums.PlatformNameEnum; import com.cloudyoung.common.utils.LogUtil; import com.cloudyoung.common.wx.constant.WebsocketConstants; import com.cloudyoung.common.wx.vo.message.WebsocketDialogueVo; import com.cloudyoung.wx.comet.jedis.JedisTemplate; import com.cloudyoung.wx.comet.service.WxWebsocketMessageService; /** * @Description websocket处理类 * @date 2018年3月7日上午9:05:44 * @version V1.0 * @author 邹立强 (zoulq@cloud-young.com) *

Copyright (c) Department of Research and Development/Beijing.

*/ @Component public class SystemWebSocketHandler implements WebSocketHandler { private static final Logger logger = LogManager.getLogger(SystemWebSocketHandler.class); private static final Map> wxUser = new ConcurrentHashMap>(); @Autowired private JedisTemplate jedisTemplate; @Autowired private WxWebsocketMessageService wxWebsocketMessageService; /** * Description websocket 客户端建立握手连接 * @param session * @throws Exception * @version V1.0 * @auth 邹立强 (zoulq@cloud-young.com) * 2018年3月8日 上午10:10:06 */ @Override public void afterConnectionEstablished(WebSocketSession session){ Map handshakeAttributes = session.getHandshakeAttributes(); String appId = handshakeAttributes.get(WebsocketConstants.WX_WEBSOCKET_APPID_KEY).toString(); String module = handshakeAttributes.get(WebsocketConstants.WX_WEBSOCKET_MODULE_KEY).toString(); String serverId = WebSocketInit.serverIdMap.get(WebsocketConstants.WX_WEBSOCKET_SERVER_ID); LogUtil.info(logger, PlatformNameEnum.WX, String.format("appId:%s, module:%s, module:%s", appId, module, serverId), "afterConnectionEstablished_invoke_method", null); if (StringUtils.isNotBlank(appId) && StringUtils.isNotBlank(module)) { CopyOnWriteArrayList wxUserList = wxUser.get(module + appId); if (CollectionUtils.isEmpty(wxUserList)) { wxUserList = new CopyOnWriteArrayList(); } jedisTemplate.addSetMember(module+appId, serverId); wxUserList.addIfAbsent(session); wxUser.put(module + appId, wxUserList); } } /** * @Description 消息处理 * @param session * @param message * @throws Exception * @version V1.0 * @auth 邹立强 (zoulq@cloud-young.com) * 2018年3月9日 上午10:48:13 */ @Override public void handleMessage(WebSocketSession session, WebSocketMessage message) { try { Map handshakeAttributes = session.getHandshakeAttributes(); LogUtil.info(logger, PlatformNameEnum.WX, String.format("attributes:%s, message:%s", JSONObject.toJSONString(handshakeAttributes), JSONObject.toJSONString(message)), "handleMessage_invoke_method", ""); String appId = String.valueOf(handshakeAttributes.get(WebsocketConstants.WX_WEBSOCKET_APPID_KEY)); if(StringUtils.isNotBlank(appId) && !"null".equals(appId)) { //String module = handshakeAttributes.get(WebsocketConstants.WX_WEBSOCKET_MODULE_KEY).toString(); //LogUtil.info(logger, PlatformNameEnum.WX, String.format("ip:%s, message:%s", session.getRemoteAddress(), JSONObject.toJSONString(message.getPayload())), "handleMessage_invoke_method", null); WebsocketDialogueVo websocketDialogueVo=new WebsocketDialogueVo(); websocketDialogueVo.setContent(message.getPayload().toString()); websocketDialogueVo.setAuthorizerAppid(appId); wxWebsocketMessageService.sendDialogueMessage(websocketDialogueVo); //session.sendMessage(new TextMessage(message.getPayload().toString())); } } catch (Exception e) { e.printStackTrace(); //LogUtil.error(logger, e, PlatformNameEnum.WX, String.format("message:%s",JSONObject.toJSONString(message)), "handleMessageError_invoke_fail"); } } /** * @Description websocket 客户端异常 * @param session * @param exception * @throws Exception * @version V1.0 * @auth 邹立强 (zoulq@cloud-young.com) * 2018年3月8日 上午10:09:47 */ @Override public void handleTransportError(WebSocketSession session, Throwable exception) { Map handshakeAttributes = session.getHandshakeAttributes(); if (null != handshakeAttributes) { Object appIdO = handshakeAttributes.get(WebsocketConstants.WX_WEBSOCKET_APPID_KEY); Object moduleO = handshakeAttributes.get(WebsocketConstants.WX_WEBSOCKET_MODULE_KEY); if(appIdO!=null&&moduleO!=null) { String appId = appIdO.toString(); String module = moduleO.toString(); String serverId = WebSocketInit.serverIdMap.get(WebsocketConstants.WX_WEBSOCKET_SERVER_ID); LogUtil.info(logger, PlatformNameEnum.WX, String.format("appId:%s, module:%s", appId, module), "handleTransportError_invoke_method", null); try { if (session.isOpen()) { session.close(); } if (StringUtils.isNotBlank(appId) && StringUtils.isNotBlank(module)) { CopyOnWriteArrayList wxUserList = wxUser.get(module + appId); if (wxUserList != null && wxUserList.size() > 0) { wxUserList.remove(session); } if (wxUserList != null && wxUserList.size() == 0) { wxUser.remove(module + appId); jedisTemplate.removeSetMember(module + appId, serverId); } if (wxUserList != null && wxUserList.size() > 0) { wxUser.put(module + appId, wxUserList); } handshakeAttributes.remove(WebsocketConstants.WX_WEBSOCKET_APPID_KEY); handshakeAttributes.remove(WebsocketConstants.WX_WEBSOCKET_MODULE_KEY); } } catch (Exception e) { LogUtil.error(logger, e, PlatformNameEnum.WX, String.format("appId:%s,module:%s", appId, module), "handleTransportError_invoke_fail"); } } } } /** * @Description websocket 客户端关闭连接 * @param session * @param closeStatus * @throws Exception * @version V1.0 * @auth 邹立强 (zoulq@cloud-young.com) * 2018年3月8日 上午10:09:21 */ @Override public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception { Map handshakeAttributes = session.getHandshakeAttributes(); if (null != handshakeAttributes) { Object appIdO = handshakeAttributes.get(WebsocketConstants.WX_WEBSOCKET_APPID_KEY); Object moduleO = handshakeAttributes.get(WebsocketConstants.WX_WEBSOCKET_MODULE_KEY); if(appIdO!=null&&moduleO!=null) { String appId = appIdO.toString(); String module = moduleO.toString(); String serverId = WebSocketInit.serverIdMap.get(WebsocketConstants.WX_WEBSOCKET_SERVER_ID); LogUtil.info(logger, PlatformNameEnum.WX, String.format("appId:%s, module:%s", appId, module), "handleTransportError_invoke_method", null); try { if (session.isOpen()) { session.close(); } if (StringUtils.isNotBlank(appId) && StringUtils.isNotBlank(module)) { CopyOnWriteArrayList wxUserList = wxUser.get(module + appId); if (wxUserList != null && wxUserList.size() > 0) { wxUserList.remove(session); } if (wxUserList != null && wxUserList.size() == 0) { wxUser.remove(module + appId); jedisTemplate.removeSetMember(module + appId, serverId); } if (wxUserList != null && wxUserList.size() > 0) { wxUser.put(module + appId, wxUserList); } handshakeAttributes.remove(WebsocketConstants.WX_WEBSOCKET_APPID_KEY); handshakeAttributes.remove(WebsocketConstants.WX_WEBSOCKET_MODULE_KEY); } } catch (Exception e) { LogUtil.error(logger, e, PlatformNameEnum.WX, String.format("appId:%s,module:%s", appId, module), "afterConnectionClosed_invoke_fail"); } } } } /** * @Description 是否支持部分消息 * @return * @version V1.0 * @auth 邹立强 (zoulq@cloud-young.com) * 2018年3月9日 上午10:46:57 */ @Override public boolean supportsPartialMessages() { return false; } /** * @Description 微信粉丝单发消息 * @param sign * @param module * @param websocketDialogueVo * @return * @return Boolean * @version V1.0 * @auth 邹立强 (zoulq@cloud-young.com) * 2018年3月6日 下午12:03:35 */ public Boolean sendMessageToUser(String sign, String module, WebsocketDialogueVo websocketDialogueVo) { CopyOnWriteArrayList wxUserList = wxUser.get(module + sign); Boolean isSuccess = false; if (wxUserList != null) { for (int i = 0; i < wxUserList.size(); i++) { WebSocketSession user = wxUserList.get(i); if (sign.equals((String) user.getHandshakeAttributes().get(WebsocketConstants.WX_WEBSOCKET_APPID_KEY))) { try { if (user.isOpen()) { String clientSign = (String) user.getHandshakeAttributes().get(WebsocketConstants.WX_WEBSOCKET_CLIENT_SIGN); websocketDialogueVo.setClientSign(clientSign); TextMessage message = new TextMessage(JSON.toJSONString(websocketDialogueVo)); isSuccess = true; synchronized (user) { user.sendMessage(message); } } } catch (IOException e) { e.printStackTrace(); } } } } LogUtil.info(logger, PlatformNameEnum.WX, String.format("appId:%s,module:%s,websocketDialogueVo:%s\n", sign, module, JSON.toJSONString(websocketDialogueVo)), "sendMessageToUserDefault_invoker", isSuccess.toString()); return isSuccess; } public static Map> getWxuser() { return wxUser; } }