Асинхронная операция завершена, но результат не отправлен в браузер - PullRequest
3 голосов
/ 01 июля 2011

Я хочу реализовать веб-чат.

Бэкэнд - это двойной канал WCF. Двухканальный работает в консоли или winforms, и это на самом деле работает в Интернете. Я могу хотя бы отправлять и получать сообщения.

В качестве базы я использовал это сообщение в блоге Итак, асинхронная операция завершена.

Когда я отлаживаю результат, я вижу, что все сообщения готовы для отправки в браузер.

[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 значение «Только чтение», в противном случае асинхронная операция заблокировала бы всю страницу.

EDIT: Вот CheckForMessagesAsync:

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: Между прочим, когда ничего не получено, поэтому время ожидания вступает в игру, ответ возвращается. так что, кажется, где-то падает. Любая идея, как войти это?

1 Ответ

1 голос
/ 04 июля 2011

Я изменил запрос jQUERY (см. Оригинальное сообщение в блоге) с POST на GET. Это исправляет.

...