From c64f9cd7d3fcd5921ca0617b4e2bb120df701738 Mon Sep 17 00:00:00 2001 From: ronger Date: Mon, 30 Dec 2019 16:41:28 +0800 Subject: [PATCH] =?UTF-8?q?WebSocket=20=E9=9B=86=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../rymcu/vertical/config/ShiroConfig.java | 1 + .../vertical/config/WebSocketConfigurer.java | 17 --- .../vertical/config/WebSocketStompConfig.java | 40 ++++++ .../com/rymcu/vertical/dto/TokenUser.java | 2 + .../web/api/common/WebSocketController.java | 59 ++++++++ .../web/api/common/WebSocketServer.java | 130 ------------------ 6 files changed, 102 insertions(+), 147 deletions(-) delete mode 100644 src/main/java/com/rymcu/vertical/config/WebSocketConfigurer.java create mode 100644 src/main/java/com/rymcu/vertical/config/WebSocketStompConfig.java create mode 100644 src/main/java/com/rymcu/vertical/web/api/common/WebSocketController.java delete mode 100644 src/main/java/com/rymcu/vertical/web/api/common/WebSocketServer.java diff --git a/src/main/java/com/rymcu/vertical/config/ShiroConfig.java b/src/main/java/com/rymcu/vertical/config/ShiroConfig.java index d827e53..76b1fb1 100644 --- a/src/main/java/com/rymcu/vertical/config/ShiroConfig.java +++ b/src/main/java/com/rymcu/vertical/config/ShiroConfig.java @@ -51,6 +51,7 @@ public class ShiroConfig implements EnvironmentAware { filterChainDefinitionMap.put("/login", "anon"); filterChainDefinitionMap.put("/api/**", "anon"); + filterChainDefinitionMap.put("/ws/**", "anon"); filterChainDefinitionMap.put("/**", "auth"); //配置shiro默认登录界面地址,前后端分离中登录界面跳转应由前端路由控制,后台仅返回json数据 shiroFilterFactoryBean.setLoginUrl("/login"); diff --git a/src/main/java/com/rymcu/vertical/config/WebSocketConfigurer.java b/src/main/java/com/rymcu/vertical/config/WebSocketConfigurer.java deleted file mode 100644 index 8c935ad..0000000 --- a/src/main/java/com/rymcu/vertical/config/WebSocketConfigurer.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.rymcu.vertical.config; - -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.web.socket.server.standard.ServerEndpointExporter; - -/** - * WebSocket 配置类 - * @author ronger - */ -@Configuration -public class WebSocketConfigurer { - @Bean - public ServerEndpointExporter serverEndpointExporter() { - return new ServerEndpointExporter(); - } -} diff --git a/src/main/java/com/rymcu/vertical/config/WebSocketStompConfig.java b/src/main/java/com/rymcu/vertical/config/WebSocketStompConfig.java new file mode 100644 index 0000000..9aeab12 --- /dev/null +++ b/src/main/java/com/rymcu/vertical/config/WebSocketStompConfig.java @@ -0,0 +1,40 @@ +package com.rymcu.vertical.config; + +import org.springframework.context.annotation.Configuration; +import org.springframework.messaging.simp.config.MessageBrokerRegistry; +import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker; +import org.springframework.web.socket.config.annotation.StompEndpointRegistry; +import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer; + +/** + * @author ronger + */ +@Configuration +@EnableWebSocketMessageBroker +public class WebSocketStompConfig implements WebSocketMessageBrokerConfigurer { + /** + * 注册stomp端点 + * @param registry + */ + @Override + public void registerStompEndpoints(StompEndpointRegistry registry) { + + // 允许使用socketJs方式访问 即可通过http://IP:PORT/ws来和服务端websocket连接 + registry.addEndpoint("/ws").setAllowedOrigins("*").withSockJS(); + } + + /** + * 配置信息代理 + * @param registry + */ + @Override + public void configureMessageBroker(MessageBrokerRegistry registry) { + + // 订阅Broker名称 user点对点 topic广播即群发 + registry.enableSimpleBroker("/user","/public"); + // 全局(客户端)使用的消息前缀 + registry.setApplicationDestinationPrefixes("/app"); + // 点对点使用的前缀 无需配置 默认/user + registry.setUserDestinationPrefix("/user"); + } +} diff --git a/src/main/java/com/rymcu/vertical/dto/TokenUser.java b/src/main/java/com/rymcu/vertical/dto/TokenUser.java index 9ab4e78..69501de 100644 --- a/src/main/java/com/rymcu/vertical/dto/TokenUser.java +++ b/src/main/java/com/rymcu/vertical/dto/TokenUser.java @@ -8,6 +8,8 @@ import lombok.Data; @Data public class TokenUser { + private Integer idUser; + private String account; private String nickname; diff --git a/src/main/java/com/rymcu/vertical/web/api/common/WebSocketController.java b/src/main/java/com/rymcu/vertical/web/api/common/WebSocketController.java new file mode 100644 index 0000000..5df9660 --- /dev/null +++ b/src/main/java/com/rymcu/vertical/web/api/common/WebSocketController.java @@ -0,0 +1,59 @@ +package com.rymcu.vertical.web.api.common; + +import com.alibaba.fastjson.JSONObject; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.messaging.handler.annotation.DestinationVariable; +import org.springframework.messaging.handler.annotation.MessageMapping; +import org.springframework.messaging.handler.annotation.SendTo; +import org.springframework.messaging.simp.SimpMessagingTemplate; +import org.springframework.messaging.simp.annotation.SendToUser; +import org.springframework.messaging.simp.stomp.StompHeaderAccessor; +import org.springframework.stereotype.Controller; + +import java.util.HashMap; + +/** + * @author ronger + */ +@Controller +public class WebSocketController { + + @Autowired + private SimpMessagingTemplate template; + + @MessageMapping("/sendMessage") + @SendTo("/public/greetings") + public void sendMessage(JSONObject message, StompHeaderAccessor headerAccessor){ + this.template.convertAndSend("/public/greetings",message); + } + + @MessageMapping("/message") + @SendToUser("/message") + public void message(JSONObject message){ + String type = message.get("type").toString(); + HashMap res = (HashMap) message.get("data"); + HashMap mine = (HashMap) res.get("mine"); + HashMap to = (HashMap) res.get("to"); + System.out.println(to.get("type")); + boolean flag = to.get("type").equals("friend")?true:false; + String id = to.get("id").toString(); + HashMap map = new HashMap(); + map.put("id",mine.get("id")); + map.put("avatar",mine.get("avatar")); + map.put("formid",mine.get("id")); + map.put("username",mine.get("username")); + map.put("type",to.get("type")); + map.put("content",mine.get("content")); + map.put("mine",false); + map.put("cid",0); + map.put("timestamp",""); + JSONObject json = new JSONObject(); + json.put("type",type); + json.put("data",map); + if(flag){ + this.template.convertAndSendToUser(id,"/message",json); + }else{ + this.template.convertAndSendToUser(id,"/message",json); + } + } +} diff --git a/src/main/java/com/rymcu/vertical/web/api/common/WebSocketServer.java b/src/main/java/com/rymcu/vertical/web/api/common/WebSocketServer.java deleted file mode 100644 index dc93ac6..0000000 --- a/src/main/java/com/rymcu/vertical/web/api/common/WebSocketServer.java +++ /dev/null @@ -1,130 +0,0 @@ -package com.rymcu.vertical.web.api.common; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Component; - -import javax.websocket.*; -import javax.websocket.server.PathParam; -import javax.websocket.server.ServerEndpoint; -import java.io.IOException; -import java.util.concurrent.CopyOnWriteArraySet; - -/** - * @author ronger - */ -@ServerEndpoint("/api/v1/websocket/{sid}") -@Component -public class WebSocketServer { - static final Logger log= LoggerFactory.getLogger(WebSocketServer.class); - /** - * 静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。 - * */ - private static int onlineCount = 0; - /** - * concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。 - */ - private static CopyOnWriteArraySet webSocketSet = new CopyOnWriteArraySet(); - - - /** - * 与某个客户端的连接会话,需要通过它来给客户端发送数据 - */ - private Session session; - - /** - * 接收sid - * */ - private String sid = ""; - /** - * 连接建立成功调用的方法*/ - @OnOpen - public void onOpen(Session session,@PathParam("sid") String sid) { - this.session = session; - webSocketSet.add(this); - addOnlineCount(); - log.info("有新窗口开始监听:" + sid + ",当前在线人数为" + getOnlineCount()); - this.sid=sid; - try { - sendMessage("连接成功"); - } catch (IOException e) { - log.error("websocket IO异常"); - } - } - - /** - * 连接关闭调用的方法 - */ - @OnClose - public void onClose() { - webSocketSet.remove(this); - subOnlineCount(); - log.info("有一连接关闭!当前在线人数为" + getOnlineCount()); - } - - /** - * 收到客户端消息后调用的方法 - * - * @param message 客户端发送过来的消息*/ - @OnMessage - public void onMessage(String message, Session session) { - log.info("收到来自窗口" + sid + "的信息:" + message); - //群发消息 - for (WebSocketServer item : webSocketSet) { - try { - item.sendMessage(message); - } catch (IOException e) { - e.printStackTrace(); - } - } - } - - /** - * - * @param session - * @param error - */ - @OnError - public void onError(Session session, Throwable error) { - log.error("发生错误"); - error.printStackTrace(); - } - /** - * 实现服务器主动推送 - */ - public void sendMessage(String message) throws IOException { - this.session.getBasicRemote().sendText(message); - } - - - /** - * 群发自定义消息 - * */ - public static void sendInfo(String message,@PathParam("sid") String sid) throws IOException { - log.info("推送消息到窗口"+sid+",推送内容:"+message); - for (WebSocketServer item : webSocketSet) { - try { - //这里可以设定只推送给这个sid的,为null则全部推送 - if(sid==null) { - item.sendMessage(message); - }else if(item.sid.equals(sid)){ - item.sendMessage(message); - } - } catch (IOException e) { - continue; - } - } - } - - public static synchronized int getOnlineCount() { - return onlineCount; - } - - public static synchronized void addOnlineCount() { - WebSocketServer.onlineCount++; - } - - public static synchronized void subOnlineCount() { - WebSocketServer.onlineCount--; - } -}