分布式处理websocket消息发送

好久没写文章了,记录一下最近的工作。

背景:最近使用websocket发送消息到通知前端操作,在单节点情况下,前端与后端点对点是没有问题的,但是在分布式情况下后端是不知道前端连接到的是哪个节点的websocket。为了处理这种情况引用了中间件redis或者mq,下面要说的是redis实现。

一、redis消息监听

redis可以实现很多东西譬如缓存、分布式锁等等,基本很多项目都会接入redis,这里就用到redis的消息监听,来实现websocket消息的发送。

先写一个监听配置类,注册redis方法与websocket主题映射

package springbootredis;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.nio.charset.StandardCharsets;
import java.util.stream.Stream;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.connection.MessageListener;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.listener.PatternTopic;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.data.redis.listener.adapter.MessageListenerAdapter;
import org.springframework.messaging.simp.SimpMessagingTemplate;

/**
 * 
 * 描述:redis 消息监听
 * @author sakyoka
 * @date 2024年3月3日 下午3:26:21
 */
@Configuration
public class RedisMessageListenerConfiguration {

    @Autowired
    private RedisConnectionFactory redisConnectionFactory;
    
    @Autowired
    private SimpMessagingTemplate simpMessagingTemplate;  
    

    @Target(ElementType.FIELD)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface SocketTopic {

        /**socket主题*/
        String value() default "";
        
        /**名称*/
        String name() default "";
    }
    
    public static class RedisTopic{
        
        @SocketTopic(value = "/topic/socketTest", name = "前端websocket订阅主题")
        public static final String REDIS_METHOD_TEST = "test";
    }
    
    @Bean
    public RedisMessageListenerContainer redisContainer() {
        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
        container.setConnectionFactory(redisConnectionFactory);
        
        //注册所有的redis监听主题
        Stream.of(RedisTopic.class.getFields())
            .forEach(e -> {
                SocketTopic socketTopic = e.getAnnotation(SocketTopic.class);
                try {
                    Object v = e.get(null);
                    MessageListener messageListener = new MessageListener() {
                        
                        @Override
                        public void onMessage(Message message, byte[] pattern) {
                            String value = new String(message.getBody(), StandardCharsets.UTF_8);
                            System.out.println("接收消息:"+ value);
                            simpMessagingTemplate.convertAndSend(socketTopic.value(), value);
                        }
                    };
                    System.out.println("注册监听reids方法:"+ v +",转发到websocket主题:"+  socketTopic.value());
                    container.addMessageListener(new MessageListenerAdapter(messageListener), new PatternTopic(v.toString()));
                } catch (Exception e1) {
                    throw new RuntimeException("注册:"+ socketTopic.name() +"监听失败", e1);
                }

            });
        return container;
    }
}

 在需要添加发送消息的地方,发送redis消息

stringRedisTemplate.convertAndSend(RedisMessageListenerConfiguration.RedisTopic.REDIS_METHOD_TEST, "test message");

 ok,通过reids在每个节点的方法监听转发带每个服务的websocket主题。

问题延伸

分布式websocket连接延伸问题,多个节点情况下,需要保证一次多次访问连接到同一个节点,不然会连接失败,这个大家是怎么处理的?

  • 25
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
分布式系统中使用WebSocket可以实现实时通信和数据传输。WebSocket是一种双向通信协议,它在客户端和服务器之间建立持久连接,允许双方实时交换数据。 在分布式系统中,可以使用WebSocket来实现以下功能: 1. 实时消息传递:WebSocket允许服务器主动向客户端发送消息,客户端也可以向服务器发送消息。这种实时通信特性对于分布式系统中的事件驱动架构非常有用,例如聊天应用程序、协同编辑器等。 2. 数据推送:服务器可以将数据实时推送给订阅者,而不需要客户端主动轮询服务器。这对于实时数据监控、股票市场报价等场景非常重要。 3. 负载均衡:在分布式系统中,可以使用负载均衡器将客户端的WebSocket请求分发到不同的服务器上。这样可以提高系统的可伸缩性和容错性。 4. 消息广播:WebSocket可以广播消息给所有连接的客户端,这对于分布式系统中的通知、事件广播等场景非常有用。 需要注意的是,在分布式系统中使用WebSocket时,需要考虑以下几个方面: 1. 连接管理:分布式系统中可能存在多个WebSocket服务器,需要考虑如何管理连接和维护会话状态。 2. 路由和负载均衡:需要使用合适的负载均衡策略将客户端的请求分发到不同的WebSocket服务器上。 3. 数据一致性:如果分布式系统中需要保持数据一致性,需要确保消息的正确传输和处理。 总之,WebSocket分布式系统中可以实现实时通信和数据传输,但需要考虑连接管理、负载均衡和数据一致性等问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值