选择用户与用户通信的方法

时间:2013-10-13 14:37:51

标签: javascript php web

让我们说我想创建一个聊天服务。在我看来,有两种做事方式,我想知道你们认为哪种方式更好。或者可能是第三种选择......我不知道。

反正

解决方案1:

有一个JavaScript循环,我以一定间隔向服务器发送请求,检查数据库是否有可能发生的新消息。当我看到我的数据库有一个标志,告诉她的新文本行调用另一个函数来检索和显示

解决方案2:

对服务器上的方法进行异步调用,该方法在服务器上等待新条目的循环中等待,然后在到达那里时将响应发送给客户端。

我不知道这些解决方案中的一个是更自然的,我想知道机器人是疯狂的告诉我什么解决方案是正确的方法来做到这一点。

这里的重点不是聊天服务,更多的是如何处理来自一个网页用户的显示输入以显示给观看相同内容的所有用户。

额外信息: 计划在客户端上使用html / css / js,在服务器上使用php + sql。

编辑:我不想开始讨论,基本上我只是想知道解决方案1是否有性能问题,那些是什么,并且由格里芬的回复判断问题从65k用户开始,当我刷新时每一秒,这对我的范围是可以接受的。

3 个答案:

答案 0 :(得分:2)

这取决于,但我认为你应该选择解决方案1.继续阅读,找出我的想法。

解决方案1 ​​应该更容易实现,如果您的服务器每秒可以处理超过65k的请求,您应该使用它,否则您将达到端口限制(假设您在负载上升之前,只使用一个网络设备。

解决方案2 可能更难实现,也因为您必须在解决方案1的顶部实施它,因为竞争条件,超时(至少客户端,但取决于您控制多少)你的服务器,服务器端也是如此)。好处是,如果正确完成,它可能比解决方案1更有效,也就是说,直到达到端口限制(使用标准单服务器LAMP设置可能无法做到)

关于解决方案2,您还可以使用websockets,它可以防止一些问题(超时,如果你做对了),并为交叉浏览器问题的成本提供更好的性能。

正如你所说,你将使用php和某种形式的sql(你可能意味着我假设的mysql),使用解决方案1.至于原因:只要你使用为编写模板而制作的脚本语言(查看php的历史,你不应该过多地考虑性能等,而是要完成任务,关于这一点,解决方案1绝对更容易实现而没有问题。只需确保使用正确的数据库索引并尽可能降低每个请求的开销(例如,不要启动完整的框架,但实际上只执行1(my-)sql查询)

除了已经提到的那些,您还可以使用chunked transfer作为Server Sent Events的替代。要使其在不同的浏览器上运行,还有一些工作要做,但它也适用于低延迟通信。除此之外,它作为websocket解决方案与端口限制具有相同的缺点,因为服务器和客户端之间始终存在开放连接。

另一种可能性是使用现成的聊天应用程序甚至聊天服务 - 那里有大量现成的解决方案,其中一些甚至使用自己的网络服务器来获得更好的性能/功能。对于现成的解决方案,您可以查看Node.JS和Socket.IO(服务器端javascript),作为服务聊天,它取决于您的具体情况。例如,实时聊天为客户提供聊天服务< - >支持会谈。


在考虑服务器上的睡眠/查询循环时,更多人建议解决方案2:

实施解决方案2的正确方法是使用线程间/进程通信(IPC),这将真正为您提供低延迟并节省资源。这些的一个例子是信号量,互斥量或条件变量(sem_ *和pthread_ *函数)。否则,您将获得与解决方案1相同的延迟和浪费资源,以及额外的交叉浏览器问题以及更多干净地实施它的工作。此外,在这种情况下,你可能应该停止使用某种基于sql的数据库和脚本语言,并转向具有更好性能的东西(C,C ++,Java - 现在甚至服务器端javascript优于php来完成这些任务,请参阅Socket。上面的IO链接)

答案 1 :(得分:2)

第一种解决方案是双方浪费资源。 看看websocketsServer-Sent events 它们都是新技术,但是为您提供浏览器和服务器之间的这种通信的最佳性能。 您的第二个解决方案有时会用于生产,因为并不要求用户只使用最新的浏览器。

答案 2 :(得分:0)

Soution 2更好有两个原因:

  1. 它在服务器(和客户端)端使用较少的资源。
  2. 反应灵敏。客户端将立即获知服务器上发生的事件,而在解决方案一中,如果您每隔30秒轮询一次,则可以通知最长30秒的客户端。
  3. 您必须确定超时,之后服务器将始终回复。这可以确保您不会断开连接(或者如果客户端失去连接,它将在下次超时时重新连接)。

    服务器端代码示例:

    $maxtime = 30; //sec
    $wait = 1000; //msec
    $startTime = microtime(true);
    $result = false;
    do {
        $result = query_datase_for_event(); // returns false if nothing happened
        if($result) break;
        usleep($wait * 1000);
    } while (microtime(true) + ($wait / 1000) - $startTime < $maxtime);
    echo json_encode($result);
    

    我从Realtime Ajax by Benjamin Hutchins派生了我的客户端代码。