package com.cnd3b.common.websocket; import com.alibaba.fastjson.JSONObject; import com.cnd3b.common.BaseClass; import com.cnd3b.common.D3BReturnObject_Err; import com.cnd3b.common.data.Row; import com.cnd3b.common.parameter.parameter; import javax.websocket.*; import javax.websocket.server.PathParam; import javax.websocket.server.ServerEndpoint; import java.io.IOException; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Calendar; import java.util.Date; import java.util.concurrent.ConcurrentHashMap; //ws://127.0.0.1:8080/samex/webSocket/829fef9884bbf7f9fb9c51499d7b332f @ServerEndpoint("/webSocket/{accesstoken}") public class WebClientSocket extends BaseClass { private Session session; //当前连接对象的账号ID private long userid; private Row userRow; private String accesstoken; private Date createdate; /** * 连接开启 * * @param accesstoken * @param session * @throws IOException */ @OnOpen private void onOpen(@PathParam("accesstoken") String accesstoken, Session session) throws IOException { this.session = session; this.accesstoken = accesstoken; createdate = getDateTime(); if (parameter.tokenlist.containsKey(accesstoken)) { userid = parameter.tokenlist.get(accesstoken); userRow = parameter.userIdList.get(userid); } else { JSONObject methodobject = new JSONObject(); methodobject.put("type", "err"); methodobject.put("msg", "请登陆"); sendSystemMessage(methodobject); return; } if (parameter.websocketClients.containsKey(userid)) { parameter.websocketClients.get(userid).put(accesstoken, this); } else { ConcurrentHashMap map = new ConcurrentHashMap<>(); map.put(accesstoken, this); parameter.websocketClients.put(userid, map); } parameter.loginDate.put(userid, createdate); } /** * 连接关闭 * * @throws IOException */ @OnClose private void onClose() throws IOException { if (parameter.websocketClients.containsKey(userid)) { parameter.websocketClients.get(userid).remove(accesstoken); if (parameter.websocketClients.get(userid).isEmpty()) { parameter.websocketClients.remove(userid); } } } /** * { * "dialogid":1,//对话框id * "messagetype":"text",//消息类型 * "description":"",//消息摘要 * "data":{ * "message":""//文字正文, * } * }, * { * "dialogid":1, * "messagetype":"file",//text,file,data,image, * "description":"", * "data":{ * "ownertable":"", * "ownerid":"", * "serialnumber":"", * "postfix":"", * "fobsurl":"", * "fobsurl_minimage":"", * "fobsurl_hls":"", * "fdocument":"" * } * }, * { * "dialogid":1, * "messagetype":"data",//text,file,data,image * "description":"", * "data":{ * "type":"", * "ownertable":"", * "ownerid":"" * } * } * * @param messageObject * @throws IOException */ /** * 消息接收 * * @param RequestContent * @throws IOException */ @OnMessage private void onMessage(String RequestContent) throws IOException { /** * 验证请求正文是否为规范的SONObject格式 */ JSONObject requestcontent = null; try { requestcontent = JSONObject.parseObject(RequestContent); } catch (Exception e) { return; } /** * 验证请求正文中是否包含必填的键值 */ String[] mustkeys = {"classname", "method", "content"}; for (String mustkey : mustkeys) { if (!requestcontent.containsKey(mustkey)) { return; } } /** * 验证请求正文中的content是否为规范的SONObject格式 */ JSONObject content = new JSONObject(); try { content = requestcontent.getJSONObject("content"); } catch (Exception e) { return; } /** * 验证正文中的token是否有效 */ String className = requestcontent.getString("classname"); parameter.requesttime.put(accesstoken, Calendar.getInstance().getTime()); String methodName = requestcontent.getString("method"); if (content.isEmpty()) { content = new JSONObject(); } content.put("$classname", className); content.put("$method", methodName); content.put("$accesstoken", accesstoken); String key = className + "." + methodName; String result; Object obj = null; try { long starttimes = Calendar.getInstance().getTimeInMillis(); /** * 执行请求方法 */ Class clz = Class.forName("com.cnd3b.websocketcontroller." + className); Constructor cla = clz.getDeclaredConstructor(JSONObject.class); obj = cla.newInstance(content); Method method = obj.getClass().getDeclaredMethod(methodName); result = (String) method.invoke(obj); long endtimes = Calendar.getInstance().getTimeInMillis(); saveCallMethodMsg(key, true, endtimes - starttimes); } catch (ClassNotFoundException e) { e.printStackTrace(); result = new D3BReturnObject_Err().setErrMsg("找不到指定的类" + className).toString(); } catch (InstantiationException e) { e.printStackTrace(); result = new D3BReturnObject_Err().setErrMsg("类" + className + "实例化异常").toString(); } catch (IllegalAccessException e) { e.printStackTrace(); result = new D3BReturnObject_Err().setErrMsg("类" + className + "安全权限异常,可能该类为非public类").toString(); } catch (NoSuchMethodException e) { e.printStackTrace(); result = new D3BReturnObject_Err().setErrMsg("找不到指定的类" + className + "的" + methodName + "方法").toString(); } catch (IllegalArgumentException e) { e.printStackTrace(); result = new D3BReturnObject_Err().setErrMsg("类" + className + "的" + methodName + "方法参数不合法").toString(); } catch (InvocationTargetException e) { Throwable targetException = e.getTargetException(); D3BReturnObject_Err d3BReturnObject_err = new D3BReturnObject_Err(); d3BReturnObject_err.setErrMsg(targetException.getMessage()); result = d3BReturnObject_err.toString(); } catch (Exception e) { e.printStackTrace(); result = new D3BReturnObject_Err().setErrMsg("发生未知异常" + e.getMessage()).toString(); } finally { if (obj != null) { try { obj.getClass().getMethod("p2ServerSystemPaoSetClose").invoke(obj); } catch (Exception e) { e.printStackTrace(); } } } return; } /** * 记录请求数 * * @param key * @param fromdb * @param time */ private void saveCallMethodMsg(String key, boolean fromdb, long time) { long callmethodTimes = parameter.callmethodTimes.containsKey(key) ? parameter.callmethodTimes.get(key) : 0L; //更新请求总数 parameter.callmethodTimes.put(key, callmethodTimes + 1L); //最新请求时间 parameter.lastcallmethodtime.put(key, Calendar.getInstance().getTime()); //从缓存获取的次数 long callmethod_fromcacheTimes = parameter.callmethod_fromcacheTimes.containsKey(key) ? parameter.callmethod_fromcacheTimes.get(key) : 0L; if (!fromdb) { /** * 方法请求从缓存获取次数 */ parameter.callmethod_fromcacheTimes.put(key, callmethod_fromcacheTimes + 1L); } else { /** * 方法请求查询最新耗时 */ parameter.callmethodLastTimeLong.put(key, time); long totaltimes = callmethodTimes - callmethod_fromcacheTimes; /** * 方法请求查询平均时间 */ long callmethodTimeLong = parameter.callmethodTimeLong.containsKey(key) ? parameter.callmethodTimeLong.get(key) : 0L; parameter.callmethodTimeLong.put(key, (callmethodTimeLong * totaltimes + time) / (totaltimes + 1)); } } @OnError private void onError(Session session, Throwable error) { error.printStackTrace(); } /** * 对当前连接发送对话框消息 * * @param message */ public void sendDialogMessage(JSONObject message) { JSONObject object = new JSONObject(); object.put("msgtype", "imdialog"); object.put("message", message); session.getAsyncRemote().sendText(object.toJSONString()); } /** * 对当前连接发送系统消息 * * @param message */ public void sendSystemMessage(JSONObject message) { JSONObject object = new JSONObject(); object.put("msgtype", "system"); object.put("message", message); session.getAsyncRemote().sendText(object.toJSONString()); } }