Как хранить идентификатор в списке подключения к клиенту - Indy 10
-
27-10-2019 - |
Вопрос
Я создаю TCP -сервер, который получает несколько клиентов и должен быть в состоянии отправлять сообщения каждому.
Как получить ручку с клиентским соединением, а затем отправить произвольные данные?
Спасибо
Код:
procedure TFRM_Main.ServerConnect(AContext: TIdContext);
var lAdd: TListItem;
var Index: integer;
begin
lAdd := ListView.Items.Add;
//AContext connection ID, what to do here?
lAdd.Caption := IntToStr(Index);
end;
Решение
использовать:
AContext.Connection.IOHandler.Write( (* bytes *) );
AContext.Connection.IOHandler.WriteFile( (* send a file to the client *) );
Для получения дополнительных вариантов, просто вызовите завершение кода (CTRL+Space) после Iohandler и посмотрите на доступные параметры, некоторое время назад я написал простое приложение для тестирования клиента/сервера, нажмите здесь Чтобы увидеть и/или загрузить источник.
Другие советы
TIdTCPServer
это многопоточный компонент. Доступ к пользовательскому интерфейсу прямо из его OnConnect
событие (или OnDisconnect
, OnExecute
, или же OnException
) не безопасен. Вам нужно использовать инди TIdSync
или же TIdNotify
класс для безопасного доступа к пользовательскому интерфейсу.
Чтобы ответить на первоначальный вопрос, самый простой, но не обязательно самый безопасный способ - хранить TIdContext.Connection
указатель объекта в TListItem.Data
имущество. Затем основной код потока будет иметь прямой доступ к соединению, когда он нуждается в нем.
Я не советую этому, хотя. Более безопасное решение состоит в том, чтобы уникально идентифицировать каждого клиента самостоятельно, например, с именем пользователя, которое отправляет клиент, и сохранить этот идентификатор в TIdContext.Data
а также TListItem.Data
характеристики. Затем, когда ваш основной код потока хочет отправить сообщение клиенту, он может пройти через TIdTCPServer.Contexts
Список ищет желаемый идентификатор, и если он будет найден, он будет иметь доступ к соответствующему TIdContext.Connection
объект.