使用Booksleeve维护开放的Redis PubSub订阅

时间:2012-04-09 19:31:41

标签: asp.net asp.net-mvc redis booksleeve

我使用Redis pubsub通道将工作进程池中的消息发送到我的ASP.NET应用程序。收到消息后,我的应用程序会将消息转发到带有SignalR的客户端浏览器。

我发现this solution维持与Redis的开放连接,但它在重新创建连接时没有考虑订阅。

我目前正在Global.asax文件中处理Redis pubsub消息:

public class Application : HttpApplication
{
    protected void Application_Start()
    {
        var gateway = Resolve<RedisConnectionGateway>();
        var connection = gateway.GetConnection();
        var channel = connection.GetOpenSubscriberChannel();

        channel.PatternSubscribe("workers:job-done:*", OnExecutionCompleted);
    }

    /// <summary>
    /// Handle messages received from workers through Redis.</summary>
    private static void OnExecutionCompleted(string key, byte[] message)
    {
        /* forwarded the response to the client that requested it */
    }
}

当前RedisConnection因任何原因关闭时会出现问题。最简单的解决方案是在重置连接时从RedisConnectionGateway类触发事件,并使用新的RedisSubscriberChannel重新订阅。但是,在重置连接时发布到通道的任何消息都将丢失。

是否有任何推荐的方法来处理这种情况?

1 个答案:

答案 0 :(得分:7)

是的,如果连接中断(网络不稳定,重新掌握,等等),那么您将需要重新应用您所做的任何订阅。重新连接和重新订阅的事件非常正常,与我们在SE / SO上使用的事件没有什么不同(除了我们通常跟踪更细粒度的订阅,并且有一些处理所有这些的包装代码)。

是的,在您的连接中断时发布的任何事件都已消失。这就是redis pub / sub的本质;它不保证交付给断开连接的客户端。要么使用承诺的工具,要么使用redis驱动队列 - 从列表的两端推送/弹出通常是一个合理的选择,并确保不会丢失任何东西(只要因为你的软件从列表中弹出后不会丢弃它)。如果它有帮助,我在我的列表上有一个添加阻塞pop方法的请求 - 它们完全破坏了多路复用器的意图,但它们在某些情况下真的有用,所以我不反对添加它们。