0

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

反正

解决方案1:

有一个 JavaScript 循环,我在其中每隔一段时间向服务器发送一个请求,以检查数据库中可能发生的任何新消息。当我看到我的数据库有一个标志向她发出信号时,新的文本行调用另一个函数来检索和显示

解决方案2:

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

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

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

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

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

4

3 回答 3

2

这取决于,但我认为你应该选择解决方案 1。继续阅读以了解我为什么这么认为。

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

解决方案 2可能更难实现,也因为您必须在解决方案 1 之上实现它,因为竞争条件、超时(至少是客户端,但取决于您对服务器、服务器端的控制程度) . 好处是,如果做得正确,它可能比解决方案 1 更有效,也就是说,直到你达到端口限制(你可能无论如何都不会使用标准的单服务器 LAMP 设置)

关于解决方案 2,您还可以使用 websockets,它应该可以防止一些问题(超时,如果您做对了),并为您提供更好的性能,但代价是跨浏览器问题。

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

除了已经提到的之外,您还可以使用分块传输作为服务器发送事件的替代。需要做一些工作才能让它在不同的浏览器上运行,但它也适用于低延迟通信。除此之外,它在端口限制方面与 websocket 解决方案具有相同的缺点,因为服务器和客户端之间始终存在开放连接。

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


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

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

于 2013-10-13T14:46:37.303 回答
2

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

于 2013-10-13T14:47:36.230 回答
0

解决方案 2 更好,原因有两个:

  1. 它在服务器(和客户端)端使用更少的资源。
  2. 它反应更快。客户端将立即收到服务器上发生的事件的通知,而在解决方案一中,如果您每 30 秒轮询一次,则最多可以延迟 30 秒通知客户端。

您必须确定超时,之后服务器将始终回复。这可以确保您不会失去连接(或者如果客户端失去连接,它将在下一次超时时重新连接)。

示例服务器端代码:

$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);

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

于 2013-10-13T14:56:01.933 回答