如何在Delphi中使用Indy管理连接?

3
我正在使用 Indy 10(阻塞模式)编写一个简单的客户端/服务器聊天程序,现在有一个问题:如何管理连接?
例如,假设一个用户在线上,我们必须为将来的请求建立连接隧道。换句话说,当用户在线时,服务器不需要用户名和密码来处理未来的用户请求,而是通过我们创建的隧道进行处理。
我们应该如何管理这些连接呢?
3个回答

3
对于问题描述的情景,其实没有太多需要进行的管理。为了避免在每个请求上重新进行身份验证,只需不要关闭连接即可。尤其是在聊天服务器中,每个参与者很可能会建立一个连接,并在聊天期间继续使用同一个连接。
Indy服务器对象已经保持着它们打开连接的列表,所以当你想向其他参与者广播聊天消息时,只需迭代该列表即可。

1
同意。如果您需要在请求之间保留自定义数据(例如身份验证详细信息),则可以在TIdPeerThread.Data(Indy 9及更早版本)和TIdContext.Data(Indy 10)属性中存储每个连接的信息。只要连接保持打开状态,该信息只需针对每个客户端收集和存储一次。如果客户端在请求之间断开并重新连接(例如在HTTP中),则必须手动跟踪您的信息,并将其应用于下一个连接。 - Remy Lebeau
谢谢!好答案。最后,您建议我用哪种方式以最少的处理来管理连接和会话ID?我认为我们必须将当前的Acontext-Index作为会话ID发送给客户端,在未来的请求中,当收到会话ID时,我们将从中提取Acontext(连接)索引并继续使用该隧道进行通信。这不是吗? - Kermia
不,Kermia。一旦连接关闭,上下文对象就会被销毁。由于您已经接受了这个答案,因此没有必要使用会话,本质上。相反,连接就是会话。客户端不需要从服务器那里得到任何信息,因为只要客户端保持打开的连接,它已经拥有了所需的一切。服务器也继续知道连接,因此在您的Indy事件处理程序中,无论事件发生在哪个连接上,都会自动为您提供正确的上下文对象。 - Rob Kennedy

1

我认为每秒100000次检查将比拥有10000个持久TCP连接消耗更少的资源。无论如何,您都需要以某种方式处理这100000个命令,因此这些检查不会成为瓶颈。

尝试改用UDP消息。例如,大多数MMO游戏同时使用TCP和UDP连接。TCP仅用于关键数据,而UDP用于任何其他数据。在您的情况下,UDP似乎是可以接受的。客户端可以发送带有一些自动增量ID的UDP数据包,服务器可以定期发送回它没有收到的ID列表,以便客户端可以重新发送它们。


0

一种选择是在服务器端创建一个唯一的会话ID(或“令牌”),例如GUID,如果客户端登录。并且在每个请求中,客户端都包括此令牌。

服务器将维护客户端会话和相关会话数据的列表,并在此列表中查找令牌。

即使客户端暂时断开与互联网的连接但仍知道其令牌,应用程序也可以重新连接并继续与服务器的会话。


谢谢您的回复,但请想象一下,如果有10,000个在线用户,每个用户每秒钟向服务器发送10条消息。那么最终我们将在一秒钟内进行100,000个会话ID检查。这对服务器来说会非常致命!! - Kermia
当我读到“一个简单的聊天程序”时,我并没有想到有10,000个用户每100毫秒都发送一条消息 :) - mjn
哦,你说得对 :D。但如果我们想用这种方法来完成更大的项目呢?这是否可能?或者你有其他建议?谢谢mjustin :)。 - Kermia
不好意思,不支持Delphi。也许可以考虑使用APE(免费的Ajax Push Engine,Sourceforge项目名为Ajax Chat Engine),它可以处理超过100,000个用户:http://www.ape-project.org/wiki/index.php/FAQ - 服务器是用C编写的。 - mjn

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接