2011-05-05 53 views
1

现在我正在做一个聊天网络应用程序,多个用户可以聊天,它可以控制多个房间。它的工作和完成工作。如何为聊天应用创建“Keep Alive”?

现在它的使用AJAX(jQuery是使用),只是使用GET与不同的查询参数server.aspx,然后返回一些内容。(这意味着可用于构筑一个大项目后面)

但我有一件事,我无法弄清楚如何为它构建,而且有人有一个灿烂的想法:)

“Keep Alive”(或TimeToLive)服务的用户。该服务应确保用户断开连接时(机器故障 - 浏览器/窗口关闭)用户超时。

我的想法是,在从用户到服务器的每个请求中,它应该更新TTL列表(带有用户标识和“时间戳”的列表),这部分很容易。

现在到了我的挑战

那么就应该是continuesly检查该TTL列表,查看是否有邮票已用完服务器上运行的一些服务,如果它有从房间中删除用户

但是如何以及在哪里可以在.net中执行此服务器服务?或者你有另一个接近? :)

+0

为什么不整合平/乒乓球作为首位聊天服务器的一部分? – 2011-05-05 07:43:43

回答

1

您可以运行Console Application(或运行它作为Windows Service),它可以扫描您的TTL列表using a Timer,该列表按设定的时间间隔进行打点以按照您的意愿处理它们。所有这些都可以在.net中完成,这样可以避免将业务逻辑存储在SQL Server中的SSIS包中。

如果你要走这条路,我会建议你写一个windows服务,也可以作为一个控制台应用程序运行。查询Environment.UserInteractive属性以确定正在运行哪个版本 - 这将有助于您的开发,因为控制台应用程序可以比Windows服务稍微冗长些。

下面是一个代码示例:

public partial class Service1 : ServiceBase 
{ 
    //Need to keep a reference to this object, else the Garbage Collector will clean it up and prevent further events from firing. 
    private System.Threading.Timer _timer; 

    static void Main(string[] args) 
    { 
     if (Environment.UserInteractive) 
     { 
      var service = new Service1(); 
      Log.Debug("Starting Console Application"); 

      service.OnStart(args); 
      // The service can now be accessed. 
      Console.WriteLine("Service ready."); 
      Console.WriteLine("Press <ENTER> to terminate the application."); 
      Console.ReadLine(); 
      service.OnStop(); 

      return; 
     } 
     var servicesToRun = new ServiceBase[] 
              { 
               new Service1() 
              }; 
     Run(servicesToRun); 
    } 

    public Service1() 
    { 
     InitializeComponent(); 
    } 

    protected override void OnStart(string[] args) 
    { 
     // For a single instance, this is a bit heavy handed, but if you're creating of a number of them 
     // the NT service will need to return in a short period of time and thus I use QueueUserWorkItem 
     ThreadPool.QueueUserWorkItem(SetupTimer, args); 
    } 

    protected override void OnStop() 
    { 
    } 

    private void SetupTimer(object obj) 
    { 


     //Set the emailInterval to be 1 minute by default 
     const int interval = 1; 
     //Initialize the timer, wait 5 seconds before firing, and then fire every 15 minutes 
     _timer = new Timer(TimerDelegate, 5000, 1, 1000 * 60 * interval); 
    } 
    private static void TimerDelegate(object stateInfo) 
    { 
      //Perform your DB TTL Check here 
    } 

} 
+0

我认为这是一个好主意。我的想法是将TTL列表保存在数据库中,但这会为该列表产生大量流量,有没有办法可以在我的webapp和控制台应用程序之间共享列表对象?或者你会建议什么? – 2011-05-05 08:57:35

+0

sweet :)很多感谢@ Tr1stan我真的很喜欢这个例子(之前没有为一个'真正'的项目做过一个控制台应用程序),所以认为不适合沿着这条路径结合@Nathan关于保留数据库表的想法TTL和控制台应用程序将通过一个标志(通过一个http),如果有任何变化的Web应用程序,并告诉下一个用户更新共享列表对象如此生病保存一些数据库往返 – 2011-05-05 09:06:06

+0

@Rasmus Fjord:不客气。如果您想处理独立于网站应用程序池运行的内容,我发现这是一种很好的方法。在你的情况下,这可能有点矫枉过正(与我所知道的一样),因为如果站点不在,那么用户无法使用它。因此,您可以使用类似的方法,查询数据库或将TTL保留在内存中,但在Global.asax Application_OnStart事件中设置计时器调用 - 然后将所有内容都保存在Web应用程序本身中。 – Tr1stan 2011-05-05 09:13:27

2

我只是有一个名为“LastPing”的用户名和日期表。 放入一段JavaScript,定期在您的网站上调用一个页面(window.setInterval(...)) - 该页面只更新当前日期时间的表格,或者在没有行更新时执行插入操作。

最后,创建一个sql server作业/任务,用于从Lastping中选择用户标识,其中日期比currentdate更早--30分钟(或其他)。这些用户标识会从任何聊天室中删除,最后从LastPing表中删除。

我认为这是它:)

+0

ps - 也许在表中包含会话ID:如果用户从一台机器移动到另一台机器并在两台机器上都登录,则不希望在旧机器上死亡的会话将它们的新会话从聊天室! – Nathan 2011-05-05 07:47:22

+0

感谢你@Nathan认为不适合用你的组合和@ Tr1stan – 2011-05-05 09:07:07

0

对于该类型的解决方案,你将需要建立一个独立的Thread是定期检查用户到期,或利用图书馆的计划任务,同样设定一个预定任务。