Первые несколько шагов. Текущую версию я делаю Visual Components Library App. Потом можно будет перевернуть это приложение в сервис, при желании.
Архитектура следующая
JSON
Наш сервер будет возвращать нам все данные в json. Для этого используем библиотеку superobject. Ответ на сервере формируется примерно так…
1 2 3 4 5 |
... json := SO; json.S['answer'] := 'ok'; json.AsJSon(false, false); ... |
CommandGet
Поскольку это центральный метод компонента TidHTTPServer, то я вынес его в отдельный модуль. В других высоконагруженных проектах, там были сотни методов, а поскольку TidHTTPServer у нас находится в Main, то не стоит раздувать главный модуль. Итого, сделано так…
1 2 3 4 |
procedure TMain.ServerCommandGet(AContext: TIdContext; ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo); begin FCommandGet.Execute(AContext, ARequestInfo, AResponseInfo); end; |
…
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
procedure TCommandGet.Execute(AContext: TIdContext; ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo); var json: ISuperObject; begin if ARequestInfo.URI = '/testConnection' then begin json := SO; json.S['answer'] := 'ok'; json.AsJSon(false, false); AResponseInfo.CacheControl := 'no-cache'; AResponseInfo.CustomHeaders.Add('Access-Control-Allow-Origin: *'); AResponseInfo.ContentText := json.AsJSon(false,false); AResponseInfo.ResponseNo := 200; AResponseInfo.WriteContent; end else AResponseInfo.ResponseNo := 404; end; |
Таймеры
Возможно, в проекте будут различные таймеры, для них создадим специальный модуль uTimers. Таймер рабочего времени работает следующим образом.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
procedure TTimers.tWorkTimerTimer(Sender: TObject); var t: TThread; begin t := TThread.CreateAnonymousThread( procedure var s: string; begin s := DateTimeToStr(Now()); PostMessage(Main.Handle, WM_WORK_TIME, 0, LParam(PChar(s))); end); t.FreeOnTerminate := true; t.Start; end; |
Обновляем статус бар на главной форме
1 2 3 4 |
procedure TMain.UpdateWorkTime(var aMsg: TMessage); begin StatusBar.Panels[1].Text := PChar(aMsg.LParam); end; |
Класс SmartPointer
Использован данный класс, о нем я говорил ранее в своем блоге, пример использования
1 2 3 4 5 6 7 |
procedure TMain.bGetRequestClick(Sender: TObject); var client: ISmartPointer<TIdHTTP>; begin client := TSmartPointer<TIdHTTP>.Create(); mAnswer.Lines.Add(client.Get('http://localhost:' + Server.DefaultPort.ToString + '/' + eRequest.Text)); end; |