WebSocket 集成
This commit is contained in:
parent
8e3d812683
commit
c64f9cd7d3
@ -51,6 +51,7 @@ public class ShiroConfig implements EnvironmentAware {
|
|||||||
filterChainDefinitionMap.put("/login", "anon");
|
filterChainDefinitionMap.put("/login", "anon");
|
||||||
|
|
||||||
filterChainDefinitionMap.put("/api/**", "anon");
|
filterChainDefinitionMap.put("/api/**", "anon");
|
||||||
|
filterChainDefinitionMap.put("/ws/**", "anon");
|
||||||
filterChainDefinitionMap.put("/**", "auth");
|
filterChainDefinitionMap.put("/**", "auth");
|
||||||
//配置shiro默认登录界面地址,前后端分离中登录界面跳转应由前端路由控制,后台仅返回json数据
|
//配置shiro默认登录界面地址,前后端分离中登录界面跳转应由前端路由控制,后台仅返回json数据
|
||||||
shiroFilterFactoryBean.setLoginUrl("/login");
|
shiroFilterFactoryBean.setLoginUrl("/login");
|
||||||
|
@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
@ -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");
|
||||||
|
}
|
||||||
|
}
|
@ -8,6 +8,8 @@ import lombok.Data;
|
|||||||
@Data
|
@Data
|
||||||
public class TokenUser {
|
public class TokenUser {
|
||||||
|
|
||||||
|
private Integer idUser;
|
||||||
|
|
||||||
private String account;
|
private String account;
|
||||||
|
|
||||||
private String nickname;
|
private String nickname;
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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<WebSocketServer> webSocketSet = new CopyOnWriteArraySet<WebSocketServer>();
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 与某个客户端的连接会话,需要通过它来给客户端发送数据
|
|
||||||
*/
|
|
||||||
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--;
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user