You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rust中Redis Pub/Sub问题:消息无法接收

Redis Pub/Sub 消息无法接收的问题分析与修复

核心错误点

  • 消息发布早于订阅建立:代码先执行publish发送消息,之后才将连接转为PubSub模式并订阅频道,此时消息已发送完毕,订阅者完全没机会接收。
  • 同步连接误用在异步环境:get_connection()是同步Redis连接,但你用了#[tokio::main]的异步主函数,应该使用redis crate提供的异步API。
  • 单连接模式冲突:同一个Redis连接不能同时执行普通命令(如publish)和PubSub操作,as_pubsub()会将连接切换到PubSub专属模式,后续无法再用该连接执行普通操作。

修正后的代码

使用异步API,分离发布与订阅的连接(实际场景中通常是不同进程/服务,这里用异步任务模拟):

use redis::{AsyncCommands, Client, RedisError};

#[tokio::main]
async fn main() -> Result<(), RedisError> {
    // 初始化Redis客户端
    let client = Client::open("redis://127.0.0.1/")?;
    println!("Successfully connected to Redis!");
    let channel = "mychannel";
    let message = "hello";

    // 启动订阅异步任务
    tokio::spawn(async move {
        // 创建异步连接用于订阅
        let mut pubsub = client.get_async_connection().await?.into_pubsub();
        pubsub.subscribe(channel).await?;
        println!("subscribed to mychannel");

        loop {
            println!("waiting for message");
            let msg = pubsub.get_message().await?;
            let payload: String = msg.get_payload()?;
            println!("Received data on mychannel: {}", payload);
            println!("got message");
        }
    });

    // 等待订阅任务完成初始化(避免发布过早)
    tokio::time::sleep(tokio::time::Duration::from_millis(100)).await;

    // 创建单独的异步连接用于发布消息
    let mut con = client.get_async_connection().await?;
    con.publish(channel, message).await?;
    println!("message published");

    // 保持程序运行,等待接收消息
    tokio::time::sleep(tokio::time::Duration::from_secs(5)).await;

    Ok(())
}

关键修正说明

  1. 改用异步API:引入AsyncCommands trait,使用get_async_connection()获取异步连接,适配tokio异步运行环境。
  2. 分离发布与订阅连接:发布和订阅使用独立的Redis连接,避免模式冲突问题。
  3. 调整执行顺序:先启动订阅任务,短暂等待确保订阅建立后再发布消息,保证消息能被正常接收。
  4. 异步任务管理:用tokio::spawn将订阅逻辑放到后台异步任务,主任务负责发布消息并维持程序运行。

内容的提问来源于stack exchange,提问作者Segmentation fault

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 12:56:00