Akromd
-
Постов
43 -
Зарегистрирован
-
Посещение
Сообщения, опубликованные Akromd
-
-
1 час назад, kami сказал:
В данном случае под сервером понимается серверный сокет с необходимыми обработчиками событий. Смотрите индейцев и выбирайте любой понравившийся.
Но гораздо проще взять готовую технологию - AppTethering. С самостоятельной реализацией вы рискуете погрязнуть в энтомологоии, особенно - если возьмете минималистичный протокол (TCP/IP).
Обратите внимание, что в любом случае устройства сконнектятся друг с другом только если они находятся в одной подсети.
Об телеринге я уже задумался. Однако первоначальная идея что устройства соединяются не в одной подсети.
Видимо все таки придется копать инди, а так хотелось с датаснапом легко и быстро)
-
3 часа назад, GASCHE сказал:
Перефразирую, читать данные других клиентов с сервера, проводить вычисления, итоги и свои данные скидывать на сервер.
Это возможно, на каждом клиенте поднимаете свой сервер, который будет слушать запросы других клиентов и скидывать им требуемые данные. Но не думаю, что это будет проще чем работа с одним сервером.
И мы опять возвращаемся к вопросу как поднять сервер на android)
-
1 час назад, GASCHE сказал:
Как-то не понятно, что мешает каждому клиенту читать данные с сервера, проводить вычисления, итоги скидывать на сервер?
Проблема в том что все вычисления зависят от данных других клиентов. Без них никаких вычислений не будет.
-
4 минуты назад, krapotkin сказал:
тетеринг в одной сети отработает нормально
можно и датаснап использовать
а в разные сети только через центральный сервер
С тетерингом какие то проблемы, но это другая тема, мне еще разбираться и разбираться.
С разными сетями все работает, но все вычисления производятся на сервере (их довольно много),а клиенты запросами получают данные. Чем больше клиентов, тем больше вычислений. Соответственно и хотелось бы скинуть вычисления на клиентов (Разбить на группы) и данные будут передаваться между этими группами. А на сервер посылаются только итоги.
-
7 минут назад, ZuBy сказал:
такс, давайте разберемся. для ясности
1) приложения на каких платформах будет работать?
2) будет использоваться БД?
3) всегда приложения в одной сети будет?
4) datasnap обязательно?
Да, отбъясняю я не очень)
1. Приложение мультиплатфотрменное. Все что поддерживает FMX на тех платформах и будет приложение.
2. БД пока не используется, и не планируется. Но мало ли.
3. Не всегда. Чаще всего не в одной сети, для этого использую стационарный сервер со статическим ip. Но хотелось бы чтоб когда два и более приложения были в одной сети, они имели возможность соединятся без стационарного сервера.
4. Не обязателен. Просто ничего другого мультиплатформенного не придумал. И с Datasnap уже что-то понял и это работает.
-
6 минут назад, krapotkin сказал:
ну, ладно, пусть становится, а по какому IP доступ-то? 192.168.143.41 ?
Имеет значение? Я не понимаю технологии процесса,через какие компоненты все это осуществить в Delphi. Если использовать datasnap то все понятно, когда у нас сервер на компе и через него все запросы. Но что сделать, если мы хотим сервер облегчить, оставив в функционале только связывание клиентов друг с другом.
-
2 минуты назад, krapotkin сказал:
и как же два клиента общаются, минуя сервер, интересно?
я и так знаю, где находятся мои клиенты - за роутером в локальной сети
Имеется ввиду, что один из них становится сервером для другого клиента.
-
1 час назад, ZuBy сказал:
даже в теории сервер на мобиле не должен быть)
может кто пользуется (я нет) оф. приложение фейсбука и есть сервер.
в теории: 3rd party приложения общаются не с сервером (api facebook.com), а приложением установленным в телефоне через SDK.
что в реале: батарейка улетает в 0, дробление единого сервиса на несколько приложении (имхо)
Да, идейно все это правильно, что сервер на мобиле ересь)
Но как тогда поступают в случае общения двух клиентов минуя сервер?
То есть обычно (в моем понимании) реализуется запрос клиента у сервера чего либо, таким образом получая и изменяя данные на сервере. В результате другой клиент может получить измененную информацию с сервера. А если мы хотим миновать сервер? чтобы клиент делал запрос сразу другому клиенту? А сервер используем только для того, чтобы в первый раз лишь сказать клиентам где они находятся.
-
А теперь такой вопрос...а возможно ли сделать datasnap сервер на android ?
-
9 часов назад, Alexander сказал:
А технология Tethering не подойдёт?
А она будет работать в связке с datasnap? Сейчас попробую использовать
-
Добрый вечер.
Только начал изучать технологию Datasnap. Разобрался с простейшим сервером и клиентом, находясь в одной сети все прекрасно работает.
Но сейчас ставлю перед собой задачу, что клиенту изначально неизвестен ip сервера, но знаем что он находится в одной сети. Сразу возникает мысль послать широковещательный пакет от клиента и при получении его сервером отправить ответ.
Теперь вопрос, как послать такой пакет? Если кто то может подсказать где почитать про это и посмотреть примеры, буду очень признателен.
-
3 часа назад, Brovin Yaroslav сказал:
Пока сложно о чем-то говорить. Но надеюсь, что все первоначальные задумки исполнятся.
А когда планируется выпуск этого компонента?
-
При включенной функции ReportMemoryLeaksOnShutdown заметил, что при вызове Tdialogservice.inputquery после закрытия формы выходит ошибка утечки памяти связанный с TWinAcceleratorKeyRegistry, с чем может быть связано?
пример кода:
TDialogService.InputQuery('Имя игрока',['Имя'],[PlayerNameText.Text], procedure (Const AResult: TModalResult; const AValues: array of string) begin if not AValues[0].Equals(PlayerNameText.Text) then begin Hero.NamePlayers := AValues[0]; end; end);
-
Добрый день.
Первое. Не работает свойство StartFromCurrentPosition. При любом значении берет то, что записано в StartValue.
Второе. Если объект динамически создать, удалить, а потом снова создать, то выскакивает ошибка не обнаружен файл
-
20 часов назад, GASCHE сказал:
Да столько объясняли и напрасно, видно плохие из нас советчики.
К сожалению я не увидел вашего объяснения, так что не пойму о чем речь.
-
-
20 минут назад, Rusland сказал:
Криво как-то рисует
Еще пока дорабатывается, проблема в скорости отрисовки, поэтому может не совсем точно быть в той точке которую мы хотим получить
-
Проект прикреплен к посту.
Код:
unit Unit1; interface uses System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants, FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.Controls.Presentation, FMX.StdCtrls, FMX.Objects, FMX.Edit; type TForm1 = class(TForm) Path1: TPath; Button1: TButton; Button2: TButton; Edit1: TEdit; Label1: TLabel; Edit2: TEdit; Label2: TLabel; Label3: TLabel; Edit3: TEdit; Label4: TLabel; Edit4: TEdit; Label5: TLabel; Label6: TLabel; Label7: TLabel; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); private { Private declarations } public { Public declarations } end; TAnimationPath = class(TThread) public private countflash: byte; tmpline: TLine; NowP,EndP: TPoint; Sender: TObject; duration: single; Step: TPoint; updateinterval: integer; { Private declarations } protected procedure Execute; override; constructor Create(StartPos,EndPos:TPoint;induration:single;inSender:TObject); procedure update; procedure flashanim; procedure flashcreate; procedure delassept; end; var Form1: TForm1; Assept: array of Integer; implementation {$R *.fmx} constructor TAnimationPath.Create(StartPos, EndPos: TPoint; induration: single; inSender: TObject); begin inherited Create(false); NowP := StartPos; EndP := EndPos; Sender := inSender; countflash := 5; duration := induration*1000; updateinterval := 50; Step := (EndP - NowP); Step.X := abs(Step.X * updateinterval); Step.Y := abs(Step.Y * updateinterval); Step.X := Trunc(Step.X / duration); Step.Y := Trunc(Step.Y / duration); tmpline := Tline.Create(nil); tmpline.Parent := TPath(sender); tmpline.Position.X := NowP.X; tmpline.Position.Y := NowP.Y; tmpline.Width := 1; tmpline.Height := 1; tmpline.Stroke := TPath(Sender).Stroke; end; procedure TAnimationPath.delassept; var I: integer; J: integer; L: TLine; begin I := Trunc(tmpline.Width)-1; J := Trunc(tmpline.Height)-1; Tpath(Sender).Data.Data := Tpath(Sender).Data.Data + ' M' + IntToStr(Trunc(tmpline.Position.X)) + ',' + IntToStr(Trunc(tmpline.Position.Y)) + ' L' + IntToStr(Trunc(tmpline.Position.X + I)) + ',' + IntToStr(Trunc(tmpline.Position.Y + J)); for I := TPath(Sender).ChildrenCount-1 downto 0 do if TPath(Sender).Children[I] is TLine then if (TLine(TPath(Sender).Children[I]) = tmpline) then begin L := TLine(TPath(Sender).Children[I]); TPath(Sender).RemoveObject(L); L.Free; Exit; end; end; procedure TAnimationPath.Execute; begin if (NowP.X <> EndP.X) and (NowP.Y <> EndP.Y) then tmpline.LineType := TLineType.Diagonal else begin if (NowP.X <> EndP.X) then tmpline.LineType := TLineType.Top; if (NowP.Y <> EndP.Y) then tmpline.LineType := TLineType.Left; end; try while (NowP.X <> EndP.X)or(NowP.Y <> EndP.Y) do begin Synchronize(Update); Synchronize(Flashcreate); Synchronize(flashanim); Sleep(updateinterval); end; while (tmpline.ChildrenCount > 0) do begin Synchronize(flashanim); Sleep(updateinterval); end; except end; Synchronize(delassept); end; procedure TAnimationPath.flashanim; var C: TCircle; I: integer; begin for I := Tmpline.ChildrenCount-1 Downto 0 do if tmpline.Children[I] is TCircle then begin C := TCircle(tmpline.Children[I]); C.Position.Point := C.Position.Point + C.Position.DefaultValue; if C.TagFloat / 10 < 1 then C.Opacity := C.TagFloat / 10; C.TagFloat := C.TagFloat - 1; if C.TagFloat < 0 then begin Tpath(Sender).RemoveObject(C); C.Free; end; end; end; procedure TAnimationPath.flashcreate; var I: Integer; C: TCircle; P: TPointF; begin for I := 0 to countflash do begin C := TCircle.Create(nil); C.Parent := tmpline; C.Width := 2 + Random * 4; C.Height := C.Width; C.fill.Color := TAlphaColors.Yellow; C.Stroke.Kind := TBrushKind.None; if NowP.X < EndP.X then P.X := tmpline.Width else P.X := 0; if NowP.Y < EndP.Y then P.Y := tmpline.Height else P.Y := 0; C.Position.Point := P; C.Position.DefaultValue := PointF(0.5 - Random,0.5 - Random).Normalize * (1 + random * 2); C.TagFloat := 10 + Random(15); C.Opacity := 1 - Random; end; end; procedure TAnimationPath.update; begin if (NowP.X < EndP.X) then begin if (NowP.X + Step.X > EndP.X) then begin tmpline.Width := tmpline.Width + EndP.X - NowP.X; NowP.X := EndP.X; end else begin NowP.X := NowP.X + Step.X; tmpline.Width := tmpline.Width + Step.X; end; end; if (NowP.Y < EndP.Y) then begin if (NowP.Y + Step.Y > EndP.Y) then begin NowP.Y := EndP.Y; tmpline.Height := tmpline.Height + EndP.Y - NowP.X; end else begin NowP.Y := NowP.Y + Step.Y; tmpline.Height := tmpline.Height + Step.Y; end; end; if (NowP.X > EndP.X) then begin if (NowP.X - Step.X < EndP.X) then begin NowP.X := EndP.X; tmpline.Position.X := tmpline.Position.X - (NowP.X - EndP.X); tmpline.Width := tmpline.Width + (NowP.X - EndP.X); end else begin NowP.X := NowP.X - Step.X; tmpline.Position.X := tmpline.Position.X - Step.X; tmpline.Width := tmpline.Width + Step.X; end; end; if (NowP.Y > EndP.Y) then begin if (NowP.Y - Step.Y < EndP.Y) then begin NowP.Y := EndP.Y; tmpline.Position.Y := tmpline.Position.Y - (NowP.Y - EndP.Y); tmpline.Height := tmpline.Height + (NowP.Y - EndP.Y); end else begin NowP.Y := NowP.Y - Step.Y; tmpline.Position.Y := tmpline.Position.Y - Step.Y; tmpline.Height := tmpline.Height + Step.Y; end; end; end; procedure TForm1.Button1Click(Sender: TObject); var TmpAnim: TAnimationPath; X,Y: Integer; begin TmpAnim := TAnimationPath.create(Point(0,0),Point(0,200),1,Path1); TmpAnim := TAnimationPath.create(Point(0,200),Point(400,200),2,Path1); TmpAnim := TAnimationPath.create(Point(400,200),Point(400,0),3,Path1); TmpAnim := TAnimationPath.create(Point(400,0),Point(0,0),4,Path1); end; procedure TForm1.Button2Click(Sender: TObject); begin Path1.Data.Clear; end; end.
-
Немного пояснения: требовалось анимировать объект Tpath (не путать с TpathAnimation!) - то есть анимировать отрисовку "сложных" объектов через SVG.
За отрисовку объектов отвечает свойство data.data, которое в виде строки хранит SVG код.
Первое мое решение как раз и было связано с постепенным изменением этого свойства, для плавного отображения, но я столкнулся с проблемой "быстрых" тормозов, собственно из-за чего и возникла эта тема.
Немного подумав, оказалось, что из постоянного дополнения этого свойства (data.data), оно очень быстро "переполнялось" и отрисовка занимала очень длительное время. Поэтому было решено использовать другой метод: вместо того чтобы постепенно изменять это свойство, мы создаем новый объект типа Tline и изменяя его размер как будто рисуем постепенно новую линию, а в конце уничтожаем ее, заменяя начало и конец добавлением в то самое свойство data.data тем самым экономя и память, и размер свойства.
Опять же, почему не использовать более простые методы? Во-первых требуется чтобы эта анимация могла происходит параллельно действиям всей программы. Во-вторых, таких анимаций одновременно может происходит довольно много.
Если кому интересно, выложу исходники
-
6 минут назад, Brovin Yaroslav сказал:
В принципе если напишите аниматор, можно его включить в FGX. Будет из коробки.
Звучит заманчиво)
-
3 минуты назад, Brovin Yaroslav сказал:
Скачайте пакет и посмотрите на TfgBitmapLinkAnimation, TfgPositionAnimation, TfgPosition3DAnimation (Модуль FGX.Animations). И обратите внимание, что все это не простые типы.
Спасибо, сейчас ознакомлюсь
-
8 минут назад, Brovin Yaroslav сказал:
Не делайте велосипед. Посмотрите в исходниках, как реализована анимация любого свойства. Можете взять из моих компонентов аниматоров FGX.
А где связь с анимацией любого свойства? ведь мы пытаемся анимировать не просто свойство opacity или width, а именно отрисовку TPath. И где можно найти аниматоры FGX?
-
4 минуты назад, krapotkin сказал:
1. все, что происходит с КОМПОНЕНТОМ, придется делать в ГП. Это заполнение св-ва Path
2. НО! все, что нужно предварительно рассчитать, не должно быть в ГП
Как вариант
procedure TMyThread.Execute; begin while not Terminated do begin ProcessCurrentState(); Synchronize(UpdateUserInterface); sleep(UpdateInterval); end; end;
при этом ПО-ЛЮБОМУ будет уходить время на UpdateUserInterface/ Линейно увеличиваясь с кол-вом компонентов
То есть использование synchromize не рентабельно, и лучше использовать заполнение в ГП? Тогда вопрос зачем он нам в потоке для UpdateUserInterface? Или этот метод в ГП?
Не совсем понимаю конструкцию while not Teminated. Получается мы бесконечно выполняем цикл?
-
4 минуты назад, krapotkin сказал:
нет
имеется в виду что Synchronize - это выполнение в главном потоке
если весь код вашего потока выполняется в главном потоке, то зачем заводить поток???
у меня аналогичная анимация Path происходит путем расчетов ключевых точек в дополнительном потоке, и только заполнение готового Path.Path происходит в главном
т.к. это всяко компонент и тут без ГП никак
Мне кажется я ответил выше, но все же поясню. Тут принцип тот же: задается ключевая точка и рисуется, проблема в том, что отдновременно их может рисоваться огромное количество на разных объектах и в то же время пользователь можето что то делать и поэтому я не понимаю как можно из главного потока это все сделать.
Поиск сервера
в DataSnap
Опубликовано
Да, именно так, только некоторые компоненты datasnap server не компилируются под андройд.
Для того, чтобы понятно было, что я хочу, прилагаю простой проект для примера с датаснапом.
В проекте сервер и клиент. Сервер достаточно запустить, а клиент по каждому нажатию "Получить id" эмулирует подключение нескольких клиентов, что приводит к вычислению некой суммы от каждого клиента.
А возвращаясь к задаче, хочется чтобы все вычисления были у клиента.
Проверка сервера.zip