场景:在使用多个服务使用一个websocket地址进行推送,这里使用redis订阅发布来实现。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
websocket使用
@Slf4j
@ServerEndpoint(value = "/ws/alarm")
@Component
public class BaseWebSocket {
private static ConcurrentHashMap<String, BaseWebSocket> webSocketSet = new ConcurrentHashMap<String, BaseWebSocket>();
private Session session;
//uid
private String uid = "";
@OnOpen
public void onOpen(Session session) {
String param=session.getQueryString();
if(StringUtils.isBlank(param)){
return;
}
if(param.contains("uid=")){
String[] split = param.split("=");
this.uid= split[1];
this.session = session;
webSocketSet.put(session.getId(), this);//加入map中
}
}
/**
* 连接关闭调用的方法
*/
@OnClose
public void onClose(Session session) {
String sid = session.getId();
if (StringUtils.isNotBlank(sid)) {
webSocketSet.remove(sid);
}
}
/**
* 收到客户端消息后调用的方法
*
* @param message 客户端发送过来的消息
* @param session 可选的参数
*/
@OnMessage
public void onMessage(String message, Session session) {
log.info("来自客户端的消息:" + message);
}
@Autowired
SysUserManageService sysUserManageService;
/**
* @param message
*/
public void sendToUser(String message) {
for(String sid:webSocketSet.keySet()){
sendUserById(message, sid);
}
}
private void sendUserById(String message,String uid){
try {
if (webSocketSet.get(uid) != null) {
webSocketSet.get(uid).sendMessage(message,webSocketSet.get(uid));
}
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 发消息
*/
public void sendAll(String message) {
sendUserById(message, id);
}
@OnError
public void onError(Session session, Throwable error) {
error.printStackTrace();
}
public void sendMessage(String message,BaseWebSocket webSocketSet) throws IOException {
synchronized (webSocketSet.session) {
webSocketSet.session.getBasicRemote().sendText(message);
}
}
使用
@Autowired
BaseWebSocket baseWebSocket;
baseWebSocket.sendToUser(String);
多服务中
websocket服务端
@Configuration
public class MsgListenerConfig extends CachingConfigurerSupport {
/**
* 消息监听容器
*/
@Bean
RedisMessageListenerContainer container(RedisConnectionFactory factory){
RedisMessageListenerContainer container = new RedisMessageListenerContainer();
container.setConnectionFactory(factory);
//订阅一个通道 该处的通道名是发布消息时的名称
container.addMessageListener(msgAdapter(),new PatternTopic("appMsg"));
return container;
}
/**
* 消息监听适配器,绑定消息处理器
*/
@Bean
MessageListenerAdapter msgAdapter(){
return new MessageListenerAdapter(new MsgListener());
}
}
@Component
@Slf4j
public class MsgListener implements MessageListener {
@Autowired
BaseWebSocket baseWebSocket;
@Override
public void onMessage(Message message, byte[] bytes) {
log.info("appMsg:" + message.toString());
if(baseWebSocket==null){
baseWebSocket=SpringContextUtil.getBean(BaseWebSocket.class);
}
baseWebSocket.sendToUser(message.toString());
}
}
其他服务端
@Autowired
StringRedisTemplate stringRedisTemplate;
stringRedisTemplate.convertAndSend("appMsg", "str");