2012-04-09 92 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