Webchatを実装したいと思います。非同期操作は完了しましたが、結果はブラウザに送信されません
バックエンドはデュアルWCFチャネルです。デュアルチャンネルは、コンソールまたはwinforms、 で動作し、実際にはWeb上で動作します。私は少なくともメッセージを送受信できます。
ベースとして私はthis blog post だから、非同期操作は完了です。
結果をデバッグすると、メッセージがすべてブラウザに送信できる状態になっていることがわかります。
[AsyncTimeout(ChatServer.MaxWaitSeconds * 1020)] // timeout is a bit longer than the internal wait
public void IndexAsync()
{
ChatSession chatSession = this.GetChatSession();
if (chatSession != null)
{
this.AsyncManager.OutstandingOperations.Increment();
try
{
chatSession.CheckForMessagesAsync(msgs =>
{
this.AsyncManager.Parameters["response"] = new ChatResponse { Messages = msgs };
this.AsyncManager.OutstandingOperations.Decrement();
});
}
catch (Exception ex)
{
Logger.ErrorException("Failed to check for messages.", ex);
}
}
}
public ActionResult IndexCompleted(ChatResponse response)
{
try
{
if (response != null)
{
Logger.Debug("Async request completed. Number of messages: {0}", response.Messages.Count);
}
JsonResult retval = this.Json(response);
Logger.Debug("Rendered response: {0}", retval.);
return retval;
}
catch (Exception ex)
{
Logger.ErrorException("Failed rendering the response.", ex);
return this.Json(null);
}
}
実際には何も送信されません。
Fiddlerを確認すると、リクエストが表示されますが、返信はありません。
[SessionState(SessionStateBehavior.ReadOnly)]
public class ChatController : AsyncController
また、SessionStateBehaviourをReadonlyに設定する必要がありました。そうしないと、非同期操作がページ全体をブロックします。 EDIT
:ここ はCheckForMessagesAsyncです: ところで、何も受信されないとき、待ちタイムアウトはそう:同じ考えをそれ `s
public void CheckForMessagesAsync(Action<List<ChatMessage>> onMessages)
{
if (onMessages == null)
throw new ArgumentNullException("onMessages");
Task task = Task.Factory.StartNew(state =>
{
List<ChatMessage> msgs = new List<ChatMessage>();
ManualResetEventSlim wait = new ManualResetEventSlim(false);
Action<List<ChatMessage>> callback = state as Action<List<ChatMessage>>;
if (callback != null)
{
IDisposable subscriber = m_messages.Subscribe(chatMessage =>
{
msgs.Add(chatMessage);
wait.Set();
});
bool success;
using (subscriber)
{
// Wait for the max seconds for a new msg
success = wait.Wait(TimeSpan.FromSeconds(ChatServer.MaxWaitSeconds));
}
if (success) this.SafeCallOnMessages(callback, msgs);
else this.SafeCallOnMessages(callback, null);
}
}, onMessages);
}
private void SafeCallOnMessages(Action<List<ChatMessage>> onMessages, List<ChatMessage> messages)
{
if (onMessages != null)
{
if (messages == null)
messages = new List<ChatMessage>();
try
{
onMessages(messages);
}
catch (Exception ex)
{
this.Logger.ErrorException("Failed to call OnMessages callback.", ex);
}
}
}
参照さのブログ記事で
EDIT2としてプレイが始まり、応答が返されます。それはどこかでクラッシュするようです。どのようにこれを記録するには?
ブレークポイントを設定し、 'this.AsyncManager.OutstandingOperations.Decrement();'を呼び出すコードに到達していることを確認しましたか? –
関連するコードを 'CheckForMessagesAsync'に投稿し、コールバックにロギングを追加してください。 –
実際に問題には関係しませんが、 'IndexAsync'のcatch節では、非同期操作カウンタを減らす必要があります。実際にコールバックをキューに入れないと、コールバックされません。あるいは、 'CheckForMessagesAsync'から正常に返った後にインクリメントするだけでよいのです。 –