Перейти к содержанию

Лидеры


Популярный контент

Показан контент с высокой репутацией за 03.03.2020 во всех областях

  1. 2 балла
    Класс для работы с FastCGI серверами, такими как php-fpm. Для тех кто не в теме : веб-сервер, к примеру nginx, получает запросы и отправляет их на исполнение FastCGI серверу, к примеру php-fpm, php-fpm получает имя скрипта, параметры, выполняет все и возвращает результат в nginx, который в свою очередь возвращает этот результат запросившему клиенту. С помощью класса вы можете так же, выполнять php скрипты на локальном или удаленном сервере. Исходники https://github.com/EvgeniyKorepov/FastCGIClient Пример delphi var FFastCGI : TFastCGI; ... procedure TFormMain.FormCreate(Sender: TObject); var AHost : String; APort : Word; AScriptFileName, ARequest, AContent : String; begin AHost := '10.0.0.4'; APort := 9000; FFastCGI := TFastCGI.Create(AHost, APort); FFastCGI.KeepAlive := True; AScriptFileName := '/opt/xxx.php'; ARequest := 'request=1234567890'; if FFastCGI.Get(AScriptFileName, ARequest, AContent) then Memo.Text := AContent else Memo.Text := FFastCGI.StatusCode.ToString + ' ' + FFastCGI.StatusText; end; пример php <?php header('Content-Type: text/html; charset=utf-8'); if (isset($_REQUEST["request"])) if ($_REQUEST["request"] == "1234567890") { header("Status: 200"); echo 'OK'; } else { http_response_code(400); echo "ERROR"; }
  2. 2 балла
    В прошлой теме я показал как делать демонов старой школы - серьезных и самодостаточных. Но это все в прошлом. Теперь существуют системы управления процессами, где все намного, намного проще. Исходники тут https://github.com/EvgeniyKorepov/LinuxDaemonNewStyle Заметьте, теперь никаких потоков, все элементарно, systemd сделает всю работу за нас. Половина кода - разбор параметров командной строки. Вторая половина - бесконечный цикл, ожидающий сигналов от экземпляра класса демона нового стиля . Код самого класса сократился на треть. Если запустите приложения в консоли - будет самое обычное приложение, которые умрет при закрытии консоли. Запуск в качестве бессмертного демона - через systemd, причем он сможет автоматически перезапускать вашего демона при крахе. Эти параметры задаются в текстовом файле /etc/systemd/system/DaemonNewStyleTest.service program DaemonNewStyleTest; {$APPTYPE CONSOLE} uses System.SysUtils, System.IOUtils, System.SyncObjs, Posix.Stdlib, Posix.SysStat, Posix.SysTypes, Posix.Unistd, Posix.Signal, Posix.Fcntl, Posix.Syslog in 'Posix.Syslog.pas', UnitDaemonNewStyle in 'UnitDaemonNewStyle.pas'; var AEvent : TEventType; begin if ParamCount = 0 then begin syslog(LOG_ERR, 'No parameters'); ExitCode := EXIT_FAILURE; exit; end; if ParamStr(1).ToLower.Equals('stop') then begin if Daemon.Stop(30) then ExitCode := EXIT_SUCCESS else ExitCode := EXIT_FAILURE; exit; end; if ParamStr(1).ToLower.Equals('reload') then begin if Daemon.Reload() then ExitCode := EXIT_SUCCESS else ExitCode := EXIT_FAILURE; exit; end; if not ParamStr(1).ToLower.Equals('start') then begin syslog(LOG_ERR, 'Unknow parameters'); ExitCode := EXIT_FAILURE; exit; end; syslog(LOG_NOTICE, 'main START'); while Daemon.IsRunning do begin syslog(LOG_NOTICE, 'main LOOP'); Daemon.Execute(AEvent); if AEvent <> TEventType.None then syslog(LOG_NOTICE, 'main Daemon receive signal'); case AEvent of TEventType.Start : begin syslog(LOG_NOTICE, 'main Event START'); end; TEventType.Reload : begin // Reload config syslog(LOG_NOTICE, 'main Event RELOAD'); end; TEventType.Stop : begin syslog(LOG_NOTICE, 'main Event STOP'); ExitCode := EXIT_SUCCESS; Sleep(10); // simulate destroy delay break; end; end; Sleep(1000); end; end. systemctl start DaemonNewStyleTest.service systemctl reload DaemonNewStyleTest.service systemctl stop DaemonNewStyleTest.service
  3. 2 балла
    обычно ничего не получается сопровождается текстом: 'Ошибка сети: '+E.Message или lResponse.StatusCode Почувствуй разницу: у мена ошибка с текстом " " в строке n, снифаю - все уходит но не сервер не сохраняет, помогите мне, ой все! ничего не работает! вот мой высер, доделайте за меня... ну че, слабаки! не могете?
  4. 1 балл
    Вопрос решился открытием разрешения "Память" приложению на телефоне.
  5. 1 балл
    Добрый день! Заметил неприятный эффект(баг, особенность либо моё недопонимание чего либо). Через некоторое непродолжительно время работы PopItem( в версии возвращающей TWaitResult) перестаёт ожидать данные из очереди, и перестаёт "усыплять" на(до) TThreadedQueue.FPopTimeout мсек, поток из которого была вызвана, а возвращает wrTimeout без ожидания(менее 100 тактов). Ниже тестовый код, который демонстрирует этот эффект. Описание теста: основной поток, создаёт поток с условным названием FirstDepthThread, который: -запускает MaxThread(константа)+1 потоков( по умолчанию их 10) с условными названиями SecondDepthThread_X ; - c интервалом в 2-5 секунды в каждую из очередей записывается константный идентификатор. Кол-во очередей =MaxThread+1(в каждом из потоков SecondDepthThread_X есть поле с очередью) . Функционал потоков SecondDepthThread_X - ждать данных извлекать их из очереди. В Procedure TSecondDepthThread.Execute есть 2-а условия( помечены в тексте, как {жучок 1} и {жучок 2}), которые в моём понимании никогда не должны выполняться, но...выполняются. Понимание, как обойти этот эффект есть, но очень хочется разобраться, что не так с указанной реализацией? Буду рад мнениям. Условия тестирования: Delphi 10.3.1., W10.1903. Так же рекомендуется попробовать разные значения MaxThread( при MaxThread=2, эффект может и не наступить,при MaxThread= 9, на 3-х разные cpu Intel эффект наступает через ,5-5 секунд, на стареньком AMD FX-8300 лишь через 2-10 минут. при MaxThread=14, AMDешный cpu так же "сдаётся" за несколько секунд). В отладчике смотрим окно Events. Если без отладчика, то в виндовом диспетчере задач, как только загрузка процессора у данного процесс подскочила от 0 к 100%, значит эффект достигнут. unit UThreadedQueue; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs,System.Generics.Collections; Const MaxThread=9; type TSecondDepthThread=class(TThread) Protected FThreadNomber:integer; FError:boolean; Procedure Execute;override; Public TickSending:Cardinal; TickInterval:Cardinal; SendingDataQuery:TThreadedQueue<TBytes>; constructor Create(AThreadCount:integer); Destructor Destroy;override; Property ThreadNomber:integer read FThreadNomber; end; TFirstDepthThread=class(TThread) Protected FSecondDepthThreads:array[0..MaxThread] of TSecondDepthThread; Procedure Execute;override; Public SendingDataQuery:TThreadedQueue<TBytes>; constructor Create; Destructor Destroy;override; end; TForm1 = class(TForm) procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); private FFirstDepthThread:TFirstDepthThread; { Private declarations } public { Public declarations } end; var Form1: TForm1; implementation uses SyncObjs,TypInfo; {$R *.dfm} Constructor TSecondDepthThread.Create(AThreadCount: Integer); begin FError:=false; TickInterval:=2000+random(3000); FThreadNomber:=AThreadCount; SendingDataQuery:=TThreadedQueue<TBytes>.Create(100, 1, 1); //инициализация очереди FreeOnTerminate := false; Inherited Create(false); end; Destructor TSecondDepthThread.Destroy; begin FreeAndNil(SendingDataQuery); inherited; end; Procedure TSecondDepthThread.Execute; var iCounterPerSec,TimeStart, TimeFinish: TLargeInteger; QSize:integer; WaitResult:TWaitResult; ReceivedData:TBytes; ElapsedTime:double; begin NameThreadForDebugging('SecondDepthThread_'+inttostr(FThreadNomber)); while (not Terminated)do begin QueryPerformanceFrequency(iCounterPerSec); QueryPerformanceCounter(TimeStart); WaitResult:=SendingDataQuery.PopItem(QSize,ReceivedData); QueryPerformanceCounter(TimeFinish); ElapsedTime:= (TimeFinish - TimeStart)/iCounterPerSec; if (ElapsedTime<0.000082)and(WaitResult=TWaitResult.wrTimeout)and(not FError) then begin {жучок 1} OutputDebugString(pchar('Поток№ '+inttostr(FThreadNomber)+ ' Всё.., началось! Ответ(состояние) очереди='+ GetEnumName(TypeInfo(TWaitResult), Ord(WaitResult))+' выполнение за '+ FormatFloat('0.000000', ElapsedTime) + ' сек., а должно быть более 0.001 сек')); FError:=true; // дальше сообщения с wrTimeout не выводим, т.к. их слишком много end; if (WaitResult=TWaitResult.wrSignaled)and(length(ReceivedData)>0) then begin if ReceivedData[0]=100+FThreadNomber then {OutputDebugString(pchar('Поток№ '+inttostr(FThreadNomber)+ ' ,есть корректные данные'))}; if ReceivedData[0]<>100+FThreadNomber then {жучок 2} OutputDebugString(pchar('Поток№ '+inttostr(FThreadNomber)+ 'некорректные данные, должно прийти'+ inttostr(100+FThreadNomber)+' ,а пришло '+inttostr(ReceivedData[0]))); if ReceivedData[0]=0 then {подвид 2-го жука} OutputDebugString(pchar('Поток№ '+inttostr(FThreadNomber)+ ' Такого быть не должно! Ответ(состояние) очереди='+ GetEnumName(TypeInfo(TWaitResult), Ord(WaitResult))+ ' сигнал о наличии данных есть, а данных нет,'+ ' выполнение за '+FormatFloat('0.000000', ElapsedTime) )); ReceivedData[0]:=0; // для контроля извлекаемых из очереди данных. end end; end; Constructor TFirstDepthThread.Create; Var Count:integer; begin for count := 0 to MaxThread do FSecondDepthThreads[Count]:=TSecondDepthThread.Create(Count); FreeOnTerminate := false; Inherited Create(false); end; Destructor TFirstDepthThread.Destroy; Var Count:integer; begin for Count := 0 to MaxThread do begin FSecondDepthThreads[Count].Terminate; FSecondDepthThreads[Count].WaitFor; FSecondDepthThreads[Count].Free; end; inherited; end; Procedure TFirstDepthThread.Execute; var Count:integer; SendingData:Tbytes; begin NameThreadForDebugging('FirstDepthThread'); Setlength(SendingData,1); while not terminated do begin for Count := 0 to MaxThread do with FSecondDepthThreads[Count] do if GetTickCount-TickSending>TickInterval then begin SendingData[0]:=100+ThreadNomber; SendingDataQuery.PushItem(SendingData); TickSending:=GetTickCount; end; sleep(1); //yield; end; end; procedure TForm1.FormCreate(Sender: TObject); begin FFirstDepthThread:=TFirstDepthThread.Create; end; procedure TForm1.FormDestroy(Sender: TObject); begin FFirstDepthThread.Terminate; FFirstDepthThread.WaitFor; FFirstDepthThread.Free; end; end.
  6. 1 балл
    Сергей Сергеев

    [IOS] хранение данных

    у меня приложение работает так и в Андроид и Иос в FormShow - вызываю Read, при первом запуске файла нет, ничего не заполняется. При первом заполнении вручную полей и попытке входа по кнопке - делаю сохранение Write При следующем запуске - файл уже есть и параметры входа считаются Для создания файла со значениями "по умолчанию" можно сделать в Read - try - Except ( добавил ) - но не проверял
  7. 1 балл
    juppy

    [IOS] хранение данных

    Вот отличное описание для тех, кто ни разу не работал. Там с примерами и прочим блекждеком. http://docwiki.embarcadero.com/Libraries/Rio/en/System.IniFiles.TIniFile http://docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/HelpUpdate2/EN/html/delphivclwin32/IniFiles_TIniFile.html Создание файла и чтение из него данных занимает нематериальное время. Поэтому я делаю так: Создаю сам файл с начальной инициализацией при первом развертывании. В примере - это создание главной формы. И там же потом его читаю но уже созданный. вот конструкция с начальной инициализацией чтением.
  8. 1 балл
    juppy

    [IOS] хранение данных

    Нет не нужно его засовывать в ресурс. Создаете его при развертывании приложения как обычно. Если нужно сделать начальные установки, то в методах класса TIniFile есть Read*** который возвращает значения по умолчанию в качестве параметра если нечего читать: Settings.ZonesColor := IniFile.ReadInteger('Settings','ZonesColor',TAlphaColors.Navy); В данном случае, если в группе Settings не найдется параметр ZonesColor, то ReadInteger вернет значение Navy, если найдет вернет тот параметр, который там прописан. Я обычно при развертывании создаю INI файл с начальными установками, сохраняю его и потом с ним работаю.
  9. 1 балл
    juppy

    [IOS] хранение данных

    На мой скромный взгляд, самый простой сопсоб - это SQLite. Но можно и в ini. На мобильных платформах работает все как обычно. iniMapFile: TIniFile; iniMapFilePath := TPath.Combine(TPath.GetDocumentsPath, 'ИМЯФАЙЛА.ini'); IniFile := TIniFile.Create(iniMapFilePath); Можно и в путь приложения сохранять.
  10. 1 балл
    Евгений Корепов

    Создание сервиса (демона) в Linux

    Я написал класс для демонизации приложения в linux. Класс форкает процесс, обрабатывает поступающие сигналы и передает их в основной поток через потокобезопасную очередь. Исходники https://github.com/EvgeniyKorepov/LinuxDaemon Для использования просто подключите модуль UnitDaemon в свое консольное приложение: program DaemonTest; {$APPTYPE CONSOLE} uses System.SysUtils, System.IOUtils, System.SyncObjs, Posix.Stdlib, Posix.SysStat, Posix.SysTypes, Posix.Unistd, Posix.Signal, Posix.Fcntl, Posix.Syslog in 'Posix.Syslog.pas', UnitDaemon in 'UnitDaemon.pas'; var AEventType : TEventType; begin syslog(LOG_NOTICE, 'main START'); while True do begin syslog(LOG_NOTICE, 'main LOOP'); if UnitDaemon.QueueEvent.PopItem(AEventType) = System.SyncObjs.TWaitResult.wrSignaled then begin syslog(LOG_NOTICE, 'main UnitDaemon.QueueEvent.PopItem'); case AEventType of TEventType.StopProcess : begin syslog(LOG_NOTICE, 'main Event StopProcess'); ExitCode := EXIT_SUCCESS; exit; end; TEventType.Start : begin syslog(LOG_NOTICE, 'main Event START'); end; TEventType.Reload : begin // Reload config syslog(LOG_NOTICE, 'main Event RELOAD'); end; TEventType.Stop : begin syslog(LOG_NOTICE, 'main Event STOP'); ExitCode := EXIT_SUCCESS; exit; end; end; end; Sleep(50); end; end. Так же поддерживается systemd - для этого положите DaemonTest.service в /etc/systemd/system/ и используйте : systemctl start DaemonTest.service systemctl reload DaemonTest.service systemctl stop DaemonTest.service
  11. 1 балл
    Вам проще адаптировать сайт https://gector-spb.ru/ для мобильных браузеров. Наймите верстальшика за доширак - обойдется дешевле и по времени гораздо быстрее.
  12. 1 балл
    Tumaso

    Требуется приложение на на все смартфоны

    @Sashar333 если вы из потока меняете визуальные компоненты в основном потоке приложения, то вам нужно оборачивать изменения визуальных компонентов в синхронизацию. А правильнее будет в потоке получить только данные, а созданием компонентов и их заполнением должен заниматься главный поток. Т.е. в потоке считываете данные в TStringList, а код парсинга этого текста переносите в форму
  13. 1 балл
    Ingalime

    переход к x64?

    Это выйдет в виде новой версии студии в середине этого года.
  14. 1 балл
    Сергей Сергеев

    10.3.3 не видит IOS SDK

    вообщем все заработало, проблема была в криво установленном Xcode ( устанавливал скачивая из developer.apple.com, установился в папку Загрузки) поэтому был не видим для PAS, перетащил в Программы и это оживило, потом для верности, еще и переустановил из АппСтор последний. решение здесь
  15. 1 балл
    Edward Tarasov

    10.3.3 не видит IOS SDK

    У catalina проблема была с PAserver(точно не помню или он на 64 бит не переведен или еще че) корочь решается установкой на винду VMware и скачивание образа 10.14.(последнего) дальше туда все накатываешь и терпимо работает. а дальше ждем пока не решат проблему с PA
  16. 1 балл
    Vitaldj

    скачать и запустить apk

    Перечитал ваш пост несколько раз, но так и не понял вашей просьбы)))
  17. 1 балл
    Евгений Корепов

    Запуск демона на Linux

    Вот просто идеальная статья по запуску демона под Linux http://blog.paolorossi.net/2017/09/04/building-a-real-linux-daemon-with-delphi-part-2/ Помимо объяснения механизма fork с отличными примерами, есть куча дополнительной наиполезнейшей инфы.
  18. 1 балл
    А есть можно выложить исходники для приложения трекера
  19. 1 балл
    Владимир Б.

    TMemo для вывода лога тормозит

    Подготовил за пол часа реализацию с цветом и стилем строки. Правда поменял форматирование кода под то которое мне удобней и понятней. FastMemo.zip
  20. 1 балл
    Процедура Invalidate не перерисовывает форму немедленно, она лишь добавляет сообщение на перерисовку в очередь сообщений. Соотв. форма перерисуется когда не будет других событий в очереди, в данном случае - после всех длительных операций или после вызова .ProcessMessages
  21. 1 балл
    есть более интересный и по-мне, более правильный способ по нажатию в меню не сразу выполняете что-то, а ЗАПИСЫВАЕТЕ действие, которое ВЫПОЛНИТСЯ по событию закрытия мультивью тогда реакция наступает визуально правильная и дальше крутите колеса, запускайте потоки и все такое
  22. 1 балл
  23. 1 балл
    Здравствуйте, подскажите пожалуйста. Как программно уменьшить масштаб страницы в Webbrowser? Когда загружаю страничку - масштаб большой.
  24. 1 балл
    Может быть кто-то сталкивался с тем как заставить TMediaPlayer воспроизводить видео на втором, - дополнительном (расширенном) мониторе в Windows. По факту играет только в пределах основного монитора.
  25. 1 балл
    Могу ошибаться, но по моему это
Эта таблица лидеров рассчитана в Москва/GMT+03:00
×
×
  • Создать...