2013-03-11 45 views
0

我正在開發Android應用程序,並在我的asp.net服務器上使用SignalR,並使用定製的Java客戶端SignalA。我遇到了以下問題:當客戶端加入某個組時,它不會收到加入後立即發送的消息。下面是來自服務器的一段代碼:SignalR:同步羣組加入

Task.Factory.StartNew(() => context.Groups.Add(groupId, connectionId)). 
    ContinueWith(t => Groups.Send(groupId, message)); 

在客戶端我收到的回調與令牌一個新的羣體,但沒有收到第一個發送的消息(之後發送的消息被接收。然而)。與官方C#客戶端一起嘗試相同的功能完美地工作。因此,在處理新的羣組令牌之前,似乎收到第一條消息。

經過長時間的嘗試比較C#和java客戶端代碼,我還沒有找到解決方案。我正在尋找一個關於如何在C#客戶端中處理這種情況的解釋(或代碼引用),以便我能夠在java客戶端中實現相同的邏輯。

P.S.如果有一種方法可以使用官方的C#客戶端而不是使用定製的Java客戶端,那麼這將更加輕鬆。

P.P.S.有一些「骯髒」的方式來解決我的問題,比如加入羣組後發送一小段延遲或從客戶端發送確認消息,但仍然在尋找一個「乾淨的」修復程序。

回答

5

沒有理由使用Task.Factory.StartNew

context.Groups.Add(connectionId, groupName)已經返回Task,你應該將消息發送到您希望通過connectionId標識的客戶端groupName前等待。

當你調用

Task.Factory.StartNew(() => context.Groups.Add(connectionId, groupName)) 

你得到一個Task<Task>

這意味着當你調用Groups.Send(groupName, message)ContinueWith內,只有外部任務已完成,並connectionId尚未完全加入groupdName

如果您運行的.NET 4.5,重寫這段代碼最簡單的方法是使用像這樣的異步/ AWAIT模式:

public async Task AddToGroupAndSend(IPersistentConnectionContext context, 
            string connectionId, 
            string groupName, 
            object message) 
{ 
    await context.Groups.Add(connectionId, groupName); 
    await context.Groups.Send(groupName, message); 
} 

如果您運行的.NET 4.0,你可以繼續使用ContinueWith,但沒有Task.Factory.StartNew

public Task AddToGroupAndSend(IPersistentConnectionContext context, 
           string connectionId, 
           string groupName, 
           object message) 
{ 
    // This doesn't appropriately handle faulted or canceled tasks 
    return context.Groups.Add(connectionId, groupName) 
        .ContinueWith(t => groups.Send(groupName, message)); 
} 

如果你不介意的代碼執行同步你甚至可以做到以下幾點:

public void AddToGroupAndSend(IPersistentConnectionContext context, 
           string connectionId, 
           string groupName, 
           object message) 
{ 
    context.Groups.Add(connectionId, groupName).Wait(). 
    groups.Send(groupName, message).Wait(); 
} 

NOTE:在我的示例中,connectionIdcontext.Groups.Add的第一個參數,groupName是第二個參數。這是這些參數的正確順序,與您在問題中編寫它的方式相反。

我不知道爲什麼你以前的代碼可以和C#客戶端一起工作,但不能和Java一起工作。鑑於您的問題中提供的代碼,我希望任何客戶端都會錯過首次發送的消息。