From 7a86c47776bd997e8761412ed5464fe6acfb302a Mon Sep 17 00:00:00 2001 From: lxyer <237809796@qq.com> Date: Sun, 18 Nov 2018 10:27:27 +0800 Subject: [PATCH] =?UTF-8?q?1=E3=80=81=E3=80=90=E6=96=B0=E5=A2=9E=E3=80=91?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0IM=202=E3=80=81=E3=80=90=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E3=80=91=E6=B7=BB=E5=8A=A0=E9=A1=B9=E7=9B=AE=E9=A1=B5=E9=9D=A2?= =?UTF-8?q?=202=E3=80=81=E3=80=90=E6=96=B0=E5=A2=9E/=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E3=80=91=E5=B0=86=E6=97=A5=E5=BF=97=E5=86=99=E5=85=A5=E5=88=B0?= =?UTF-8?q?ArangoDb=EF=BC=88=E5=8E=9F=E6=9D=A5MongoDb=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 26 +++-- root/project/index.html | 26 ++++- src/com/lxyer/bbs/base/ArangoKit.java | 40 +++++++ src/com/lxyer/bbs/base/BaseServlet.java | 2 - src/com/lxyer/bbs/base/TaskQueue.java | 10 +- src/com/lxyer/bbs/base/entity/VisLog.java | 13 +-- src/com/lxyer/redim/ChatWebSocket.java | 108 ++++++++++++++++++ src/com/lxyer/redim/entity/MsgRecord.java | 87 ++++++++++++++ src/com/lxyer/redim/info/MsgInfo.java | 101 ++++++++++++++++ .../lxyer/redim/service/ImFriendService.java | 59 ++++++++++ src/com/lxyer/redim/service/ImMsgService.java | 43 +++++++ src/com/lxyer/redim/servlet/ImServlet.java | 30 +++++ 12 files changed, 518 insertions(+), 27 deletions(-) create mode 100644 src/com/lxyer/bbs/base/ArangoKit.java create mode 100644 src/com/lxyer/redim/ChatWebSocket.java create mode 100644 src/com/lxyer/redim/entity/MsgRecord.java create mode 100644 src/com/lxyer/redim/info/MsgInfo.java create mode 100644 src/com/lxyer/redim/service/ImFriendService.java create mode 100644 src/com/lxyer/redim/service/ImMsgService.java create mode 100644 src/com/lxyer/redim/servlet/ImServlet.java diff --git a/pom.xml b/pom.xml index 0bfe40e..48a5c71 100644 --- a/pom.xml +++ b/pom.xml @@ -14,8 +14,8 @@ org.apache.maven.plugins maven-compiler-plugin - 10 - 10 + 11 + 11 @@ -25,12 +25,12 @@ org.redkale redkale - 1.9.6 + 1.9.8 org.redkalex redkale-plugins - 1.9.5.2 + 1.9.8 @@ -41,17 +41,21 @@ com.jfinal enjoy - 3.4 - - - org.mongodb - mongodb-driver - 3.8.0 + 3.5 + + org.mongodb mongo-java-driver - 3.8.0 + 3.9.0 + + + + + com.arangodb + arangodb-java-driver + 5.0.1 com.lxyer diff --git a/root/project/index.html b/root/project/index.html index 4c4c801..ff23590 100644 --- a/root/project/index.html +++ b/root/project/index.html @@ -3,11 +3,23 @@ #set(title=bean.title) #set(keywords=bean.title) #set(description=bean.title) +#set( + project=["redbbs","redtimer", "ExcelUtil","jfly"] +) #@layout() #define css() #end @@ -15,6 +27,16 @@
+ #for(x : project) +
+
+ +
+
+ #end + + + #define xx()
@@ -221,8 +243,8 @@
-->
-
- + + #end #end diff --git a/src/com/lxyer/bbs/base/ArangoKit.java b/src/com/lxyer/bbs/base/ArangoKit.java new file mode 100644 index 0000000..d75cb85 --- /dev/null +++ b/src/com/lxyer/bbs/base/ArangoKit.java @@ -0,0 +1,40 @@ +package com.lxyer.bbs.base; + +import com.arangodb.ArangoCollection; +import com.arangodb.ArangoDB; +import com.arangodb.ArangoDatabase; +import com.lxyer.bbs.base.entity.VisLog; + +import java.util.function.Function; + +/** + * @author: liangxianyou at 2018/11/18 9:02. + */ +public class ArangoKit { + + protected static final boolean winos = System.getProperty("os.name").contains("Window"); + + protected static Function chDev = (s) -> s + (winos ? "_dev" : ""); + + //Arango + protected static ArangoDB arangoDb = new ArangoDB.Builder().host("120.24.230.60", 8529).user("root").password("root").build(); + protected static ArangoDatabase dbDev = arangoDb.db(chDev.apply("redbbs")); + protected static ArangoCollection colVisLog = dbDev.collection(chDev.apply("vis_log")); + + static { + if (!dbDev.exists()) { + dbDev.create(); + } + + if (!colVisLog.exists()) { + colVisLog.create(); + } + } + + public static void save(T t) { + if (t instanceof VisLog) { + colVisLog.insertDocument(t); + } + } + +} diff --git a/src/com/lxyer/bbs/base/BaseServlet.java b/src/com/lxyer/bbs/base/BaseServlet.java index ae75a8f..0f58633 100644 --- a/src/com/lxyer/bbs/base/BaseServlet.java +++ b/src/com/lxyer/bbs/base/BaseServlet.java @@ -86,9 +86,7 @@ public class BaseServlet extends HttpServlet { VisLog visLog = new VisLog(); visLog.setIp(request.getRemoteAddr()); - visLog.setUri(request.getRequestURI()); visLog.setHeaders(headers); - visLog.setUserid(userid); visLog.setPara(para); visLog.setTime(System.currentTimeMillis()); visLog.setFtime(String.format("%1$tY%1$tm%1$td%1$tH%1$tM%1$tS", visLog.getTime())); diff --git a/src/com/lxyer/bbs/base/TaskQueue.java b/src/com/lxyer/bbs/base/TaskQueue.java index f16e2e9..18be055 100644 --- a/src/com/lxyer/bbs/base/TaskQueue.java +++ b/src/com/lxyer/bbs/base/TaskQueue.java @@ -1,5 +1,6 @@ package com.lxyer.bbs.base; +import com.lxyer.bbs.base.entity.VisLog; import com.lxyer.bbs.base.kit.LxyKit; import com.lxyer.bbs.base.user.UserInfo; import com.lxyer.bbs.base.user.UserRecord; @@ -83,7 +84,12 @@ public class TaskQueue extends BaseService implements Runnable public void run() { try { while (true){ - Map logData = (Map) take(); + T task = take(); + if (task instanceof VisLog) { + ArangoKit.save(task); + } + + /*Map logData = (Map) take(); logData.put("ftime", String.format("%1$tY%1$tm%1$td%1$tH%1$tM%1$tS", logData.get("time"))); visLog.insertOne(new Document(logData)); @@ -94,7 +100,7 @@ public class TaskQueue extends BaseService implements Runnable //[访问量] if (uri.startsWith("/jie/detail/")){ updateViewNumAsync(logData); - } + }*/ } } catch (InterruptedException e) { e.printStackTrace(); diff --git a/src/com/lxyer/bbs/base/entity/VisLog.java b/src/com/lxyer/bbs/base/entity/VisLog.java index f35ebaf..1515cef 100644 --- a/src/com/lxyer/bbs/base/entity/VisLog.java +++ b/src/com/lxyer/bbs/base/entity/VisLog.java @@ -1,7 +1,5 @@ package com.lxyer.bbs.base.entity; -import org.redkale.convert.json.JsonConvert; - import java.util.Map; /** @@ -11,7 +9,7 @@ import java.util.Map; */ public class VisLog { private String ip; - private int userid; + private String userid; private String ftime; private String uri; private long time; @@ -26,11 +24,11 @@ public class VisLog { this.ip = ip; } - public int getUserid() { + public String getUserid() { return userid; } - public void setUserid(int userid) { + public void setUserid(String userid) { this.userid = userid; } @@ -73,9 +71,4 @@ public class VisLog { public void setHeaders(Map headers) { this.headers = headers; } - - @Override - public String toString() { - return JsonConvert.root().convertTo(this); - } } diff --git a/src/com/lxyer/redim/ChatWebSocket.java b/src/com/lxyer/redim/ChatWebSocket.java new file mode 100644 index 0000000..e553034 --- /dev/null +++ b/src/com/lxyer/redim/ChatWebSocket.java @@ -0,0 +1,108 @@ +package com.lxyer.redim; + +import com.lxyer.base.JBean; +import com.lxyer.redim.entity.MsgRecord; +import com.lxyer.redim.info.MsgInfo; +import com.lxyer.redim.service.ImFriendService; +import com.lxyer.redim.service.ImMsgService; +import org.redkale.net.http.*; + +import javax.annotation.Resource; +import java.util.List; +import java.util.Map; +import java.util.Random; +import java.util.concurrent.CompletableFuture; + +/** + * + * Created by liangxianyou at 2018/7/8 22:51. + */ +@RestWebSocket(name = "chat", catalog = "ws", comment = "文字聊天", anyuser = true) +public class ChatWebSocket extends WebSocket { + + @Resource + protected ImMsgService chatService; + @Resource + protected ImFriendService imFriendService; + + protected Random random = new Random(); + + @Override + protected CompletableFuture onOpen(HttpRequest request) { + String token = request.getParameter("token"); + return CompletableFuture.supplyAsync(() -> { + if (token == null) { + setAttribute("isyk", true); + return request.getSessionid(false); + } + return token; + }); + } + + @Override + public CompletableFuture createUserid() { + return CompletableFuture.supplyAsync(()-> { + int userid = 0; + + //fixme: 1、isyk => tour; 2、set cate to user global + if (getAttribute("isyk") == null){//tour + userid = imFriendService.currentUserid(getSessionid()); + setAttribute("isyk", true); + } + + //如果未获取登录信息,使用token.hashCode 负值 作为登录用户 + if (userid == 0){ + //MsgInfo msgInfo = new MsgInfo(); + userid = - Math.abs(getSessionid().hashCode()); + } + + //接收离线信息 + int finalUserid = userid; + CompletableFuture.runAsync(()->{ + JBean> list = chatService.offlineMsg(finalUserid); + List recordList = list.getResult(); + + if (recordList != null && recordList.size() > 0){ + recordList.forEach(msgRecord->{ + JBean msgInfo = chatService.createMsgInfo(msgRecord); + send(msgInfo.getResult()).thenAccept(x->{ + if ((Integer)x == 0){//发送成功 + msgRecord.setStatus((short) 20); + } + chatService.update(msgRecord); + }); + }); + } + }); + + return userid; + }); + } + + @Override + public void preOnMessage(String restmapping, WebSocketParam param, Runnable messageEvent) { + super.preOnMessage(restmapping, param, messageEvent); + } + + @RestOnMessage(name = "text") + public void onChatMessage(MsgRecord msg, Map extmap) { + msg.setFromuserid((Integer) getUserid()); + + JBean msgInfo = chatService.createMsgInfo(msg); + + sendMessage(msgInfo.getResult(), msg.getTouserid()).thenAccept(x->{ + if ((Integer)x == 0){//发送成功 + msg.setStatus((short) 20); + } + chatService.insert(msg); + }); + } + + + @Override + @RestOnMessage(name = "close") + public void onClose(int code, String reason) { + System.out.println("close!"); + super.onClose(code, reason); + } +} \ No newline at end of file diff --git a/src/com/lxyer/redim/entity/MsgRecord.java b/src/com/lxyer/redim/entity/MsgRecord.java new file mode 100644 index 0000000..3b32bbe --- /dev/null +++ b/src/com/lxyer/redim/entity/MsgRecord.java @@ -0,0 +1,87 @@ +package com.lxyer.redim.entity; + +import org.redkale.convert.json.JsonConvert; + +import javax.persistence.*; + +/** + * + * @author lxyer + */ +@Cacheable(interval = 5*60) +@Table(catalog = "redbbs", name = "im_msgrecord", comment = "[聊天记录表]") +public class MsgRecord implements java.io.Serializable { + + @Id + @GeneratedValue + @Column(comment = "[主键id]") + private int msgid; + + @Column(comment = "[发送人]") + private int fromuserid; + + @Column(comment = "[接收人]") + private int touserid; + + @Column(comment = "[内容]") + private String content = ""; + + @Column(updatable = false, comment = "[发送时间]") + private long createtime = System.currentTimeMillis(); + + @Column(comment = "[状态]-10删除,10未发送 20已发送 30已读") + private short status = 10; + + public void setMsgid(int msgid) { + this.msgid = msgid; + } + + public int getMsgid() { + return this.msgid; + } + + public void setFromuserid(int fromuserid) { + this.fromuserid = fromuserid; + } + + public int getFromuserid() { + return this.fromuserid; + } + + public void setTouserid(int touserid) { + this.touserid = touserid; + } + + public int getTouserid() { + return this.touserid; + } + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } + + public void setCreatetime(long createtime) { + this.createtime = createtime; + } + + public long getCreatetime() { + return this.createtime; + } + + public void setStatus(short status) { + this.status = status; + } + + public short getStatus() { + return this.status; + } + + @Override + public String toString() { + return JsonConvert.root().convertTo(this); + } +} diff --git a/src/com/lxyer/redim/info/MsgInfo.java b/src/com/lxyer/redim/info/MsgInfo.java new file mode 100644 index 0000000..80c0c04 --- /dev/null +++ b/src/com/lxyer/redim/info/MsgInfo.java @@ -0,0 +1,101 @@ +package com.lxyer.redim.info; + +/** + * @author: liangxianyou at 2018/8/12 15:04. + */ +public class MsgInfo { + + private String username; + private String avatar; + private int id; + private String type; + private String content; + private int cid; + private boolean mine; + private int fromid; + private long timestamp; + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } + + public int getCid() { + return cid; + } + + public void setCid(int cid) { + this.cid = cid; + } + + public boolean isMine() { + return mine; + } + + public void setMine(boolean mine) { + this.mine = mine; + } + + public int getFromid() { + return fromid; + } + + public void setFromid(int fromid) { + this.fromid = fromid; + } + + public long getTimestamp() { + return timestamp; + } + + public void setTimestamp(long timestamp) { + this.timestamp = timestamp; + } + + /*var message = { + username: "纸飞机" //消息来源用户名 + ,avatar: "http://tp1.sinaimg.cn/1571889140/180/40030060651/1" //消息来源用户头像 + ,id: "100000" //消息的来源ID(如果是私聊,则是用户id,如果是群聊,则是群组id) + ,type: "friend" //聊天窗口来源类型,从发送消息传递的to里面获取 + ,content: "嗨,你好!本消息系离线消息。" //消息内容 + ,cid: 0 //消息id,可不传。除非你要对消息进行一些操作(如撤回) + ,mine: false //是否我发送的消息,如果为true,则会显示在右方 + ,fromid: "100000" //消息的发送者id(比如群组中的某个消息发送者),可用于自动解决浏览器多窗口时的一些问题 + ,timestamp: 1467475443306 //服务端时间戳毫秒数。注意:如果你返回的是标准的 unix 时间戳,记得要 *1000 +}*/ +} diff --git a/src/com/lxyer/redim/service/ImFriendService.java b/src/com/lxyer/redim/service/ImFriendService.java new file mode 100644 index 0000000..facde36 --- /dev/null +++ b/src/com/lxyer/redim/service/ImFriendService.java @@ -0,0 +1,59 @@ +package com.lxyer.redim.service; + +import com.lxyer.base.JBean; +import org.redkale.service.Service; + +public interface ImFriendService extends Service { + + //================ 查询相关 ================= + /** + * 分组好友数据 + * @return + */ + JBean friends(String sessionid); + + /** + * 根据条件查询好友 + * @return + */ + JBean friendList(String sessionid); + + /** + * 群组数据 + * @return + */ + JBean groups(String sessionid); + + + //================ 操作好友相关 ================= + /** + * 保存好友分组 + * @return + */ + JBean itemSave(String sessionid); + /** + * 添加好友 + * @return + */ + JBean addFriend(String sessionid); + + //================ 操作群组相关 ================= + /** + * 保存群组 + * @return + */ + JBean groupSave(String sessionid); + + /** + * 加入群组 + * @return + */ + JBean addGroup(String sessionid); + + /** + * 登录人用户id + * @param sessionid + * @return + */ + int currentUserid(String sessionid); +} diff --git a/src/com/lxyer/redim/service/ImMsgService.java b/src/com/lxyer/redim/service/ImMsgService.java new file mode 100644 index 0000000..76deac7 --- /dev/null +++ b/src/com/lxyer/redim/service/ImMsgService.java @@ -0,0 +1,43 @@ +package com.lxyer.redim.service; + +import com.lxyer.base.JBean; +import com.lxyer.redim.entity.MsgRecord; +import com.lxyer.redim.info.MsgInfo; +import org.redkale.service.Service; + +import java.util.List; + + +public interface ImMsgService extends Service { + + /** + * 消息入库 + * @param msg + */ + JBean insert(MsgRecord... msg); + + /** + * 消息修改 + */ + JBean update(MsgRecord... msg); + + /** + * 历史消息 + * @return + */ + JBean list(); + + /** + * 创建消息体 + * + * @param msg + */ + JBean createMsgInfo(MsgRecord msg); + + /** + * 获取离线消息 + * @param userid + * @return + */ + JBean> offlineMsg(int userid); +} diff --git a/src/com/lxyer/redim/servlet/ImServlet.java b/src/com/lxyer/redim/servlet/ImServlet.java new file mode 100644 index 0000000..c574cbf --- /dev/null +++ b/src/com/lxyer/redim/servlet/ImServlet.java @@ -0,0 +1,30 @@ +package com.lxyer.redim.servlet; + +import com.lxyer.base.JBean; +import com.lxyer.redim.service.ImFriendService; +import org.redkale.net.http.*; + +import javax.annotation.Resource; +import java.util.logging.Logger; + +/** + * @author: liangxianyou at 2018/8/5 23:55. + */ +@WebServlet(value = {"/imx/*"}, comment = "测试servlet") +public class ImServlet extends HttpServlet { + + public Logger log = Logger.getLogger(this.getClass().getSimpleName()); + + @Resource + ImFriendService imFriendService; + + @HttpMapping(url = "/imx/friends", comment = "测试函数") + public void abc(HttpRequest request, HttpResponse response){ + + String token = request.getParameter("token"); + + JBean jBean = imFriendService.friends(token); + response.finish(jBean.getResult()); + } + +}