delphi – Indy 10 TCP服务器

delphi – Indy 10 TCP服务器,第1张

概述经过大量的搜索,我认为Indy TCP服务器最适合在我正在使用的Instant Messenger服务器上使用.我现在面临的唯一问题是向其他连接的客户端广播和转发消息,向同一客户端发送回响应似乎没有,并且不会挂起其他客户端活动,但是为了将消息转发给其他客户端我知道的机制是通过使用aContext.locklist,并在连接列表之间迭代,以找到要接收数据的客户端连接. 我认为这里的问题是它会冻结列表 经过大量的搜索,我认为Indy TCP服务器最适合在我正在使用的Instant Messenger服务器上使用.我现在面临的唯一问题是向其他连接的客户端广播和转发消息,向同一客户端发送回响应似乎没有,并且不会挂起其他客户端活动,但是为了将消息转发给其他客户端我知道的机制是通过使用aContext.lockList,并在连接列表之间迭代,以找到要接收数据的客户端连接.

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

我使用的是Indy 10和Delphi 7

广播代码:

Var tmpList: TList;    i: Integer;BegintmpList := 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;
解决方法 是的,您必须遍历上下文列表才能向多个客户端广播消息.但是,您没有(也不应该)从循环内部执行实际写入.一,正如您已经注意到的那样,通过保持列表锁定一段时间可以影响服务器性能.二,它不是线程安全的.如果您的循环将数据写入连接而另一个线程同时写入同一连接,则这两个写入将相互重叠并破坏与该客户端的通信.

我通常做的是实现每个客户端的出站队列,使用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;
总结

以上是内存溢出为你收集整理的delphi – Indy 10 TCP服务器全部内容,希望文章能够帮你解决delphi – Indy 10 TCP服务器所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1277815.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-09
下一篇 2022-06-09

发表评论

登录后才能评论

评论列表(0条)

保存