简体   繁体   English

Delphi TIdTCPServer处理多个请求

[英]Delphi TIdTCPServer processing multiple requests

I'm developing a messaging system in delphi using TidTCPServer and TidTCPClient. 我正在使用TidTCPServer和TidTCPClient在delphi中开发一个消息传递系统。

First all clients log in with a username and a password. 首先,所有客户端都使用用户名和密码登录。 The server searches for the user data in SQL server using ADO components. 服务器使用ADO组件在SQL Server中搜索用户数据。 After that the clients send multiple requests to the server every 10 seconds to tell the server that they're online and get the status of their contact list. 之后,客户端每10秒钟向服务器发送多个请求,以告知服务器它们处于联机状态并获取其联系人列表的状态。 All these requests end up with reading or modifying SQL tables. 所有这些请求最终都会读取或修改SQL表。

Sometimes I get this error: Operation cannot be performed while executing asynchronously . 有时我会收到此错误: Operation cannot be performed while executing asynchronously It's raised by ADO. 它是由ADO提出的。 I think that the TCP server is working asynchronously and multiple access to ADODataset at the same time is the problem. 我认为TCP服务器正在异步工作,并且同时访问ADODataset是个问题。 What should I do? 我该怎么办? Should I put the incoming requests into a list and process them one by one until the list is clear? 我是否应该将传入的请求放入列表中并逐个处理,直到列表清晰为止?

TIdTCPServer is a multi-threaded component. TIdTCPServer是一个多线程组件。 Each client runs in its own worker thread. 每个客户端都在其自己的工作线程中运行。

ADO is a set of apartment-threaded COM objects. ADO是一组单元线程的COM对象。 You cannot share them across thread boundaries unless you marshal them. 除非封送它们,否则您不能跨线程边界共享它们。

You will have to either: 您将必须:

  1. give each thread its own database connection and query components. 给每个线程自己的数据库连接和查询组件。 Optionally put the objects in a pool to control the number of active connections/queries that run at a time. (可选)将对象放入池中,以控制一次运行的活动连接/查询的数量。 The pool can handle the necessary marshalling when taking a connection out of the pool. 从池中断开连接时,池可以处理必要的编组。

  2. Delegate the queries to a dedicated thread that runs the queries and sends the results back to the appropriate thread. 将查询委托给运行查询的专用线程,然后将结果发送回适当的线程。

  3. Switch to another database framework that better supports threaded access, like dbExpress. 切换到另一个更好地支持线程访问的数据库框架,例如dbExpress。

Personally, I use a pooled version of #3. 我个人使用#3的合并版本。 When a client needs to execute a query, it grabs a TSQLConnection from the pool (connecting it to the database if needed), creates a TSQLQuery object, executes the query, reads the result, and then puts the TSQLConnection back into the pool. 当客户端需要执行查询时,它将从池中获取一个TSQLConnection (如果需要,将其连接到数据库),创建一个TSQLQuery对象,执行查询,读取结果,然后将TSQLConnection放回池中。 The pool has a dedicated thread that monitors which connections are in use, and closes connections that are idle for a period of time. 池具有专用线程,该线程监视正在使用的连接,并关闭一段时间内处于空闲状态的连接。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM