Реализация DATETIME
Команда DATETIME – это последняя команда данного протокола. Оно отличатся и от QUIT и от HELP, в том, что требует особой функциональности, которая не может быть создана только с помощью свойств. Для реализации команды DATETIME будет использован обработчик события.
Для начала построим базовый обработчик команды, используя шаги с которым вы уже знакомы:
1. Создадим новый командный обработчик.
2. Command = DateTime
3. Name = cmdhDateTime
4. ReplyNormal.NumericCode = 200
В данный момент свойство ReplyNormal.Text не определяется, обработчик события будет его определять для каждого ответа. Для определения обработчика, используйте инспектор объектов, выбрав командный обработчик для DATETIME. Переключитесь на закладку events и создайте событие OnCommand. Delphi создаст обработчик следующим образом:
procedure TForm1.IdTCPServer1TIdCommandHandler2Command(ASender: TIdCommand);
begin
end;
В обработчик OnCommand передается аргумент of ASender типа TIdCommand. Это не командный обработчик, а сама команда. Командные обработчики глобальны для всех соединений, тогда как, команды специфичны для соединения connection и обрабатываются в рамках экземпляра события OnCommand. Это гарантирует, что обработчик выполнит корректную обработку для каждого клиентского соединения.
Перед вызовом обработчика события, Indy создает экземпляр команды и инициализирует его свойства на основе данных обработчика команд. Вы можете использовать команды для смены свойства со значений по умолчанию, вызывать методы для выполнения задач или для доступа к свойству Connection для общения с соединением напрямую.
Данный протокол определяет команду DATETIME, как имеющую дополнительный параметр, указывающий формат даты и времени. Команда (TIdCommand) реализует это с помощью свойства Params, которое является списком строк. Когда команда принимается от клиента и свойство ParseParams установлено в true (по умолчанию) Indy использует свойство CmdDelimeter (по умолчанию равное #32 или пробел) для разделения команды и параметров.
Например, в данном протоколе, клиент может послать следующее:
DATETIME hhnnss
В этом случае, свойство ASender.Params будет содержать строку "hhnnss" в свойстве ASender.Params[0]. Количество параметров может быть определено с помощью свойства ASender.Params.Count.
Используя данные свойства обработчик OnCommand может быть реализован следующим образом:
procedure TForm1.IdTCPServer1TIdCommandHandler2Command(ASender: TIdCommand);
var
LFormat: string;
begin
if ASender.Params.Count = 0 then
begin
LFormat := 'yyyy-mm-dd hh:nn:ss';
end
else
begin
LFormat := ASender.Params[0];
end;
ASender.Reply.Text.Text := FormatDateTime(LFormat, Now);
end;
данная реализация просто читает параметры и использует ASender.Reply.Text для посылки ответа обратно клиенту. Не требуется устанавливать ASender.Reply.NumericCode, так как Indy инициализирует его значением 200, из командного обработчика ReplyNormal.NumericCode.
Примечание: используйте свойство ASender.Reply.Text.Text. Указание слова Text дважды требуется потому что свойство Text команды это список строк и мы имеем также TStrings.Text в дополнение к этому. Поскольку это список строк, другие методы или свойства, такие как Add, Delete и другие также могут использоваться. Свойство Text используется как ASender.Reply.Text, в некоторых случаях может быть предварительно проинициализировано и запись в него вызовет перекрытия текста.
Если снова протестировать пример с помощью telnet, то теперь ответ будет таким:
200 Hello
datetime
200 2002-08-26 18:48:06
В некоторых случаях свойство Params не может быть использовано. Свойство DATETIME одно из них. Представим себе следующую команду:
DATETIME mm dd yy
В данном случае значение свойства Params.Count будет равно 3 и событие будет неверно обработано, возвратит только значение месяца (mm). Для данных случаев, когда значение параметра включает разделители, можно использовать свойство UnparsedParams. Дополнительно, свойство ParseParams можно установить в False.
Свойство UnparsedParams содержит данные независимо от свойства ParseParams, но установка ParseParams в false увеличивает эффективность, сообщая Indy, что не требуется разбирать параметры в свойство Params.
Обработчик события, модифицированный для использования с UnparsedParams:
procedure TForm1.IdTCPServer1TIdCommandHandler2Command(ASender: TIdCommand);
var
LFormat: string;
begin
if ASender.Params.Count = 0 then
begin
LFormat := 'yyyy-mm-dd hh:nn:ss';
end
else
begin
LFormat := ASender.UnparsedParams;
end;
ASender.Reply.Text.Text := FormatDateTime(LFormat, Now);
end;