如何向单个客户端而不是所有客户端发送命令?

2023-11-27

我正在用 Indy 10 编写一个简单的客户端/服务器聊天程序。我的服务器(idtcpserver)向客户端发送一条命令,客户端应答,但是当连接多个客户端并且服务器发送命令时,all连接的客户端向服务器发送数据。

如何向指定客户端而非全部客户端发送命令?


将命令发送到所有连接的客户端的唯一方法是,如果您的代码循环遍历所有向每个客户端发送命令的客户端。因此,只需删除该循环,或者至少将其更改为仅发送到您感兴趣的特定客户端。

向客户端发送命令的最佳位置是从该客户端自己的内部发送命令,以避免由于命令重叠而破坏与该客户端的通信OnExecute事件,例如:

procedure TForm1.IdTCPServer1Execute(AContext: TIdContext);
begin
  ...
  if (has a command to send) then
  begin
    AContext.Connection.IOHandler.WriteLn(command here);
    ...
  end;
  ...
end;

如果您需要从其他线程向客户端发送命令,那么最好为该客户端提供自己的出站命令队列,然后让该客户端的OnExecute事件在安全的情况下发送到队列。其他线程可以在需要时将命令推送到队列中。

type
  TMyContext = class(TIdServerContext)
  public
    ClientName: String;
    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 Create(AConnection, AYarn, AList);
  Queue := TIdThreadSafeStringList.Create;
end;

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

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

procedure TForm1.SendCommandToClient(const ClientName, Command: String);
var
  List: TList;
  I: Ineger;
  Ctx: TMyContext;
begin
  List := IdTCPServer1.Contexts.LockList;
  try
    for I := 0 to List.Count-1 do
    begin
      Ctx := TMyContext(List[I]);
      if Ctx.ClientName = ClientName then
      begin
        Ctx.Queue.Add(Command);
        Break;
      end;
    end;
  finally
    IdTCPServer1.Context.UnlockList;
  end;
end;

procedure TForm1.IdTCPServer1Connect(AContext: TIdContext);
var
  List: TList;
  I: Ineger;
  Ctx, Ctx2: TMyContext;
  ClientName: String;
begin
  Ctx := TMyContext(AContext);
  ClientName := AContext.Connection.IOHandler.ReadLn;
  List := IdTCPServer1.Contexts.LockList;
  try
    for I := 0 to List.Count-1 do
    begin
      Ctx2 := TMyContext(List[I]);
      if (Ctx2 <> Ctx) and (Ctx.ClientName = ClientName) then
      begin
        AContext.Connection.IOHandler.WriteLn('That Name is already logged in');
        AContext.Connection.Disconnect;
        Exit;
      end;
    end;
    Ctx.ClientName = ClientName;
  finally
    IdTCPServer1.Context.UnlockList;
  end;
  AContext.Connection.IOHandler.WriteLn('Welcome ' + ClientName);
end;

procedure TForm1.IdTCPServer1Disconnect(AContext: TIdContext);
var
  Ctx: TMyContext;
begin
  Ctx := TMyContext(AContext);
  Ctx.ClientName = '';
  Ctx.Queue.Clear;
end;

procedure TForm1.IdTCPServer1Execute(AContext: TIdContext);
var
  Ctx: TMyContext;
  Queue: TStringList;
begin
  Ctx := TMyContext(AContext);
  ...
  Queue := Ctx.Queue.Lock;
  try
    while Queue.Count > 0 do
    begin
      AContext.Connection.IOHandler.WriteLn(Queue[0]);
      Queue.Delete(0);
      ...
    end;
    ...
  finally
    Ctx.Queue.Unlock;
  end;
end;
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何向单个客户端而不是所有客户端发送命令? 的相关文章

  • 为什么turn服务器不支持tcp连接?

    我是 WebRTC 新手 我需要为我的 webrtc 应用程序配置我自己的 Turn 服务器 我使用以下命令安装了我的转弯服务器 apt get install coturn 我只需要通过 tcp 运行转变服务器 它不必使用 UDP 进行任
  • 如何使用 Delphi Sydney 10.4.2 和 Edge Webbrowser 组件获取 HTML SOURCE

    I have TEdgeBrowser在德尔福 10 4 2 中 我想从 HTML 代码中提取基于 RegEx 的字符串 在过去 这是可能的TWebBrowser 仅适用于 IE 11 或更低版本 作为 selectedEngine 但我的
  • TensorRT 多线程

    我正在尝试使用 python API 来使用 TensorRt 我试图在多个线程中使用它 其中 Cuda 上下文与所有线程一起使用 在单个线程中一切正常 我使用 docker 和 tensorrt 20 06 py3 图像 onnx 模型和
  • 如何正确实现TBitmap的扫描线访问?

    我正在尝试根据以下方式访问位图的扫描线关于内河码头的文章 http edn embarcadero com article 29173 使用像这样的扫描线 for y 0 to n do begin line bitmap scanline
  • Control.Invoke 在隐藏的 ShowDialog 中“卡住”

    我有解决这个问题的方法 但这不是我第一次被咬 所以我试图确切地了解发生了什么 从我的申请中 我ShowDialog表单 表单上有一个按钮 单击该按钮时会调用另一个 非 GUI 线程上的代码 非 GUI 线程发回状态 Pushed then
  • 执行按钮单击时使 wpf UI 响应

    在我的 wpf c 应用程序中 当用户按下按钮时会执行一个很长的过程 当按下按钮直到执行完整的代码时 窗口将冻结 用户无法在窗口中执行任何其他任务 如何使按钮单击代码作为后台进程 以便窗口响应用户 我尝试过以下方法 但没有成功 privat
  • 在 NodeJS 中处理长时间运行的进程?

    我看过一些较旧的帖子涉及这个主题 但我想知道当前的现代方法是什么 用例是 1 假设您想要在视频文件上执行长时间运行的任务 例如 60 秒长 例如jspm install这最多可能需要 60 秒 2 不能对任务进行细分 其他要求包括 需要知道
  • 多线程:只有在执行完其他方法后才调用执行方法

    我正在尝试根据要求异步处理方法 一旦第一个方法完成 只有第二个方法应该开始执行 问题是第一个方法本身具有在后台线程上运行的代码 我尝试了dispatch semaphore wait 但这也不起作用 dispatch queue t que
  • Indy FTP 传输类型

    我正在使用 IdFTP Indy 10 组件从远程位置下载一些文件 zip 和 txt 在获取每个文件之前 我将 TransferType 设置为二进制 IdFTP TransferType ftBinary IdFTP Get ASour
  • 如何在 C# 中从工作线程发布 UI 消息

    我正在用 C 编写一个简单的 winforms 应用程序 我创建了一个工作线程 我希望主窗口响应线程完成其工作 只需更改文本字段中的一些文本 testField Text Ready 我尝试了事件和回调 但它们都在调用线程的上下文中执行 并
  • 访问 Linux 线程(pthreads)的本地堆栈

    我目前正在实现一个使用多线程但对总内存消耗有要求的应用程序 我希望有一个主线程执行 I O 并有几个工作线程执行计算 目前 我在主堆栈上有几个可供工作人员访问的数据结构 我使用 OpenMP 进行工作分配 由于主 工作者模式不能很好地与 O
  • 跨线程操作无效 VB.NET

    我浏览了该网站 发现与该主题相关的问题是针对 C 的 我正在维护的应用程序是用 VB NET 编写的 因此 如果我忽略了一个问题 我深表歉意 这是我调用我的线程的地方 Private Sub saveBtn Click ByVal send
  • C# 是否可以中断 ThreadPool 内的特定线程?

    假设我已将一个工作项排入队列ThreadPool 但是如果没有要处理的数据 从BlockingQueue 如果队列为空并且队列中不再有工作 那么我必须调用Thread Interrupt方法 如果我想中断阻塞任务 但是如何用 a 做同样的事
  • 为应用程序启用主题

    我有一个旧的应用程序 在Win XP中的delphi 7中启动 现在我正在使用delphi 2009 win Vista 如果我开始一个新项目 所有按钮都有一个圆形边缘 但在我的旧应用程序中 所有按钮都有 方形 形状的外观 有什么设置我错过
  • 使用具有最大并发进程数的 multiprocessing.Process

    我有Python code from multiprocessing import Process def f name print hello name if name main for i in range 0 MAX PROCESSE
  • 自动打开命名管道和 tcp\ip

    我正在安装一个需要修改 SQL Server 的新产品 具体来说 启用 tcp ip 并打开命名管道 我知道如何手动完成 我想要的是一种通过 SQL 或 C 代码为新客户自动化执行此操作的方法 我希望有任何关于正确方向的建议 您可以使用 C
  • 无效的跨线程访问问题

    我有两个 ViewModel 类 PersonViewModel 和 PersonSearchListViewModel PersonViewModel 实现的字段之一是通过 WCF 下载的个人资料图像 本地缓存在独立存储中 PersonS
  • 如何使用用户输入来寻址 Pascal 中的特定变量(Eval/Exec?)

    我正在尝试在分形程序中做一些非常具体的事情隆起7X http apophysis 7x org 使用的脚本语言是Pascal 该项目是用德尔福写的 https svn code sf net p apophysis7x svn trunk
  • 如何使用 Handler.Post() 通知工作线程 UI 被修改?

    我有一个工作线程 偶尔我会使用以下命令向 UI 线程发送更新Handler Post 在某些情况下 我需要工作线程等待Handler Post 在 UI 线程上执行and视图被修改并且afterUI线程被修改 通知worker线程继续 这是
  • C# 系统 CPU 使用情况并与 Windows 任务管理器同步

    这是一个由两部分组成的问题 我想将我的代码发布到堆栈上以帮助其他人完成相同的任务 问题一 我有一个代码子集 我相信它可以根据测量间隔正确测量 CPU 使用情况 根据检索的时间跨系统中的尽可能多的核心 我在线程调用中使用 1 秒 我必须从网上

随机推荐

  • 如何从 jQuery ui Draggable 获取位置 x 和 y?

    这是一个例子http jsfiddle net naqbq 我如何获取当前位置x and y重新定位图像后
  • vftable-这是什么?

    高级编程语言中的vftable是什么 我读到类似虚拟对象结构的地址的内容 但这是一个非常混乱的信息 有人可以解释一下吗 它很可能代表 虚函数表 并且是一些运行时实现使用的一种机制 以便允许虚函数调度 主流 C 实现 GCC Clang MS
  • 如何在 Spring Boot 应用程序启动时启动 H2 TCP 服务器?

    当将应用程序作为 Spring Boot 应用程序运行时 我可以通过将以下行添加到 SpringBootServletInitializer main 方法中来启动 H2 TCP 服务器 文件中的数据库 SpringBootApplicat
  • Android使椭圆形背景可绘制并带有聊天角

    我知道如何创建椭圆形背景 我将此可绘制元素添加到relativelayout背景
  • 以兼容级别 80 运行 SQL Server 2005 数据库是否会对性能产生负面影响?

    我们的软件必须能够在 SQL Server 2000 和 2005 上运行 为了简化开发 我们以兼容级别 80 运行 SQL Server 2005 数据库 但是 在某些情况下 SQL 2005 上的数据库性能似乎比 SQL 2000 上慢
  • 路由在 Symfony 3.4 中不起作用

    我使用以下命令创建了一个新的 Symfony 3 4 项目 composer create project symfony skeleton my project 之后我添加了以下组件 composer require twig compo
  • 如何在U-Boot和Linux内核中添加自定义的ATAG变量?

    我要添加定制atagU Boot 和 Linux 内核中的变量 我怎样才能做到这一点 有没有什么程序可以添加ATAG变量在U Boot and Linux 最新的 Linux 内核正试图废弃ATAGS with 设备树 但是 那setup
  • 如何像 Instagram 和 Vine 一样在 ListView 中播放视频?

    我是 Android 开发新手 我正在尝试在列表视图中播放多个视频 目前 每个列表视图行项目都是一个视频视图 这种方法不起作用 因为当我开始滚动时 VideoViews 表现异常 我研究过here here here并发现VideoView
  • 获取绘图的只读属性名称列表

    如果要通过属性结构复制绘图 则需要过滤掉只读属性 例如 Annotation BeingDeleted Parent Type 有没有办法获取对象的只读属性列表 该问题源自一个相关问题 如何从绘图处理程序中绘图 我开始研究上一个问题 尝试动
  • 按行比较矩阵与向量中的元素

    我想将矩阵的值与相应的向量进行比较 比较应该按行进行 矩阵示例 ret TLT VTI 1995 01 20 0 005649718 0 004461441 1995 01 23 0 002840909 0 002560820 1995 0
  • 如何在 AWS Elastic Beanstalk 上使用 Resque 运行 Rails 后台作业?

    我正在运行我的 Rails 应用程序AWS 弹性豆茎平台 它运行具有 Auto Scaling 和 Elastic Load Balancing 的单个 EC2 实例 我想知道怎么跑resque delayed job or sidekic
  • mysql联合不同列数

    我知道联合查询必须具有相同数量的列 我正在尝试从表中获取结果comments以及表中的结果strings 它有多个连接 我如何正确地做到这一点 我还没有测试过 因为我知道我会收到不同数量的列的错误 这是我试图合并的两个查询 查询1 字符串
  • 如何使用TreeStore或TreeEditor组件更新数据?

    我使用 tree Panel 和 TreeStore 组件 我使用 JSON 文件来存储我的数据 但我想知道如何使用 TreeStore 升级我的数据 我解释我的问题 我的页面上有 2 个组件 Tree Panel用TreeStore和Pa
  • LinkedIn 的访问令牌更新流程可以在服务器上执行吗?

    在 Facebook 的 Graph API 中 一旦我们初步验证了用户身份 我们就可以直接与 API 从服务器 进行交互 以获得长期存在的页面访问令牌 这个长期存在的页面访问令牌永远不会过期 https developers facebo
  • 在 python opencv 中为像素着色

    我需要为图像中的像素着色 我使用opencv和python 我试过img x y 255 255 255 给一个上色pixel x y 但它不会工作 这其中是否有什么错误呢 你能建议任何方法吗 提前致谢 img x y 255 255 25
  • IF EXISTS UPDATE ELSE INSERT 语法错误

    我正在使用由我的 ISP 托管的 MySQL 5 1 这是我的查询 mysql query IF EXISTS SELECT FROM licensing active WHERE title 1 title 1 THEN BEGIN UP
  • 从内容页设置母版页上的属性值

    每次加载页面时 我都需要将数据传递给母版页中的变量 我在每个内容页面上设置了一个RequiredRoles 字符串 定义了访问该页面所需的角色 在我的母版页上 我有一种方法可以获取该数组 并检查当前用户是否属于这些角色中的一个或多个 我将如
  • 方法重载装饰器

    我正在尝试编写一个为 python 提供方法重载功能的装饰器 类似于中提到的PEP 3124 我编写的装饰器非常适合常规函数 但我无法让它适用于类中的方法 这是装饰器 class Overload object def init self
  • UI Router Extras 破坏了我的单元测试并出现意外结果错误?

    问题 安装 ui router extras 不是普通的 ui router 时 为什么我的测试失败 我该如何使用ui router extras我的测试仍然通过吗 如果你想快速安装 请使用 yeoman angular fullstack
  • 如何向单个客户端而不是所有客户端发送命令?

    我正在用 Indy 10 编写一个简单的客户端 服务器聊天程序 我的服务器 idtcpserver 向客户端发送一条命令 客户端应答 但是当连接多个客户端并且服务器发送命令时 all连接的客户端向服务器发送数据 如何向指定客户端而非全部客户