воскресенье, 17 ноября 2013 г.

Пример использования DataSnap Callback: запрос данных во время вызова серверного метода

Что это и для чего надо:
Работа с Datasnap  заключается в запросе от сервера данных и вызове серверных методов, например:
 - Запросить список товаров с сервера (dataset )
 - Создать новый документ
 - Добавить в него позиции
 - Закрыть документ

Иногда при добавлении позиции необходимо сделать дополнительный выбор, например выбрать партию товара или разрез.

    Это можно сделать через возврат кода ошибки (что-то вроде Prepare/Execute), чтобы клиент запросил пользователя, а затем попробовал снова выполнить операцию.
    Или же дать серверу возможность запросить клиента непосредственно во время операции все необходимые ему данные.

Первый вариант требует перечня кодов ошибок с соответствующей обработкой.
Второй вариант требует зарегистрировать клиенту функции обратного вызова, которые может вызывать сервер, а также при каждом обращении к серверу иметь в виду, что в ответ сервер может что-то потребовать от клиента (а это грозит блокировкой, если запрос требует реакции от пользователя). Для того, чтобы не было блокировок при однопоточном пользовательском интерфейсе, обращения к серверу нужно делать в отдельном потоке - тогда пришедший от сервера вызов можно синхронизировать с основным потоком (который уже не ждет возврата управления от исходного вызова серверного метода). А также не забывать сообщать серверу ID клиента.

Вызов:
procedure TForm2.btnRegisterWareClick(Sender: TObject);
begin
  TThread.CreateAnonymousThread(
    procedure()
    begin
      clmClient.ServerMethods1Client.RegisterWare(seWareID.Value, clmClient.DSClientCallbackChannelManager1.ManagerId)
    end).Start;
end;

Сама функция обратного вызова:
  TmyCallback = class(TDBXCallback)
  protected
    FSelectedString: Integer;
    procedure SelectString(const Arg: TJSONValue);
  public
    function Execute(const Arg: TJSONValue): TJSONValue; override;
  end;

{ TmyCallback }

function TmyCallback.Execute(const Arg: TJSONValue): TJSONValue;
begin
  TThread.Synchronize(nil, procedure()  // запрос данных у пользователя - только в основном потоке
    begin
      SelectString(Arg);
    end);
  Result := TJSONNumber.Create(FSelectedString);
end;

procedure TmyCallback.SelectString(const Arg: TJSONValue);
var
  strs: TStringList;
  enum: TJSONPairEnumerator;
  val, str: string;
begin
  enum := TJSONObject(Arg).GetEnumerator;
  if Assigned(enum) then
  begin
    strs := TStringList.Create;
    try
      while enum.MoveNext do
      begin
        Val:= enum.Current.JsonString.Value;
        str := enum.Current.JsonValue.Value;
        strs.AddObject(str, TObject(val.ToInteger()));
      end;
      FSelectedString := TfrmSelectString.SelectString(strs);
    finally
      strs.Free;
    end;
  end;
  enum.Free;
end;

А вот что происходит на сервере:

procedure TServerMethods1.RegisterWare(ID: Integer; ClientID: string);
var
  Params, ParamsServ: TJSONObject;
  ResObj: TJSONValue;
  temp: TJSONValue;
begin
  ResObj := nil;
  Params := TJSONObject.Create;
  Params.AddPair(TJSONPair.Create('1', 'Размер 42'));
  Params.AddPair(TJSONPair.Create('2', 'Размер 43'));
  Params.AddPair(TJSONPair.Create('3', 'Размер 44'));
  ParamsServ := TJSONObject(Params.Clone);  //Делаем копию для себя, ибо ушедшую не вернуть
 ServerContainer1.DSServer1.NotifyCallback(ClientID, 'SelectString', Params, ResObj);
  if Assigned(ResObj) then
    begin
      temp := ParamsServ.GetValue(ResObj.Value);
      if Assigned(temp) then
        Form1.QueueLogMsg(Format('RegisterWare %d с разрезом %s', [ID, temp.ToString]))
      else
        Form1.QueueLogMsg(Format('RegisterWare %d без разреза', [ID]));
      ResObj.Free;
      ParamsServ.Free;
    end
  else
    Form1.QueueLogMsg(Format('RegisterWare %d без разреза', [ID]));
end;

И напоследок напоминание:
 - Локальные переменные процедур - не инициализируются
 - Всё, что вы передаете в функцию - можете попрощаться с ними и не освобождать
 - Всё, что вы получаете из функции - надо освободить (ведь тут ARC не работает (хотя, надо уточнить для мобилок))

С обратными вызовами можно делать что угодно - передавать в неё готовый набор данных или SQL-запрос, или имя справочника, из которого хранимая процедура вернет набор для выбора.

Код: https://github.com/VladimirSrednikh/datasnap-callback-with-ui

Так как пока с технологией жестко не определился, следующее изучение будет по TRealThinkClient

воскресенье, 10 ноября 2013 г.

Настроил себе точку доступа на D-Link DWA-125 при помощи утилиты Connectify.
Советы с поднятием SoftAP вручную провалились:
 - Динамически адрес подключенному смартфону не выдал => подключения не происходит.
 - при указании статического адреса соединение рвется непонятно почему.

P.S. Нет,  Connectify тоже не спасение. Время от времени смартфон отключался от свистка и переподключался на домашний роутер с Wi-Fi'ем.
Почему?

P.P.S. Запустил на работе - за 40 минут 20 переподключений. Очень плохо.

понедельник, 4 ноября 2013 г.

Пример дизайнера форм FMX

https://drive.google.com/file/d/0B-o0lV3HGn-JcWNUWHhNM3ZYVEk/edit?usp=sharing
Можно кидать на панельку контролы, двигать, изменять размеры.

Есть также дерево объектов, правда пока без редактирования.

суббота, 2 ноября 2013 г.

Oxygene под Андроид

Поставил триалку Оксигена
запустил простое приложение с одной кнопкой
Кнопка выглядит как простой прямоугольник.

четверг, 31 октября 2013 г.

Xamarin

Решил попробовать сделать приложение под Андроид в Xamarin.
Открыл AndroidManifest.xml, поменял Target android Version
и не получается сохранить
Проверил ProcMon'ом - никто не держит файл, никаких отлупов.
Но сохранить не может :-)

Upd. Что-то где-то переключил - увидел ругань на несовпадение переводов строк  (исходно были МАКовские).
Разрешил поменять на виндовые - сохранил :)

вторник, 29 октября 2013 г.

Прототип

Делать прототип я начал с Mobile App под платформу Win32, т.к. по сути на планшет будет то же самое - никаких платформо-зависимых вызовов, только дергать сервер получать/отправлять данные.

Сервер пришлось помучать, чтобы заставить обычное VCL-приложение заработать в неосновном потоке (благо всякие окошки удалось отключить)
Заработало.

Начал собирать под Андроид - пришлось довыпиливать из интерфейсных модулей использование VCL-контролов, а также IBX.
Потом долго пытался бороться с 

[DCC Hint] H2596 C:\Users\Public\Documents\RAD Studio\12.0\PlatformSDKs\android-ndk-r8e\toolchains\arm-linux-androideabi-4.6\prebuilt\windows\bin\arm-linux-androideabi-ld.exe: warning: cannot scan executable section 29 of c:\\program files (x86)\\embarcadero\\rad studio\\12.0\\lib\\Android\\Release/libmidas.a(alchemy.o) for Cortex-A8 erratum because it has no mapping symbols.
пока наконец не понял, что это "всего лишь" Hint а не Error.

Сделал прототип, стал показывать.
Оказалось, что мой wi-fi dongle неустойчиво держит связь,
Т.к. сервер у меня Stateful, помогла смена для серверных объектов LifeCycle на 'Session' (прототип сервера на большее и не допилен).

Теперь остается ждать согласования проекта, написания обоснования, наполнения его требованиями, изыскательские работы по ограничениям.

Ну и обратные вызовы я так и не попробовал.

О стиле

FireMonkey - это реализация идеи Model-View-Controller
Контрол  - это Model
Стиль - это View
Поэтому использование FireMonkey требует стилей.
Без них выглядит неважно.
И даже нельзя задать некоторые свойства (например, высоту TEdit, или TabHeight для TabControl'а) если нет стиля. Эти свойства, как правило, влияют на отображение контрола, а не на поведение (ReadOnly, Visible)

воскресенье, 27 октября 2013 г.

Delphi XE5, Android & Datasnap

В последнее время вижу много статей про Datasnap
Это вполне объяснимо ставшей доступной возможностью создавать приложения для Андроида в Дельфи.

В моей компании я предложил портировать приложение (кассовая программа) на Андроид.
Как это можно сделать: на Андроиде тонкий клиент, на сервере существующая программа, допиленная до возможности управления не с клавиатуры/мышки, а с удаленного устройства.
Проще всего это сделать при помощи DataSnap.
Можно передавать наборы данных, можно вызывать функции сервера.
Что еще надо?
Только нарисовать "мордочку" под планшет, да переделать сервер, чем я сейчас и занимаюсь.
На следующей неделе планирую показать руководству действующий прототип с созданием документа, добавлением позиций, оплатой и закрытием.
После чего инициатива перейдет к продакт-менеджерам для формулирования хотелок и планированию релиза.

Что удобно - в таком варианте изменение функционала будет добавляться/меняться прозрачно как для стационарной, так и для мобильной версии, ибо кодовая база едина.

В моем случае, правда, на мобильном клиенте из базы будут использоваться разве что типы данных и константы (посмотрим, что там с новой архитектурой FM)

пятница, 18 октября 2013 г.

Обжалование решения "судьи" Блинова

Смотрю запись трансляции. Суд начал читать какую-то бумагу (?) в 10:30
12:23 трансляции:
"Навальный и его пособник Офицеров в начале 2009 года решили похитить имущество Кировлеса. В начале 2009г Н. и О. изучили деятельность Кировлеса и поставили его в известность о том. что его продукция будет реализовываться через посредника. получив согласие(!) Опалева (директор Кировлеса), О. для создания видимости гражданско-правовых обязательств зарегистрировал ООО, подготовил и подписал договор поставки, не имеющий экономического смысла(!!!)" (13:30)

Все.
За одну минуту Кировский областной суд заявил, что перепродажа для него является экономической бессмыслицей, и посредническая наценка - не более чем фикция.

четверг, 17 октября 2013 г.

Как сделать из Wi-FI "Свистка" точку доступа

Купил сегодня D-Link DWA-125. При помощи данного совета настроил себе точку доступа:
http://4pda.ru/forum/index.php?showtopic=175743&st=2120#entry10287735
с правами администратора и выполняем в ней следующую команду:

- netsh wlan set hostednetwork mode=allow ssid="MS Virtual Wi-Fi" key="Pass for virtual wifi" keyUsage=persistent

В данном примере "MS Virtual Wi-Fi" – имя беспроводной сети, "Pass for virtual
wifi
"-пароль для доступа к этой сети. Вы можете задать данные значения по
своему усмотрению.

После выполнения данной команды, система найдет новое оборудование и в
диспетчере устройств появится новый сетевой адаптер,
а точнее виртуальный – Адаптер мини-порта виртуального WiFi Microsoft
(Microsoft Virtual WiFi miniport adapter). Но опять же, данный виртуальный
адаптер появится только в том случаи, если у нас драйвер беспроводного адаптера
имеет поддержку Virtual WiFi.
Перейдя в Панель управления – Центр управления сетями и общим доступом –
изменение параметров адаптера, увидим новое соединение
Wireless Network Connection 2, которое будет показывать статус – нет подключения.
Поэтому следующим этапом будет запуск сети. Для этого необходимо в командной
сроке, запущенной с правами администратора, выполнить команду:
- netsh wlan start hostednetwork.

После этого сеть запустится и заработает программная точка доступа (SoftAP).
В этом можно убедиться перейдя в Панель управления – Центр управления сетями и
общим доступом. Так как у нас используется подключение к интернету по Wi-Fi, мы
обнаружили, что Windows 7 подключена одновременно к нескольким беспроводным
сетям. Теперь другие беспроводные устройства могут подключаться к нашей точке
доступа.

примечание: Сам DWA-125 не очень удобный, так как слишком громоздкий, и соседние порты будут заблокированы его тушкой.
И еще - очень нестабильная связь у меня получилась (проверял на Samsung Galaxy S4)

P.S. кажется победил отваливание доступа - надо убрать с настроек адаптера все лишние протоколы , например TCP/IP v6, Microsoft Network, файлы и принтеры и всякие прочие антивирусы и файерволы.
Правда пока поставил себе Connectify, попробую на работе без неё, будет ли держаться связь.

пятница, 6 сентября 2013 г.

https://itunes.apple.com/jp/app/delta-view/id671491538
за месяц сделали, еще два доводили до окончательного релиза.
На основе Windows-версии.

четверг, 16 мая 2013 г.

Суровая мужская дружба на Хабре


naum, #
Давай обнимемся, бро, я знаю, что ты чувствуешь. Мне FM неприятен, ничего не могу с собой поделать. Видя как это сделано в других кроссплатформенных фреймворках, вспоминая приятности VCL и удивляясь расхлябанности его визуальной составляющей в купе с жутким падением производительности — мне становится грустно. Садиться за FM сейчас — с одной стороны нужно, с другой крайне неприятно. Для себя отметил одну особенность — начинаю использовать околодельфовую технологию только тогда, когда ее запускает в продакшен 3-4 крупных и любимых мною компонент-вендора.



SegaZero, #
Я для себя решил, что для мак-разработок и iOS я лучше буду использовать xcode и objectiveC. Да, язык непривычный (но простой), среда весьма далека от делфи, но зато там всё вылизано под платформу в результирующем бинарнике.
FM буду юзать только тогда, когда он перестанет падать в среде хотя бы, сейчас это нельзя пользовать. Я уж молчу про конкретные проседания на простых казалось бы layouts. Особенно грустно становится, когда смотришь в код и видишь цикл отрисовки всех слоёв без проверки на перекрытие и видимость…
Грусть и печаль.


naum, #
 
Выходи за меня.

среда, 20 февраля 2013 г.

То, что у вас не работает, у меня замечательно стоит.

понедельник, 4 февраля 2013 г.

Доносительство как образ жизни

Послушал передачу с Ириной Прохоровой (сабж)
http://rbctv.rbc.ru/archive/sistema/562949985241277.shtml ч1
http://rbctv.rbc.ru/archive/sistema/562949985241362.shtml ч2

Очень удивительно, как люди обсуждают, но более удивительно было слушать саму Ирину.
Казалось бы, она понимает важность вкладываемых значений в слова, и все-таки пользуется штампами.

И тот факт, что доносительство в том, презираемом смысле, существует в обществе, где вести себя естественно - это противозаконно - даже не обсуждался.