2011-06-20 42 views
5

Tôi đang cố gắng đầu tiên để thử nghiệm với Comet. Tôi đã phát triển một ứng dụng web trò chuyện rất đơn giản - về cơ bản là một thế giới xin chào của sao chổi qua C#. Các vấn đề tôi đang gặp là IIS đôi khi sẽ sụp đổ và do tai nạn tôi có nghĩa là nó chỉ đơn giản là dừng đáp ứng yêu cầu HTTP. Sau đó, nó mất bao giờ để khởi động lại nhóm ứng dụng và đôi khi toàn bộ dịch vụ IIS. Tôi gần như tích cực thủ phạm là đối tượng ManualResetEvent tôi đang sử dụng để chặn các yêu cầu sao chổi cho đến khi một tín hiệu để phát hành (cập nhật) những chủ đề được nhận. Tôi đã thử viết một trình xử lý HTTP để thực hiện việc này và đặt thuộc tính có thể sử dụng lại thành false (để đặt các luồng yêu cầu mới trên một cá thể khác của đối tượng ManualResetEvent) nhưng điều đó không hoạt động. Tôi cũng đang cố gắng triển khai IRegisteredObject để tôi có thể phát hành các lệnh đó khi ứng dụng đang tắt nhưng điều đó dường như không hoạt động. Nó vẫn còn treo và dường như không có bất kỳ mô hình nào khi nó bị treo (mà tôi đã nhận thấy). Tôi gần như chắc chắn đó là một sự kết hợp của các trường hợp tĩnh và việc sử dụng ManualResetEvent gây ra nó. Tôi chỉ không biết chắc chắn làm thế nào hoặc làm thế nào để sửa chữa nó cho rằng vấn đề.C# máy chủ comet đóng băng IIS

Comet.cs (lib sao chổi đơn giản của tôi)

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading; 
using System.Net.Mail; 
using System.Web.Hosting; 

namespace Comet 
{ 
    public class CometCore : IRegisteredObject 
    { 
     #region Globals 
     private static CometCore m_instance = null; 
     private List<CometRequest> m_requests = new List<CometRequest>(); 
     private int m_timeout = 120000; //Default - 20 minutes; 
     #endregion 

     #region Constructor(s) 
     public CometCore() 
     { 
      HostingEnvironment.RegisterObject(this); 
     } 
     #endregion 

     #region Properties 
     /// <summary> 
     /// Singleton instance of the class 
     /// </summary> 
     public static CometCore Instance 
     { 
      get 
      { 
       if (m_instance == null) 
        m_instance = new CometCore(); 
       return m_instance; 
      } 
     } 

     /// <summary> 
     /// In milliseconds or -1 for no timeout. 
     /// </summary> 
     public int Timeout { get { return m_timeout; } set { m_timeout = value; } } 
     #endregion 

     #region Public Methods 
     /// <summary> 
     /// Pauses the thread until an update command with the same id is sent. 
     /// </summary> 
     /// <param name="id"></param> 
     public void WaitForUpdates(string id) 
     { 
      //Add this request (and thread) to the list and then make it wait. 
      CometRequest request; 
      m_requests.Add(request = new CometRequest(id)); 

      if (m_timeout > -1) 
       request.MRE.WaitOne(m_timeout); 
      else 
       request.MRE.WaitOne(); 
     } 

     /// <summary> 
     /// Un-pauses the threads with this id. 
     /// </summary> 
     /// <param name="id"></param> 
     public void SendUpdate(string id) 
     { 
      for (int i = 0; i < m_requests.Count; i++) 
      { 
       if (m_requests[i].ID.Equals(id)) 
       { 
        m_requests[i].MRE.Set(); 
        m_requests.RemoveAt(i); 
        i--; 
       } 
      } 
     } 
     #endregion 

     public void Stop(bool immediate) 
     { 
      //release all threads 
      for (int i = 0; i < m_requests.Count; i++) 
      { 
       m_requests[i].MRE.Set(); 
       m_requests.RemoveAt(i); 
       i--; 
      } 
     } 
    } 

    public class CometRequest 
    { 
     public string ID = null; 
     public ManualResetEvent MRE = new ManualResetEvent(false); 
     public CometRequest(string pID) { ID = pID; } 
    } 
} 

My lớp chat và dịch vụ web

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web; 
using System.Web.Services; 
using Comet; 

namespace CometTest 
{ 
    /// <summary> 
    /// Summary description for Chat 
    /// </summary> 
    [WebService(Namespace = "http://tempuri.org/")] 
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] 
    [System.ComponentModel.ToolboxItem(false)] 
    // To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line. 
    [System.Web.Script.Services.ScriptService] 
    public class Chat : System.Web.Services.WebService 
    { 

     [WebMethod] 
     public string ReceiveChat() 
     { 
      return ChatData.Instance.GetLines(); 
     } 

     [WebMethod] 
     public string ReceiveChat_Comet() 
     { 
      CometCore.Instance.WaitForUpdates("chat"); 
      return ChatData.Instance.GetLines(); 
     } 

     [WebMethod] 
     public void Send(string line) 
     { 
      ChatData.Instance.Add(line); 
      CometCore.Instance.SendUpdate("chat"); 
     } 
    } 

    public class ChatData 
    { 
     private static ChatData m_instance = null; 
     private List<string> m_chatLines = new List<string>(); 
     private const int m_maxLines = 5; 

     public static ChatData Instance 
     { 
      get 
      { 
       if (m_instance == null) 
        m_instance = new ChatData(); 
       return m_instance; 
      } 
     } 

     public string GetLines() 
     { 
      string ret = string.Empty; 
      for (int i = 0; i < m_chatLines.Count; i++) 
      { 
       ret += m_chatLines[i] + "<br>"; 
      } 
      return ret; 
     } 

     public void Add(string line) 
     { 
      m_chatLines.Insert(0, line); 
      if (m_chatLines.Count > m_maxLines) 
      { 
       m_chatLines.RemoveAt(m_chatLines.Count - 1); 
      } 
     } 
    } 
} 

Các thử nghiệm aspx tập tin

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="CometTest.Default" %> 

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 

<html xmlns="http://www.w3.org/1999/xhtml"> 
<head runat="server"> 
    <title></title> 
</head> 
<body> 
    <form id="form1" runat="server"> 

     <asp:ScriptManager ID="ScriptManager1" runat="server"> 
      <Services> 
       <asp:ServiceReference Path="~/Chat.asmx" /> 
      </Services> 
     </asp:ScriptManager> 

     <div id="lyrChatLines" style="height: 200px; width: 300px; border: 1px solid #cccccc; overflow: scroll"> 
     </div> 

     <asp:Panel runat="server" DefaultButton="cmdSend"> 
      <asp:UpdatePanel runat="server"> 
       <ContentTemplate> 
        <asp:TextBox style="width: 220px" runat="server" ID="txtChat"></asp:TextBox> 
        <asp:Button runat="server" ID="cmdSend" Text="Send" OnClick="cmdSend_Click" /> 
       </ContentTemplate> 
      </asp:UpdatePanel> 
     </asp:Panel> 

     <script type="text/javascript"> 

      function CometReceive() 
      { 
       CometTest.Chat.ReceiveChat_Comet(receive, commError, commError); 
      } 

      function ReceiveNow() 
      { 
       CometTest.Chat.ReceiveChat(receive, commError, commError); 
      } 

      function receive(str) 
      { 
       document.getElementById("lyrChatLines").innerHTML = str; 
       setTimeout("CometReceive()", 0); 
      } 

      function commError() 
      { 
       document.getElementById("lyrChatLines").innerHTML = 
        "Communication Error..."; 
       setTimeout("CometReceive()", 5000); 
      } 

      setTimeout("ReceiveNow()", 0); 
     </script> 
    </form> 
</body> 
</html> 

Và mã aspx đằng sau

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web; 
using System.Web.UI; 
using System.Web.UI.WebControls; 

namespace CometTest 
{ 
    public partial class Default : System.Web.UI.Page 
    { 
     protected void Page_Load(object sender, EventArgs e) 
     { 

     } 

     protected void cmdSend_Click(object sender, EventArgs e) 
     { 
      Chat service = new Chat(); 
      service.Send 
      (
       Request.UserHostAddress + "> " + 
       txtChat.Text 
      ); 
      txtChat.Text = string.Empty; 
      txtChat.Focus(); 
     } 
    } 
} 

Nếu ai có một lý thuyết tốt vào nguyên nhân và/hoặc chỉnh sửa trước khi tai nạn dường như độc đoán nó sẽ được nhiều đánh giá cao nếu you'ld bài :)

Trả lời

1

này câu hỏi .NET Comet engine có một số liên kết mà nên chỉ cho bạn đúng hướng. Bạn cần xem xét việc triển khai IHttpAsyncHandler để xử lý yêu cầu sao chổi chạy dài.

+0

Cảm ơn! Tôi sẽ thử ngay khi có thể. Tôi có một handler http tôi đã viết để có được xung quanh vấn đề này nhưng tôi thực hiện IHttpHandler (không phải là asnyc) vì vậy tôi sẽ definatley cho rằng một thử. Bạn có nghĩ rằng nó có thể làm điều này mà không cần tạo một trình xử lý HTTP không? Tôi hỏi bởi vì nó sẽ là tốt đẹp để phát triển một lib đơn giản mà có thể dễ dàng được sử dụng trong một servie web như tôi đã ở trên. –

+1

Tôi đã không sử dụng dịch vụ web nên tôi không thể nói. Tuy nhiên tôi đã phát triển một máy chủ sao chổi bằng cách sử dụng IHttpAsyncHandler và nó hoạt động rất tốt. IIS/http.sys sử dụng một số lượng cố định các luồng để xử lý các yêu cầu gửi đến, nếu bạn buộc chúng với hoạt động hoặc chặn dài (.WaitOne) gọi bạn sẽ nhanh chóng tiêu diệt iis. –

+0

Liên kết http://msdn.microsoft.com/en-us/library/aa480516.aspx này có được trợ giúp từ msdn không? Nó nói về Async WebMthods. –

Các vấn đề liên quan