2013-03-11 47 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一起工作。鉴于您的问题中提供的代码,我希望任何客户端都会错过首次发送的消息。