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 服务器 的相关文章

随机推荐

  • 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 服务器最适合在我正在开发的即时通讯服务器上使用 我现在面临的唯一问题是向其他连接的客户端广播和转发消息 向同一客户端发回响应似乎没问题 并且不会挂起其他客户端活动 但对于将消息转发到其他客户端 我知