2012-04-09 61 views
7

我正在使用Redis pubsub频道将消息从工作进程池发送到我的ASP.NET应用程序。当收到一条消息时,我的应用程序将该消息转发给客户端的浏览器与SignalR。使用Booksleeve维护开放的Redis PubSub订阅

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

我目前正在处理Redis的发布 - 订阅消息在我的Global.asax文件:

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重新订阅。但是,在连接重置期间发布到通道的任何消息都将丢失。

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

+0

我的解决方案确实会返回一个Redis连接,如果它已经打开,或者打开一个,否则。我相信,在“常规使用”中,连接将保持打开状态,并且不会将其放到PubSub模式中。在某些原因导致连接关闭的罕见情况下,您将得到一个新连接,并且yes - 连接正在重置时发布到通道的消息将会丢失。但是这个时间很短,并且不会定期发生。无论如何,让我们让BookSleeve的作者重点关注这个(CC @marcgravell)。 – 2012-04-10 01:43:11

+0

@OferZelig谢谢,但'@ someone'不能工作,除非我已经以某种方式参与了这篇文章; p – 2012-04-10 13:08:46

+0

@MarcGravell我不知道;无论如何:1)如何与其他SE用户沟通以获得他/她的关注?我的意思是 - 在一个SE网站内部,不是通过查看个人资料,并去他/她的博客或这样的; 2)您可以在SE中实现标识此功能和警报的功能( xxx模式,其中xxx是已知的SE用户名)。谢谢! – 2012-04-11 08:08:08

回答

7

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

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

+0

我不介意看到添加到API的阻塞弹出方法。现在我的web项目正在使用Booksleeve,但服务我的Web应用程序的工作人员依赖于ServiceStack.Redis来阻止弹出API。 – 2012-04-10 17:04:14

+1

@Justin它将被添加 - 希望本周 – 2012-04-10 17:32:58

+0

这将是太棒了!谢谢! – 2012-04-12 12:59:01