Indy 10 TCP 服务器

2023-11-27

经过大量搜索后,我认为 Indy TCP 服务器最适合在我正在开发的即时通讯服务器上使用。我现在面临的唯一问题是向其他连接的客户端广播和转发消息,向同一客户端发回响应似乎没问题,并且不会挂起其他客户端活动,但对于将消息转发到其他客户端,我知道的机制是通过使用aContext.locklist,并在连接列表之间迭代以查找要接收数据的客户端连接。

我认为这里的问题是它冻结列表并且在调用解锁列表之前不处理其他客户端请求。那么这样不会损害服务器的性能吗?锁定列表并在连接之间迭代以转发每条消息(因为这是在信使中经常发生的情况)。有没有更好的方法来做到这一点?

我正在使用 Indy 10 和 Delphi 7

广播代码:

Var tmpList: TList;
    i: Integer;
Begin
tmpList := IdServer.Contexts.LockList;

For i := 0 to tmpList.Count Do Begin
  TIdContext(tmpList[i]).Connection.Socket.WriteLn('Broadcast message');
End;
IdServer.Contexts.UnlockList;

转发消息代码:

Var tmpList: TList;
  i: Integer;
Begin
  tmpList := IdServer.Contexts.LockList;

  For i := 0 to tmpList.Count Do Begin
    If TIdContext(tmpList[i]).Connection.Socket.Tag = idReceiver Then
      TIdContext(tmpList[i]).Connection.Socket.WriteLn('Message');
  End;
  IdServer.Contexts.UnlockList;

是的,你必须循环遍历Contexts列表以便向多个客户端广播消息。但是,您不会(也不应该)从循环内部执行实际写入。第一,正如您已经注意到的,将列表锁定一段时间可能会影响服务器性能。第二,它不是线程安全的。如果您的循环将数据写入一个连接,而另一个线程同时写入同一连接,则这两个写入将相互重叠并破坏您与该客户端的通信。

我通常做的是实现每个客户端出站队列,使用 TIdContext.Data 属性或 TIdServerContext 后代来保存实际队列。当您需要从客户端之外向客户端发送数据时OnExecute事件,将数据放入该客户端的队列中。那个客户的OnExecute然后,事件可以在安全的情况下将队列的内容发送到客户端。

例如:

type
  TMyContext = class(TIdServerContext)
  public
    Tag: Integer;
    Queue: TIdThreadSafeStringList;
    ...
    constructor Create(AConnection: TIdTCPConnection; AYarn: TIdYarn; AList: TThreadList = nil); override;
    destructor Destroy; override;
  end;

constructor TMyContext.Create(AConnection: TIdTCPConnection; AYarn: TIdYarn; AList: TThreadList = nil);
begin
  inherited;
  Queue := TIdThreadSafeStringList.Create;
end;

destructor TMyContext.Destroy;
begin
  Queue.Free;
  inherited;
end;

.

procedure TForm1.FormCreate(Sender: TObject);
begin
  IdServer.ContextClass := TMyContext;
end;

procedure TForm1.IdServerConnect(AContext: TIdContext);
begin
  TMyContext(AContext).Queue.Clear;
  TMyContext(AContext).Tag := ...
end;

procedure TForm1.IdServerDisconnect(AContext: TIdContext);
begin
  TMyContext(AContext).Queue.Clear;
end;

procedure TForm1.IdServerExecute(AContext: TIdContext);
var
  Queue: TStringList;
  tmpList: TStringList;
begin
  ...
  tmpList := nil;
  try
    Queue := TMyContext(AContext).Queue.Lock;
    try
      if Queue.Count > 0 then
      begin
        tmpList := TStringList.Create;
        tmpList.Assign(Queue);
        Queue.Clear;
      end;
    finally
      TMyContext(AContext).Queue.Unlock;
    end;
    if tmpList <> nil then
      AContext.Connection.IOHandler.Write(tmpList);
  finally
    tmpList.Free;
  end;
  ...
end;

.

var
  tmpList: TList;
  i: Integer;
begin
  tmpList := IdServer.Contexts.LockList;
  try
    for i := 0 to tmpList.Count-1 do
      TMyContext(tmpList[i]).Queue.Add('Broadcast message');
  finally
    IdServer.Contexts.UnlockList;
  end;
end;

.

var
  tmpList: TList;
  i: Integer;
begin
  tmpList := IdServer.Contexts.LockList;
  try
    for i := 0 to tmpList.Count-1 do
    begin
      if TMyContext(tmpList[i]).Tag = idReceiver then
        TMyContext(tmpList[i]).Queue.Add('Message');
    end;
  finally
    IdServer.Contexts.UnlockList;
  end;
end;
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Indy 10 TCP 服务器 的相关文章

  • Delphi错误数据集未处于插入或编辑模式

    客观的 单击 TRxDBCombo 上的按钮调用搜索框 从搜索框中选择记录时 结果将设置为 TComboEditBox 的字段值 并发布在 TRxMemoryData 数据集中 错误 第二次调用此函数时出现数据集未处于插入或编辑模式 TDB
  • 如何更改 Delphi 2010 IDE 中编辑器选项卡的字体大小?

    有谁知道如何更改 Delphi 2010 IDE 中编辑器选项卡的字体大小 我的 1080p 22 显示器的字体太小 无法阅读 而且会导致眼睛疼痛 一些笔记 它不尊重系统的 DPI 设置 因此更改系统设置没有帮助 而且 我现在已经使用 14
  • 如何更改 Chromium 组件的默认背景颜色?

    I use TChromium http code google com p delphichromiumembedded 我分配AWebPageAsString这是一个带有灰色背景颜色的静态 HTML 页面 FBrowser TChrom
  • 如何添加资源并使用它们

    在我的应用程序中 我想添加 2 个图像作为资源 我想使用这些图像 当我在应用程序中单击 是 按钮时 第一张图像将被设置为壁纸 当我在应用程序中单击 否 按钮时 第二张图像将被设置为桌面壁纸 提前致谢 regards 最简单的方法是创建一个文
  • 使用 NestJS 的 TCP 服务器

    是否可以使用 NestJS 创建 TCP 服务器 我有一个仅通过 TCP 进行通信的 GPS 跟踪器 由于 NestJS 可以通过 TCP 在微服务之间进行通信 我认为也许 NestJS 可以用作低级网络应用程序 例如 java netty
  • 如何在 Vista 上安装 Delphi 7

    我多次尝试在 Vista 上安装 Delphi 7 但 Vista 告诉我此应用程序 Delphi 7 存在已知问题 从而阻止了我这样做 我公司的其他几个人在 Vista 上安装 D7 时遇到了问题 由此得出的结论是 我们的 D7 应用程序
  • 如何在滚动框上创建缓慢的滚动效果?

    我喜欢在滚动框中平移图像后创建平滑的减慢滚动效果 就像平移地图一样谷歌地图 http maps google com 我不确定它是什么类型 但行为完全相同 当快速移动地图时 当您释放鼠标时它不会立即停止 而是开始减慢速度 有什么想法 组件
  • Delphi - 自XE8以来如何正确注册图形类?

    我正在编写一个 Delphi 包 它提供了一个新的自定义 TGraphic 对象 允许读取 VCL 组件 如 TImage 中的新图像格式 我最初使用 RAD Studio XE7 开发了这个包 并且运行良好 然而 我最近迁移到了较新的 R
  • 开源 Delphi 包可使用哪些项目选项?

    我写了一些 Delphi 代码 想在 GitHub 上分享 所有代码都根据需要包含在运行时和设计时包中 每个项目有许多项目选项需要设置 输出目录 搜索路径 编译选项等 我设法找到了一些适合我的情况的默认选项 但阅读此处的其他问答很明显有多个
  • 如何根据输入的内容过滤组合框的内容?

    我们有一个包含 100 多个项目的组合框 当我们在组合框中输入字符时 我们想要过滤掉项目 例如 如果我们输入 ac 并单击下拉选项 那么我们希望它仅显示以 ac 开头的项目 我怎样才能做到这一点 也许您会更喜欢使用操作系统内置的自动完成功能
  • 如何将 REST API 与 FireMonkey 结合使用?

    我需要在 FireMonkey 中实现 REST API 来获取一些信息 但我不确定如何做到这一点 REST API使用OAuth2 我可以访问两个代码 Consumer Key和Consumer Secret 之后 我需要获得一个临时的
  • 处理 TShellListView 后代中的文件放置

    我正在尝试创建 TShellListView 的后代 它接受从 Windows 资源管理器中删除的文件 我想在组件定义中处理拖 放操作 而不必在任何使用该组件的应用程序中实现它 我找到了接受从 Windows 资源管理器中拖放的文件的示例
  • 石和磅的格式正确吗?

    我有一个图表 用于显示重量 以英石和磅 lbs 为单位 该图表由记录中的数据填充 对于权重 数据类型为 Double 记录数据是在运行时编辑的 我需要知道一种正确格式化输入数据的方法 为了更好地理解 首先看一下这些示例值 它们表示为石和磅
  • delphi中如何实现多重继承?

    我正在对一个旧库进行完全重写 我不确定如何处理这种情况 为了便于理解 大家都欢呼自行车类比 我有以下课程 TBike 自行车本身 TBikeWheel 自行车的一个轮子 TBikeWheelFront and TBikeWheelBack
  • 将数据从一个数据集结构移动到另一个数据集结构的更快方法(在 TDatasetProvider 中)

    我有一个自定义的 TDatasetProvider 它允许为其提供的任何数据创建新字段 因此 假设您在原始数据集上获得了以下字段 客户ID Name Age 您需要使用显示位图在 DBGrid 上选择它 好吧 你可以 因为我的 DSP 可以
  • TObjectList.Contains 导致 Delphi 2009 中的访问冲突

    在 Delphi 2009 中 到目前为止 我在泛型方面没有遇到大问题 使用 Generics Collections 列表 没有特殊的泛型功能 现在我发现这段代码会在访问的行中导致AVMyList Contains 如果我声明 TMyLi
  • Delphi IDE导致CPU过热

    我正在使用 Delphi 7 但我已经尝试过 Delphi 2005 2010 版本 在所有这些新版本中 当 Delphi IDE 在屏幕上可见时 我的 CPU 利用率为 50 一个核心为 100 另一个核心为 宽松 当 IDE 最小化时
  • 如何在运行时(Delphi/Windows)程序中添加代码?

    我正在Windows XP Delphi 7上工作 我需要在正在运行的程序中添加一些过程 或函数 并且我不想在完成后再次重新编译它 我只有一个具有 5 个功能的主机应用程序来发送不同类型的警报 但是还有其他新的警报类型 所以我必须执行新的功
  • Delphi 5 中的 Oracle 数据库连接

    我正在使用 Delphi 5 版本 我想连接到 Oracle 数据库 我有 TDatabase 组件 我不知道如何通过 Delphi 连接到数据库 请提供连接数据库的步骤 谢谢 The TDatabase http docwiki emba
  • 如何调试仅在应用程序关闭时发生的崩溃? (德尔福)

    因此 经过最近的一些更改 我们发现我们最古老的应用程序之一有时会在关闭时崩溃 这会以 运行时错误 216 消息的形式或来自 Windows 错误报告的消息的形式表明应用程序已停止工作 该应用程序已经发出OutputDebugString 每

随机推荐

  • jQuery Mobile 固定页脚在键盘出现时移动

    我使用 Phonegap 和 jQuery Mobile 设计了一个应用程序 固定页脚可以正常工作 直到我单击下拉列表或文本字段 这会导致页脚从视图中消失 Android 4 0 或移动到视图中间 Android 2 2 Galaxy Ta
  • npm 将所有模块安装在 /usr/local/lib/node_modules/ 中

    我在 Ubuntu 12 10 上安装了 node js 0 8 14 我在主目录中创建了一个带有子目录的目录node modules 我想在那里安装一些本地节点模块但正在运行 npm install myModule 在此目录中安装此模块
  • 在 PHP 中如何检查类是否存在?

    所以我在主类中有这种结构函数 function construct this gt conf GLOBALS conf this gt dbi new dbinfo this gt modOpt new modOptions this gt
  • HTTP_HOST 的可靠性如何?

    我编写了一个 PHP 脚本 我想在同一服务器上的多个域上使用该脚本 指向相同的脚本 我想向脚本添加功能 以便我可以随时找出脚本正在使用的域 HTTP HOST 可用于查找域 但是 我读到它不可靠 尤其是对于较旧的浏览器 我的理解是大多数 A
  • 检查应用程序是否在测试环境中运行

    只是想知道我是否可以确定我的应用程序当前是否在测试环境中运行 原因是我正在运行自动屏幕截图 并且只想在运行该 UI 测试时隐藏 修改我的应用程序的部分内容 例如 我想跳过注册推送通知以避免在启动时出现 iOS 弹出窗口 我正在寻找类似的东西
  • java中引用变量的大小是多少[重复]

    这个问题在这里已经有答案了 java中引用变量的大小是多少 我很确定它不会依赖于架构 是吗 它与 C 中的指针概念有相似之处吗 我尝试过 但无法得到任何令人信服的答案 引用使用的内存量取决于几个参数 在 32 位 JVM 上 它将是 32
  • python 中的绝对导入不起作用,相对导入起作用

    我似乎无法在 python 中使用绝对导入 这是我的文件结构 a b init py init py foo py foo py Including or removing the future import has no effect f
  • 地理位置在 Windows 7/XP 上的 Safari 5.x 上不起作用

    我正在开发一个使用 W3C 标准地理定位 API 的应用程序 但我一生都无法让它在我的 Windows 7 和 XP PC 上的 Safari 上运行 它在我的 iPad 和 iPhone 上运行良好 它还可以在 Chrome 5 6 7
  • Swift 对象引用数组?

    我可能错过了有关 swift 的重要信息 我有一个包含键 快速数组对的地图 我更改了数组 但地图内的数组没有更改 有人可以解释一下发生了什么事吗 谢谢 var map String String var list String map li
  • 在 pandas 数据框中查找元素

    我有一个 pandas 数据框 如下所示 0 1 0 2 2 3 1 4 我想要做的是 如果我得到 2 作为输入 我的代码应该在数据框中搜索 2 当找到时 它返回另一列的值 在上面的示例中 我的代码将返回 0 和 3 我知道我可以简单地查看
  • 限制输入为数字和 。在输入字段上

    继我问的另一个问题之后 我似乎真的没有取得任何进展 由于我的无能 我选择了这些人的答案 因为他回答了我的问题 我正在收集我没有问正确的问题 因为我不知道该怎么做 所以问题是我有输入元素 保持简单
  • 企业防火墙/代理后面的 Firestore / gRPC

    我们公司已经使用 Firestore 构建了一个电子应用程序 现在我们正在尝试将该应用程序部署在公司代理和防火墙 客户环境 后面 使用电子设置代理身份验证设置后app on login 应用程序中的所有网络请求均成功 Firestore 连
  • mongoexport 语法错误消息

    我正在使用 mongodb 2 4 3 但无法让 mongoexport 工作 我收到的每个命令的错误消息是 JavaScript execution failed SyntaxError Unexpected identifier 起初我
  • MVC 如何使用列表项 POST 操作方法传递对象列表

    我想从 Razor 视图将项目列表发布到控制器 但我得到的对象列表为 null 我的班级结构是 Model List
  • 如何使用 Twitter Bootstrap ScrollSpy 执行函数

    我想在 ScrollSpy 收到通知后加载更多数据 但我不知道如何捕获该事件并执行函数 UPDATED该触发器现已被推送到主构建中 您可以在完整的文档中看到它 http twitter github com bootstrap javasc
  • Magento 无法使用正确的用户名和密码登录管理员

    我刚安装好Magento 1 7 0 2 在我的本地主机 LAMP 上 现在 安装后 当我想要进入管理面板时 它会要求我输入用户名和密码 虽然我使用了正确的用户名和密码仍然显示Invalid User Name or Password 我清
  • 从 ElementTree 获取属性名称和值

    我有一个 XML
  • 使用 ViewPager 和 Fragment

    我是一名 Android 开发新手 我正在尝试了解 ViewPager 在我尝试使用这个示例之前 http mobile tutsplus com tutorials android android user interface desig
  • 将类型化绑定参数与 PHP PDO-ODBC、unixODBC 和 FreeTDS 一起使用

    我使用以下设置从 PHP 应用程序访问 MS SQL 数据库 红帽企业 Linux 5 PHP 5 2 14 与 PDO 和 PDO ODBC unixODBC 2 2 11 免费TDS 0 82 1 dev 20100810 非参数化查询
  • Indy 10 TCP 服务器

    经过大量搜索后 我认为 Indy TCP 服务器最适合在我正在开发的即时通讯服务器上使用 我现在面临的唯一问题是向其他连接的客户端广播和转发消息 向同一客户端发回响应似乎没问题 并且不会挂起其他客户端活动 但对于将消息转发到其他客户端 我知