0

私はAndroidアプリを開発しており、サーバーとカスタムJavaクライアントSignalASignalRで使用しています。次の問題に直面しています。クライアントがグループに参加すると、参加直後に送信されるメッセージを受信しません。サーバーからのコードは次のとおりです。asp.net

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

クライアント側では、新しいグループ トークンでコールバックを受け取りますが、最初に送信されたメッセージは受信されません (ただし、その後に送信されたメッセージは受信されます)。公式の C# クライアントで同じことを試すと、完全に機能します。そのため、新しいグループ トークンが処理される前に最初のメッセージが受信されたようです。

長い間、C# と Java クライアント コードを比較してみましたが、解決策が見つかりませんでした。この状況が C# クライアントでどのように処理されるかについての説明 (またはコード参照) を探しているので、Java クライアントで同じロジックを実装できます。

PSカスタムJavaクライアントを使用する代わりに、Androidで公式のC#クライアントを使用する方法があれば、はるかに簡単です。

PPSグループに参加した後、サーバーに少し遅延を加えたり、クライアントから確認メッセージを送信したりするなど、問題を修正する「汚い」方法がいくつかありますが、それでも「きれいな」修正を探しています.

4

1 に答える 1

5

を使用する理由はありませんTask.Factory.StartNew

context.Groups.Add(connectionId, groupName)は、 で識別されるクライアントを期待する にTaskメッセージを送信する前に、待機する必要がある をすでに返します。groupNameconnectionId

電話すると

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

を取得しTask<Task>ます。

これは、Groups.Send(groupName, message)の内部で呼び出すとContinueWith、外側の Task のみが完了し、connectionIdまだ に完全に追加されていないことを意味しますgroupdName

.NET 4.5 を実行している場合、このコードを書き直す最も簡単な方法は、次のように async/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();
}

注:私の例connectionIdでは、 は最初の引数でcontext.Groups.AddgroupNameは 2 番目の引数です。これは、これらのパラメーターの正しい順序であり、質問に書いた方法とは逆です。

以前のコードが C# クライアントでは機能するのに、Java では機能しない理由がわかりません。あなたの質問で提供されたコードを考えると、どちらのクライアントも最初に送信されたメッセージを見逃すと思います。

于 2013-03-11T12:35:00.603 に答える