diff --git a/pom.xml b/pom.xml index 1a1f665..5d3c982 100644 --- a/pom.xml +++ b/pom.xml @@ -160,6 +160,13 @@ 3.12.0 + + org.t-io + tio-websocket-spring-boot-starter + + 3.3.2.v20190601-RELEASE + + diff --git a/src/main/java/com/dd/admin/AdminApplication.java b/src/main/java/com/dd/admin/AdminApplication.java index 07d2945..8841008 100644 --- a/src/main/java/com/dd/admin/AdminApplication.java +++ b/src/main/java/com/dd/admin/AdminApplication.java @@ -2,8 +2,10 @@ package com.dd.admin; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.tio.websocket.starter.EnableTioWebSocketServer; @SpringBootApplication +@EnableTioWebSocketServer public class AdminApplication { public static void main(String[] args) { diff --git a/src/main/java/com/dd/admin/business/webSocket/MsgHandlerInterface.java b/src/main/java/com/dd/admin/business/webSocket/MsgHandlerInterface.java new file mode 100644 index 0000000..4f4f248 --- /dev/null +++ b/src/main/java/com/dd/admin/business/webSocket/MsgHandlerInterface.java @@ -0,0 +1,13 @@ +package com.dd.admin.business.webSocket; + +import org.tio.core.ChannelContext; + +import java.util.Map; + +/** + * 处理消息的抽象接口 + * @Author: 王旭磊 + */ +public interface MsgHandlerInterface { + Object handler(Map map, ChannelContext context); +} diff --git a/src/main/java/com/dd/admin/business/webSocket/MyWebSocketMsgHandler.java b/src/main/java/com/dd/admin/business/webSocket/MyWebSocketMsgHandler.java new file mode 100644 index 0000000..7fb1100 --- /dev/null +++ b/src/main/java/com/dd/admin/business/webSocket/MyWebSocketMsgHandler.java @@ -0,0 +1 @@ +package com.dd.admin.business.webSocket; import cn.stylefeng.guns.core.websocket.config.HandlerType; import cn.stylefeng.guns.core.websocket.handler.GroupMessageHandler; import cn.stylefeng.guns.core.websocket.handler.OfflineMessageHandler; import cn.stylefeng.guns.core.websocket.handler.P2PMessageHandler; import cn.stylefeng.guns.core.websocket.handler.WeiXinOfflineMessageHandler; import cn.stylefeng.guns.core.websocket.model.LayimUser; import cn.stylefeng.guns.generator.core.util.StringUtil; import com.alibaba.fastjson.JSON; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.tio.core.ChannelContext; import org.tio.core.Tio; import org.tio.http.common.HttpRequest; import org.tio.http.common.HttpResponse; import org.tio.utils.lock.SetWithLock; import org.tio.websocket.common.WsRequest; import org.tio.websocket.server.handler.IWsMsgHandler; import org.tio.websocket.starter.TioWebSocketServerBootstrap; import javax.annotation.PostConstruct; import java.util.HashMap; import java.util.Map; import java.util.Set; @Component public class MyWebSocketMsgHandler implements IWsMsgHandler { cn.stylefeng.guns.core.websocket.MyWebSocketMsgHandler handler; private static Logger log = LoggerFactory.getLogger(cn.stylefeng.guns.core.websocket.MyWebSocketMsgHandler.class); @PostConstruct public void init() { handler = this; } @Autowired public TioWebSocketServerBootstrap bootstrap; private Map handlerMap = new HashMap(); private MyWebSocketMsgHandler() { handlerMap.put(HandlerType.P2P_REQ,new P2PMessageHandler()); handlerMap.put(HandlerType.GROUP_MSG_REQ,new GroupMessageHandler()); handlerMap.put(HandlerType.OFFLINE_MESSAGE_REQ_MSG,new OfflineMessageHandler()); handlerMap.put(HandlerType.WEIXIN_OFFLINE_MESSAGE_REQ_MSG,new WeiXinOfflineMessageHandler()); } @Override public HttpResponse handshake(HttpRequest request, HttpResponse httpResponse, ChannelContext channelContext) throws Exception { String user = request.getParam("user"); String clientip = request.getClientIp(); LayimUser layimUser = JSON.parseObject(user,LayimUser.class); String id = layimUser.getId(); String username = layimUser.getUsername(); Tio.bindUser(channelContext,id); channelContext.setAttribute("name",username); channelContext.setAttribute("ip",clientip); log.info("user"+user); System.out.println(username+":进入了Tio id:"+id+"name:"+username+" ip:"+clientip); SetWithLock channelContexts = Tio.getAllChannelContexts(bootstrap.getServerGroupContext()); Set contextList = channelContexts.getObj(); System.out.println("当前在线用户:"); for(ChannelContext context:contextList){ System.out.println(context.getAttribute("name")+"\t"); } Integer count = channelContexts.size(); return httpResponse; } @Override public void onAfterHandshaked(HttpRequest httpRequest, HttpResponse httpResponse, ChannelContext channelContext) throws Exception { // System.out.println("握手成功进入群组"); } @Override public Object onBytes(WsRequest wsRequest, byte[] bytes, ChannelContext channelContext) throws Exception { System.out.println("接收到bytes消息"); return null; } @Override public Object onClose(WsRequest wsRequest, byte[] bytes, ChannelContext channelContext) throws Exception { return null; } @Override public Object onText(WsRequest wsRequest, String text, ChannelContext channelContext) throws Exception { if(text.equals("心跳内容")) return null; System.out.println("接收到文本消息:"+text); Map map = JSON.parseObject(text,Map.class); String handlerType =(String)map.get("hanlderType"); if(!StringUtil.isEmpty(handlerType)){ MsgHandlerInterface msgHandler = (MsgHandlerInterface) handlerMap.get(handlerType); if(msgHandler!=null){ msgHandler.handler(map,channelContext); }else{ log.debug("非法请求..."); } }else{ log.debug("非法请求..."); } System.out.println(map); return null; } } \ No newline at end of file diff --git a/src/main/java/com/dd/admin/business/webSocket/controller/WsController.java b/src/main/java/com/dd/admin/business/webSocket/controller/WsController.java new file mode 100644 index 0000000..16ec4ac --- /dev/null +++ b/src/main/java/com/dd/admin/business/webSocket/controller/WsController.java @@ -0,0 +1 @@ +package com.dd.admin.business.webSocket.controller; import cn.stylefeng.guns.base.shiro.ShiroUser; import cn.stylefeng.guns.core.websocket.Mapper.WsMapper; import cn.stylefeng.guns.core.websocket.model.LayimFriend; import cn.stylefeng.guns.core.websocket.model.LayimInit; import cn.stylefeng.guns.core.websocket.model.LayimUser; import cn.stylefeng.guns.sys.core.shiro.ShiroKit; import cn.stylefeng.roses.core.reqres.response.ResponseData; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import java.util.ArrayList; import java.util.List; @RequestMapping("/ws") @Controller public class WsController { @Autowired WsMapper wsMapper; @RequestMapping("/init") @ResponseBody public ResponseData init(){ ShiroUser user = ShiroKit.getUser(); Long userId = user.getId(); Long deptId = user.getDeptId(); LayimUser mine = wsMapper.getMine(userId); LayimFriend friend = new LayimFriend();friend.setList(wsMapper.getFriends(userId,deptId)); List friends = new ArrayList<>();friends.add(friend); LayimInit init = new LayimInit(mine,friends,null); return ResponseData.success(0,"",init); } } \ No newline at end of file diff --git a/src/main/java/com/dd/admin/business/webSocket/handler/GroupMessageHandler.java b/src/main/java/com/dd/admin/business/webSocket/handler/GroupMessageHandler.java new file mode 100644 index 0000000..ff2bd2f --- /dev/null +++ b/src/main/java/com/dd/admin/business/webSocket/handler/GroupMessageHandler.java @@ -0,0 +1 @@ +package com.dd.admin.business.webSocket.handler; import cn.stylefeng.guns.core.websocket.MsgHandlerInterface; import org.springframework.stereotype.Component; import org.tio.core.ChannelContext; import java.util.Map; @Component public class GroupMessageHandler implements MsgHandlerInterface { @Override public Object handler(Map map, ChannelContext context ){ return null; } } \ No newline at end of file diff --git a/src/main/java/com/dd/admin/business/webSocket/handler/OfflineMessageHandler.java b/src/main/java/com/dd/admin/business/webSocket/handler/OfflineMessageHandler.java new file mode 100644 index 0000000..0803fcf --- /dev/null +++ b/src/main/java/com/dd/admin/business/webSocket/handler/OfflineMessageHandler.java @@ -0,0 +1 @@ +package com.dd.admin.business.webSocket.handler; import cn.stylefeng.guns.core.websocket.MsgHandlerInterface; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import org.tio.core.ChannelContext; import java.util.Map; @Component @Slf4j public class OfflineMessageHandler implements MsgHandlerInterface { @Override public Object handler(Map map, ChannelContext context ){ log.info("进入点对点聊天方法"); Map mine = (Map) map.get("mine"); Map to = (Map) map.get("to"); return null; } } \ No newline at end of file diff --git a/src/main/java/com/dd/admin/business/webSocket/handler/P2PMessageHandler.java b/src/main/java/com/dd/admin/business/webSocket/handler/P2PMessageHandler.java new file mode 100644 index 0000000..9beaf35 --- /dev/null +++ b/src/main/java/com/dd/admin/business/webSocket/handler/P2PMessageHandler.java @@ -0,0 +1 @@ +package com.dd.admin.business.webSocket.handler; import cn.hutool.core.bean.BeanUtil; import cn.stylefeng.guns.core.websocket.MsgHandlerInterface; import cn.stylefeng.guns.core.websocket.config.HandlerType; import cn.stylefeng.guns.core.websocket.util.TioUtil; import cn.stylefeng.guns.modular.messgae.model.params.ChatmessageParam; import cn.stylefeng.guns.modular.messgae.service.ChatmessageService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.tio.core.ChannelContext; import org.tio.core.Tio; import org.tio.utils.lock.SetWithLock; import javax.annotation.PostConstruct; import java.util.Date; import java.util.Map; import java.util.Set; @Component @Slf4j public class P2PMessageHandler implements MsgHandlerInterface { public static P2PMessageHandler handler; @Autowired ChatmessageService chatmessageService; @PostConstruct public void init() { handler = this; handler.chatmessageService = this.chatmessageService; } @Override public Object handler(Map map, ChannelContext context ){ Map mine = (Map) map.get("mine"); Map to = (Map) map.get("to"); String fromId = mine.get("id"); String content = mine.get("content"); String avatar = mine.get("avatar"); String userName = mine.get("username"); String type = to.get("type"); String toId = to.get("id"); boolean isMine = false; Long timestamp = new Date().getTime(); ChatmessageParam message = new ChatmessageParam(); message.setUsername(userName); message.setAvatar(avatar); message.setContent(content); message.setToUid(Long.valueOf(toId)); message.setType(type); message.setTimestamp(timestamp); message.setFromid(Long.valueOf(fromId)); // handler.chatmessageService.add(message); Map messageMap = BeanUtil.beanToMap(message); messageMap.put("mine",false); messageMap.put("id",fromId); //t-io支持多点登录,获取的是一个集合,因为此账号可能存在多个连接哦 SetWithLock contexts = Tio.getChannelContextsByUserid(context.getGroupContext(), toId); //用户在线 if(contexts!=null && contexts.size() > 0) { Set contextList = contexts.getObj(); //t-io支持多点登录,获取的是一个集合,向集合发送聊天信息 for (ChannelContext con : contextList) { TioUtil.sendMessage(con, HandlerType.P2P_REQ, messageMap); message.setUnreadPoint(1); } }else{ message.setUnreadPoint(2); } handler.chatmessageService.add(message); return null; }} \ No newline at end of file diff --git a/src/main/java/com/dd/admin/business/webSocket/handler/WeiXinOfflineMessageHandler.java b/src/main/java/com/dd/admin/business/webSocket/handler/WeiXinOfflineMessageHandler.java new file mode 100644 index 0000000..6aa89a9 --- /dev/null +++ b/src/main/java/com/dd/admin/business/webSocket/handler/WeiXinOfflineMessageHandler.java @@ -0,0 +1 @@ +package com.dd.admin.business.webSocket.handler; import cn.stylefeng.guns.core.websocket.MsgHandlerInterface; import org.springframework.stereotype.Component; import org.tio.core.ChannelContext; import java.util.Map; @Component public class WeiXinOfflineMessageHandler implements MsgHandlerInterface { @Override public Object handler(Map map, ChannelContext context ){ return null; } } \ No newline at end of file diff --git a/src/main/java/com/dd/admin/business/webSocket/util/TioUtil.java b/src/main/java/com/dd/admin/business/webSocket/util/TioUtil.java new file mode 100644 index 0000000..7ec82d4 --- /dev/null +++ b/src/main/java/com/dd/admin/business/webSocket/util/TioUtil.java @@ -0,0 +1 @@ +package com.dd.admin.business.webSocket.util; import cn.stylefeng.guns.core.websocket.model.SocketMsg; import com.alibaba.fastjson.JSON; import org.tio.core.ChannelContext; import org.tio.core.Tio; import org.tio.websocket.common.WsResponse; public class TioUtil { /** * 快速生成WsResponse * @param action * @param body * @return */ public static WsResponse madeWsResponse(String hanlderType, Object body){ SocketMsg msg = new SocketMsg(hanlderType,body); String reponseMsg = JSON.toJSONString(msg); return WsResponse.fromText(reponseMsg,"utf-8"); } public static boolean sendMessage(ChannelContext con, String hanlderType, Object body){ WsResponse weResponse = madeWsResponse(hanlderType,body); return Tio.send(con,weResponse); } } \ No newline at end of file