Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/289.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何创建;“保持活力”;用于聊天应用程序?_C#_Asp.net_Webforms_Livechat - Fatal编程技术网

C# 如何创建;“保持活力”;用于聊天应用程序?

C# 如何创建;“保持活力”;用于聊天应用程序?,c#,asp.net,webforms,livechat,C#,Asp.net,Webforms,Livechat,目前,我正在做一个聊天网络应用程序,多个用户可以聊天,它可以控制多个房间。它的工作和完成工作 现在它使用的是ajax(使用jquery),只需使用不同的查询参数访问server.aspx,然后返回一些内容即可 但我有一件事我不知道该怎么做,希望有人能想出一个好主意:) 用户上的“保持活动”(或TimeToLive)服务。该服务应确保当用户断开连接(机器崩溃-浏览器/窗口关闭)时,用户从聊天室超时 我的想法是,在用户向服务器发出的每个请求中,它都应该更新一个TTL列表(一个带有用户ID和“时间戳”

目前,我正在做一个聊天网络应用程序,多个用户可以聊天,它可以控制多个房间。它的工作和完成工作

现在它使用的是ajax(使用jquery),只需使用不同的查询参数访问server.aspx,然后返回一些内容即可

但我有一件事我不知道该怎么做,希望有人能想出一个好主意:)

用户上的“保持活动”(或TimeToLive)服务。该服务应确保当用户断开连接(机器崩溃-浏览器/窗口关闭)时,用户从聊天室超时

我的想法是,在用户向服务器发出的每个请求中,它都应该更新一个TTL列表(一个带有用户ID和“时间戳”的列表),这一部分很简单

现在是我的挑战

然后,应该有一些服务在服务器上运行,该服务将继续检查此TTL列表,以查看是否有任何标记已用完,以及是否已将用户从文件室中删除


但是,在.net中如何以及在何处执行此服务器服务?或者你还有别的方法吗?:)

我只需要一个名为“LastPing”的表,其中包含用户id和日期。 在站点上放置一段javascript,定期调用页面(window.setInterval(…)——该页面仅使用当前日期时间更新表,如果没有更新行,则执行插入操作

最后,创建一个sql server作业/任务,从Lastping中选择用户id,其中日期早于currentdate-30分钟(或其他时间)。这些用户ID将从任何聊天室等中删除,并最终从LastPing表中删除


我想就是这样:)

对于这种类型的解决方案,您需要设置一个单独的
线程,定期检查用户是否过期,或者利用库执行计划任务,类似地设置计划任务。

您可以运行这可以扫描您的TTL列表,该列表在设置的时间间隔内滴答作响,以便按照您的意愿进行处理。所有这些都可以在.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
    }

}
公共部分类Service1:ServiceBase
{
//需要保留对此对象的引用,否则垃圾收集器将清理它并防止触发更多事件。
专用系统.Threading.Timer\u Timer;
静态void Main(字符串[]参数)
{
if(Environment.UserInteractive)
{
var service=newservice1();
调试(“启动控制台应用程序”);
服务启动(args);
//现在可以访问该服务。
控制台。WriteLine(“服务就绪”);
控制台。WriteLine(“按下以终止应用程序”);
Console.ReadLine();
service.OnStop();
返回;
}
var servicesToRun=new ServiceBase[]
{ 
新服务1()
};
运行(servicesToRun);
}
公共服务1()
{
初始化组件();
}
启动时受保护的覆盖无效(字符串[]args)
{
//对于一个单独的例子,这有点过于苛刻,但是如果你正在创建一系列的例子
//NT服务需要在短时间内返回,因此我使用QueueUserWorkItem
QueueUserWorkItem(SetupTimer,args);
}
受保护的覆盖void OnStop()
{
}
专用无效设置计时器(对象obj)
{
//默认情况下,将emailInterval设置为1分钟
const int interval=1;
//初始化计时器,在点火前等待5秒,然后每15分钟点火一次
_计时器=新计时器(TimerDelegate,5000,1000*60*间隔);
}
私有静态无效TimerDelegate(对象状态信息)
{
//在此处执行DB TTL检查
}
}

为什么不首先将乒乓球作为聊天服务器的一部分进行集成?ps-可能还需要在表中包含会话id:如果用户从一台机器移动到另一台机器并同时登录到这两台机器,您不希望旧机器上死掉的会话从聊天室中启动新会话!也谢谢你,内森·思克,我会和你的组合一起去,@Tr1stanI,我觉得这是个好主意。我的想法是将TTL列表保留在DB中,但这会为该列表生成大量流量,是否有某种方式可以在我的webapp和控制台应用程序之间共享列表对象?或者你有什么建议吗?甜心:)非常感谢@Tr1stan我真的很喜欢这个例子(以前没有为一个“真正的”项目做过控制台应用程序),所以我想我会走这条路,结合@Nathan关于将DB表保留为TTL的想法,控制台应用程序将升起一个标志(通过http)如果webapp有任何更改,并告诉下一个用户更新共享列表对象,那么我将保存一些数据库roundtrips@Rasmus峡湾:不客气。我发现这是一个很好的方法,如果你想处理独立于网站应用程序池运行的事情。在您的情况下,这可能有点过分(就我所知),因为如果站点没有运行,那么用户无论如何也不能使用它。因此,您可以使用类似的方法,查询DB或将TTL保留在内存中,但在Global.asax应用程序启动事件中设置计时器调用-然后所有内容都将保留在web应用程序本身中。