package com.zchd.zim; import com.zchd.base.info.SwearWordService; import com.zchd.base.util.Kv; import com.zchd.base.util.Utils; import com.zchd.zim.entity.ChannelMessage; import com.zchd.zim.entity.FriendMessage; import com.zchd.zim.entity.ImUser; import com.zdemo.cachex.MyRedisCacheSource; import org.redkale.net.http.HttpRequest; import org.redkale.net.http.RestOnMessage; import org.redkale.net.http.RestWebSocket; import org.redkale.net.http.WebSocket; import org.redkale.service.RetResult; import org.redkale.source.DataSource; import org.redkale.util.Comment; import javax.annotation.Resource; import java.util.Map; import java.util.concurrent.CompletableFuture; /* * ws://127.0.0.1:8091/im_chat?imtoken=xx * */ @RestWebSocket(name = "im_chat", comment = "IM即使通讯", anyuser = true) public class ImChatWebSocket extends WebSocket { @Resource(name = "z_im") protected DataSource zimSource; @Resource(name = "int_cache") protected MyRedisCacheSource intCache; @Resource protected ImAccountService accountService; @Resource protected ImChatService chatService; @Resource protected ImMessageMonitor messageMonitor; @Resource protected SwearWordService swearWordService; @Override protected CompletableFuture onOpen(HttpRequest request) { return CompletableFuture.supplyAsync(() -> { String token = request.getHeader("imtoken", request.getParameter("imtoken")); return token; }); } @Override protected CompletableFuture createUserid() { return CompletableFuture.supplyAsync(() -> { ImUser user = accountService.currentImUser(getSessionid()); int userid = user.getUserid(); if (userid > 0) { WebSocket socket = findLocalWebSocket(userid); if (socket != null) { forceCloseWebSocket(userid); } setAttribute("appid", user.getAppid()); setAttribute("guserid", user.getGuserid()); } return userid; }); } @Override public CompletableFuture onConnected() { return CompletableFuture.runAsync(() -> { final int userid = (int) getUserid(); getLogger().info("im:state-change:" + userid + "---ws connected---"); intCache.setBit("im:user", userid, true); // 上线开启订阅 messageMonitor.online(userid); // 拉取离线消息 chatService.pullOfflineMsg(userid); }); } /* {friend:{bean:{"type": "friend-text","content": "发给V的私聊"},extmap:{"mck":"11001and1234567860","guserid": "S_C_01_R0002"}}} {friend:{bean:{"type": "friend-text","content": "发给M的私聊"},extmap:{"mck":"11001and1234567861","guserid": "S_C_01_R0001"}}} */ @RestOnMessage(name = "friend", comment = "私聊消息") public void friend(@Comment("content、type") Map bean, @Comment("mck、guserid") Map extmap) { int userid = (int) getUserid(); String guserid = extmap.get("guserid"); String appid = (String) getAttribute("appid"); String mck = extmap.get("mck"); int targetguserid = chatService.getUserid(appid, guserid); FriendMessage message = FriendMessage.buildFriendMessage(bean.get("content"), userid, targetguserid); // 禁言检查 if (intCache.getBit("im:banned-talk", userid)) { sendTip("发送失败,你已被禁言", mck, 3002); return; } // 检查敏感词 :若加入消息撤回,可使用延时检查(后置审核),检查到违禁词 撤回消息 RetResult check = swearWordService.check(message.getContent()); if (!check.isSuccess()) { sendTip("发送消息含有敏感词", mck, 3001); return; } // 发送消息 chatService.sendFriendMessage(message); // 回执 Kv kv = chatService.buildBackMessage(message, mck); send(kv); } /* {channel:{bean:{"type": "channel-test","content": "asfsafasfsaf"},extmap:{"mck":"11001and1234567860","channeltype": "world","channelvalue": "2"}}} {channel:{bean:{"type": "channel-test","content": "这是世界频道消息V"},extmap:{"mck":"11001and1234567860","channeltype": "Word","channelvalue": "W_C_01_001"}}} */ @RestOnMessage(name = "channel", comment = "频道消息") public void channel(@Comment("content、type") Map bean, @Comment("mck、channeltype、channelvalue") Map extmap) { int userid = (int) getUserid(); String appid = (String) getAttribute("appid"); String channeltype = extmap.get("channeltype"); String channelvalue = extmap.get("channelvalue"); String mck = extmap.get("mck"); // 禁言检查 if (intCache.getBit("im:banned-talk", userid)) { sendTip("发送失败,你已被禁言", mck, 3002); return; } // 检查敏感词 :若加入消息撤回,可使用延时检查(后置审核),检查到违禁词 撤回消息 RetResult check = swearWordService.check(bean.get("content")); if (!check.isSuccess()) { sendTip("发送消息含有敏感词", mck, 3001); return; } ChannelMessage message = new ChannelMessage(); message.setContent(bean.get("content")); message.setAppid(appid); message.setSenduserid(userid); message.setChanneltype(channeltype); message.setChannelvalue(channelvalue); message.setCreatetime(System.currentTimeMillis()); message.setStatus((short) 20); message.setMessageid(Utils.fmt36(message.getSenduserid()) + "-" + Utils.fmt36(message.getCreatetime())); // 发送 chatService.sendChannelMessage(message); // 回执 Kv kv = chatService.buildBackMessage(message, mck); send(kv); } @Override public CompletableFuture onClose(int code, String reason) { final int userid = (int) getUserid(); getLogger().info("im:state-change:" + userid + "---close---" + code + "---" + reason); intCache.setBit("im:user:", userid, false); // 取消用户订阅 messageMonitor.offline(userid); return null; } @Comment("发送提示信息") public void sendTip(String tipinfo, String mck, int code) { Kv tip = Kv.of("type", "tip") .set("mck", mck).set("code", code) .set("info", tipinfo); send(tip); } }