javascript聊天客户端的服务器轮询间隔

时间:2009-03-24 03:44:12

标签: javascript ajax

我正在为我的网站构建一个基本的小AJAX shoutbox / chat,但我不确定如何实现服务器轮询。

这是我想到的基本程序流程:

  1. 用户进入页面并显示最近10条消息
  2. 要获取其他人发送的消息,客户端javascript将请求带有timestamp参数的URL(设置为客户端收到的最后一条消息的值)
  3. 服务器返回自该时间戳以来的所有消息(最多10个)。
  4. 唯一的问题是轮询服务器的频率。显然,每次添加新邮件时都应该进行轮询,但是当您只是阅读其他邮件时,它需要自动更新。

    应该是设定的时间限制吗?例如:每10秒钟。或者,它会根据使用情况而有所不同吗?例如:5秒后检查。如果没有消息,请不要再检查10秒。如果仍然没有新消息,请检查15秒,然后是20,最多可能每30秒检查一次。每次检测到新消息时,请将计时器重置为5秒并重新开始。

    我只关心在服务器上施加不必要的压力,考虑到我们可以同时在线拥有数百名用户。

    ......或者我弄错了什么?有没有更好的方法来实现基本的JavaScript聊天?

7 个答案:

答案 0 :(得分:5)

您可能希望研究所谓的Comet编程技术,以便将信息流式传输给您的用户,而不是让客户端轮询服务器。这实际上是一系列技术,其中一些技术可能比其他技术更好,具体取决于具体情况,例如您使用的服务器类型以及您需要的客户端兼容性。

如果您的服务器一次可以处理大量打开的连接(例如,它不会使用每个连接的整个线程或进程,例如nginx或基于erlang的服务器,您可能希望使用长轮询技术,一旦收到一条消息,客户端就会立即请求另一条消息。如果没有可用的消息,服务器只是保持连接打开,可能偶尔发送虚拟数据作为保持连接,直到消息可用。

答案 1 :(得分:4)

Comet,由Brian描述是一种很好的技术,但需要服务器上的会话支持,这可能比你想要实现一个简单的聊天框更高级。

实现轮询间隔的最佳方法是假设您有一个聊天窗口,您可以将其最小化以执行其他操作,或者打开以查看是否有新消息。当您处于对话中时,您将经常切换到它(轮询)。如果您暂时没有收到任何消息,您将开始寻找稀有和罕见的消息,直到您偶尔检查它为止。

假设你不需要进行实时打字,你可以在达到峰值活动时每3秒左右轮询一次,如果5-10个民意调查没有显示任何内容,则开始调整间隔时间(可能加倍)它每次)直到它达到30-60秒。获取消息应该将轮询间隔重置为几秒,而发送消息应立即轮询,但可能不需要影响轮询的频率。

答案 2 :(得分:3)

老实说,如果你正在实施一个“基本的小AJAX shoutbox / chat ”,JabberComet之类的东西对你来说太过分了。这些东西需要你额外运行 服务器/代理来承担应用服务器和数据库的负载 当你想到像presence management这样的东西(“乔正在打字......”)时,你的应用程序就会变得过于复杂(考虑到“聊天”不是你的主要焦点)。
考虑从MeeboUserplane等提供商添加小部件。一旦你想到Jabber等等......

答案 3 :(得分:0)

您应该检查其他用户是否每隔5秒左右输入一次,如果其他用户正在键入,那么您可以每隔1秒检查一次,看看用户是否发送了新消息。实际上,您应该能够每1秒检查一次,看看其他用户是否正在打字,然后每隔0.25秒.5秒检查一下是否已发送新消息。随着宽带被普遍接受,不应该是一个问题。使用较长的轮询超时进行拨号访问。

答案 4 :(得分:0)

这是一个非常难的问题,请记住滥用。恶意用户会尽可能频繁地点击您,最早的时间戳伪造,从而对您的数据库服务器造成压力。一定要验证时间戳,或者忽略它,因为不管怎么说每个人都在同一时间?

您可以根据其他用户的响应时间将轮询间隔发送给用户。这是我认为最好的动态。

答案 5 :(得分:0)

http://jabbify.com/home/comet_service 这是一个由jmvc框架的人提供的基于免费彗星的聊天服务。尚未尝试过,但看起来很有希望。

答案 6 :(得分:0)

执行此操作的专业方法是使用WebSocket javascript连接。例如,您可以使用https://socketsbay.com/之类的免费服务,并使用

连接

    // Create WebSocket connection.
    const socket = new WebSocket('wss://socketsbay.com/wss/v2/[ChannelId]/[ApiKey]/');

    // Connection opened
    socket.addEventListener('open', function (event) {
        socket.send('Hello Server!');
    });

    // Listen for messages
    socket.addEventListener('message', function (event) {
        console.log('Message from server ', event.data);
    });

您可以忘记服务器池化时间,因为它是实时的。