|
|
@@ -0,0 +1,230 @@
|
|
|
+package com.cnd3b.common.websocket;
|
|
|
+
|
|
|
+import com.alibaba.fastjson.JSONObject;
|
|
|
+import com.cnd3b.common.BaseClass;
|
|
|
+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.util.Arrays;
|
|
|
+import java.util.Calendar;
|
|
|
+import java.util.Map;
|
|
|
+import java.util.concurrent.ConcurrentHashMap;
|
|
|
+
|
|
|
+//ws://127.0.0.1:8080/samex/webSocket/829fef9884bbf7f9fb9c51499d7b332f
|
|
|
+@ServerEndpoint("/webSocket/{accesstoken}")
|
|
|
+public class WebClientSocket extends BaseClass {
|
|
|
+
|
|
|
+ //websocket连接池
|
|
|
+ public static Map<Long, WebClientSocket> websocketClients = new ConcurrentHashMap<Long, WebClientSocket>();
|
|
|
+ private Session session;
|
|
|
+ //当前连接对象的账号ID
|
|
|
+ private long userid;
|
|
|
+ private Row userRow;
|
|
|
+
|
|
|
+ @OnOpen
|
|
|
+ private void onOpen(@PathParam("accesstoken") String accesstoken, Session session) throws IOException {
|
|
|
+ this.session = session;
|
|
|
+ if (parameter.tokenlist.containsKey(accesstoken)) {
|
|
|
+ userid = parameter.tokenlist.get(accesstoken);
|
|
|
+ userRow = parameter.userIdList.get(userid);
|
|
|
+ } else {
|
|
|
+ sendMessage("请登陆!");
|
|
|
+ }
|
|
|
+ websocketClients.put(userid, this);
|
|
|
+ }
|
|
|
+
|
|
|
+ @OnClose
|
|
|
+ private void onClose() throws IOException {
|
|
|
+ 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
|
|
|
+ */
|
|
|
+ @OnMessage
|
|
|
+ private void onMessage(String messageObject) throws IOException {
|
|
|
+ JSONObject mesageObj = messageCheck(messageObject);
|
|
|
+ if (mesageObj == null) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ long dialogid = mesageObj.getLong("dialogid");//对话框ID
|
|
|
+ /**
|
|
|
+ * 消息处理
|
|
|
+ */
|
|
|
+ mesageObj = messageProcessing(mesageObj);
|
|
|
+ /**
|
|
|
+ * 消息发送
|
|
|
+ */
|
|
|
+ sendMessageToDialog(mesageObj.toJSONString(), dialogid);
|
|
|
+ }
|
|
|
+
|
|
|
+ public JSONObject messageProcessing(JSONObject mesageObj) {
|
|
|
+ mesageObj.put("datetime", getDateTime_Str());
|
|
|
+ mesageObj.put("messageid", String.valueOf(userid) + Calendar.getInstance().getTimeInMillis());
|
|
|
+ /**
|
|
|
+ * 创建发送方信息
|
|
|
+ */
|
|
|
+ JSONObject sendfromObject = new JSONObject();
|
|
|
+ sendfromObject.put("userid", userid);
|
|
|
+ sendfromObject.put("siteid", userRow.getString("siteid"));
|
|
|
+ sendfromObject.put("username", userRow.getString("fname"));
|
|
|
+ mesageObj.put("sendfrom", sendfromObject);
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 消息持久化,保存消息体mesageObj,字段:siteid,dialogid,userid,messageid,datetime,description,messagetype,mesageObj
|
|
|
+ */
|
|
|
+
|
|
|
+ return mesageObj;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 消息格式检查
|
|
|
+ *
|
|
|
+ * @param messageObject
|
|
|
+ * @throws Exception
|
|
|
+ */
|
|
|
+ public JSONObject messageCheck(String messageObject) {
|
|
|
+ JSONObject mesageObj = null;
|
|
|
+ String errmsg = "";
|
|
|
+ try {
|
|
|
+ mesageObj = JSONObject.parseObject(messageObject);
|
|
|
+ } catch (Exception e) {
|
|
|
+ errmsg = "不是有效的JSONObject消息格式";
|
|
|
+ }
|
|
|
+ if (!mesageObj.containsKey("dialogid") || mesageObj.getLongValue("dialogid") <= 0) {
|
|
|
+ errmsg = "dialogid缺失";
|
|
|
+ }
|
|
|
+ if (!mesageObj.containsKey("messagetype")) {
|
|
|
+ errmsg = "messagetype缺失";
|
|
|
+ }
|
|
|
+ String messagetype = mesageObj.getString("messagetype");
|
|
|
+ if (!Arrays.asList(new String[]{"text", "file", "data"}).contains(messagetype)) {
|
|
|
+ errmsg = "无效的messagetype";
|
|
|
+ }
|
|
|
+ if (!mesageObj.containsKey("description") || "".equals(mesageObj.getString("description"))) {
|
|
|
+ errmsg = "description缺失";
|
|
|
+ }
|
|
|
+ if (!mesageObj.containsKey("data")) {
|
|
|
+ errmsg = "data缺失";
|
|
|
+ }
|
|
|
+ JSONObject data = mesageObj.getJSONObject("data");
|
|
|
+ if ("text".equals(messagetype)) {
|
|
|
+ if (!data.containsKey("message") || "".equals(mesageObj.getString("message"))) {
|
|
|
+ errmsg = "text消息必须包含message";
|
|
|
+ }
|
|
|
+ } else if ("file".equals(messagetype)) {
|
|
|
+ if (!data.containsKey("ownertable") || "".equals(mesageObj.getString("ownertable"))) {
|
|
|
+ errmsg = "file消息必须包含ownertable";
|
|
|
+ }
|
|
|
+ if (!data.containsKey("ownerid") || "".equals(mesageObj.getString("ownerid"))) {
|
|
|
+ errmsg = "file消息必须包含ownerid";
|
|
|
+ }
|
|
|
+ if (!data.containsKey("serialnumber") || "".equals(mesageObj.getString("serialnumber"))) {
|
|
|
+ errmsg = "file消息必须包含serialnumber";
|
|
|
+ }
|
|
|
+ if (!data.containsKey("fobsurl") || "".equals(mesageObj.getString("fobsurl"))) {
|
|
|
+ errmsg = "file消息必须包含fobsurl";
|
|
|
+ }
|
|
|
+ if (!data.containsKey("fdocument") || "".equals(mesageObj.getString("fdocument"))) {
|
|
|
+ errmsg = "file消息必须包含fdocument";
|
|
|
+ }
|
|
|
+ } else if ("data".equals(messagetype)) {
|
|
|
+ if (!data.containsKey("type") || "".equals(mesageObj.getString("type"))) {
|
|
|
+ errmsg = "data消息必须包含type";
|
|
|
+ }
|
|
|
+ if (!data.containsKey("ownertable") || "".equals(mesageObj.getString("ownertable"))) {
|
|
|
+ errmsg = "data消息必须包含ownertable";
|
|
|
+ }
|
|
|
+ if (!data.containsKey("ownerid") || "".equals(mesageObj.getString("ownerid"))) {
|
|
|
+ errmsg = "data消息必须包含ownerid";
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (!"".equals(errmsg)) {
|
|
|
+ sendMessage(errmsg);
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ return mesageObj;
|
|
|
+ }
|
|
|
+
|
|
|
+ @OnError
|
|
|
+ private void onError(Session session, Throwable error) {
|
|
|
+ error.printStackTrace();
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 对当前连接发送消息
|
|
|
+ *
|
|
|
+ * @param message
|
|
|
+ */
|
|
|
+ public void sendMessage(String message) {
|
|
|
+ session.getAsyncRemote().sendText(message);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 向指定的对象发送消息
|
|
|
+ *
|
|
|
+ * @param message
|
|
|
+ * @param toUserid
|
|
|
+ * @throws IOException
|
|
|
+ */
|
|
|
+ public void sendMessageToUser(String message, long toUserid) throws IOException {
|
|
|
+ if (websocketClients.containsKey(toUserid)) {
|
|
|
+ websocketClients.get(toUserid).session.getAsyncRemote().sendText(message);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 向指定的d对话框发送消息
|
|
|
+ *
|
|
|
+ * @param message
|
|
|
+ * @param dialogid
|
|
|
+ * @throws IOException
|
|
|
+ */
|
|
|
+ public void sendMessageToDialog(String message, long dialogid) throws IOException {
|
|
|
+ for (WebClientSocket item : websocketClients.values()) {
|
|
|
+ item.session.getAsyncRemote().sendText(message);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+}
|