#delphi #callback #datasnap #podo
#delphi #обратный вызов #datasnap #podo
Вопрос:
Я снова нахожусь в ситуации, когда я трачу неприличное количество времени на попытки настроить образцы обратного вызова datasnap в соответствии со своими потребностями. Я ООП-программист старой школы, и у меня есть несколько очень больших иерархий объектов в стиле PODO «toolbox» 🙂 .. и, имея эту замечательную функцию datasnap, я хочу использовать возможности обратного вызова.
НО — когда я это реализую… это просто сбой… (FASTMM4 сообщает об утечках памяти).
Попробуйте создать простой сервер VCL datasnap — TCP. И добавьте кнопку и этот источник …
procedure TForm1.Button1Click(Sender: TObject);
var
// AObject : TObject;
aJSONVal : TJSONValue;
begin
// AObject := TObject.Create;
// ServerContainer1.DSServer1.BroadcastObject('SomeChannel','SomeCallbackID', AObject);
// AObject.Free;
aJSONVal := TJSONObject.Create;
ServerContainer1.DSServer1.BroadcastMessage('SomeChannel','SomeCallbackID',aJSONVal);
// aJSONVal.Free; // Mat pointed out that this is done by the broadcast.
end;
Это будет работать — до тех пор, пока вы продолжаете использовать TJSONValue …
Но попробуйте переключить прокомментированный код — и вы поймете, что я имею в виду.
Я мог бы, конечно, изменить весь мой существующий код на JSON… но это просто неприемлемо.
Есть ли у кого-нибудь идеи о том, как использовать BroadcastOBJECT или NotifyOBJECT?
С уважением, Бьярне
Комментарии:
1. @Bimmer_R- Предложение: пожалуйста, объясните нам, как происходит сбой — что происходит? Какое исключение вызывает Delphi? Какое сообщение об ошибке вы получаете? Я не думаю, что вы получите много ответов, просто сказав нам «это просто сбой» и попросив нас пойти и создать сервер datasnap и выяснить, что происходит, а что нет.
2. @Mikey … Извините .. конечно, я должен предоставить всю необходимую информацию. Когда я говорю «сбой» — это означает нарушение доступа .. или, как я указал. Fastmm4 сообщает об утечках памяти. Для создания серверного приложения datasnap. на самом деле вам нужно так мало шагов / кликов, что это почти так же быстро, как запуск нового приложения vcl forms 🙂 Вот отличный пример того, как настроить сервер datasnap и использовать обратный вызов. edn.embarcadero.com/article/41374 Единственное отличие, как я вижу, заключается в том, что Im вещает с сервера… но это действительно не должно быть проблемой .. или это так?
Ответ №1:
Объект, который вы передаете вызову Notify или Broadcast, затем принадлежит этому вызову. Поэтому не вызывайте «AObject.Free;» или «aJSONVal.Бесплатно;». Это часто приводит к нарушению доступа или другим проблемам, связанным с управлением памятью.
Обратите также внимание, что широковещательные сообщения помещаются в очередь на сервере и позже отправляются в другом потоке. Это означает, что когда ваш вызов возвращается к широковещательной передаче, он фактически еще не отправил сообщение всем клиентам.
Я надеюсь, что это поможет,
Мат
Комментарии:
1. Привет, мат. Спасибо за ваш интерес к этому. Я модифицировал демонстрационную программу CallbackChannels — и разместил ее на megaupload (не знал, как обмениваться файлами через SO — если это возможно). megaupload.com/?d=BL0SZC98 Помните — выполнение широковещательного обратного вызова для callbackid … все равно не сработает. Но трансляция на канал — это нормально. И notifyobject для callbackid / clientid также в порядке. Я надеюсь, вы найдете демонстрационную версию полезной.
Ответ №2:
Возможный ответ: Ваш вопрос был расплывчатым, но, основываясь на том, что вы сказали, я бы начал с этого:
Справка по Delphi XE: (ms-help://embarcadero.rs_xe/vcl/DSServer.TDSServer.BroadcastObject.html ):
функция BroadcastObject (const ChannelName: строка; const CallbackId: строка; const Msg: TObject): логическое значение; перегрузка;
Вторая перегрузка отправляет объект всем обратным вызовам клиента с заданным зарегистрированным идентификатором обратного вызова. Для этой цели в вызове требуется дополнительный параметр CallbackId.»
Вы используете вторую перегрузку, которая принимает 3 параметра — правильно ли настроены ваши идентификаторы обратного вызова?
Комментарии:
1. Привет, Майки. Вы правы — для каждого из широковещательных методов существует две перегрузки. Но, поскольку я прочитал «инструкции» .. трансляция не нуждается в какой-либо «настройке». Вы можете транслировать что угодно — в любое время, когда захотите. Если никто не слушает, то это не имеет значения. И с 4 возможными трансляциями — я могу заставить работать только одну. Все остальные завершаются неудачей из-за нарушения доступа или утечки памяти.
2. @Bimmer_R: Я бы не назвал ошибки утечки mem как таковые. Но AV-файлы — они генерируются на стороне клиента или сервера? Как настроено ваше развертывание? У вас есть клиенты на удаленных машинах или все локально? Можете ли вы проследить весь путь выполнения до AV? Какую версию Delphi вы используете? Включен ли у вас в IDE параметр ‘break on Delphi language expections’? Как я уверен, вы знаете, AV часто маскирует реальную проблему. Если исключение генерируется на удаленном клиенте, оно может отображаться как AV от серверного вызова, который маскирует фактическое исключение на стороне клиента. Пожалуйста, — подробности! HTH
3. @Bimmer_R — и я так понимаю, что когда вы говорите «это просто сбой», вы имеете в виду, что иногда вообще НИЧЕГО не происходит, за исключением того, что вы видите сообщение об утечке, верно? «Я могу заставить работать только один. Все остальные завершаются сбоем из-за нарушения доступа или утечки памяти » — чем отличается тот, который работает? Это может привести вас к вашему ответу.
4. @Mikey. Еще раз привет — теперь у меня кое-что работает. И я хотел бы поделиться своими знаниями. Выполнение BroadCastObject для канала (всех обратных вызовов / клиентов) довольно просто. И, по-видимому, то же самое относится к NotifyObject (определенному каналу, обратному вызову, клиенту). Где я терплю неудачу, это BroadCastObject для определенного обратного вызова. По какой-то причине это не сработает. Я модифицировал демонстрационную программу embacadero CallBackChannels и отправил ее по почте Павлу Гловацки, с которым я только что посетил двухдневный семинар по этой области. Дайте мне знать, если кто-нибудь захочет получить модифицированную версию ChannelCallbackDemo.
5. @Bimmer_R — Спасибо за согласие — я на самом деле ничего не ответил, но, полагаю, я двигался в правильном направлении? Теперь эта модифицированная версия делает то, что вам нужно? Если это так, я хотел бы это увидеть — сейчас эта функция не используется, но она очень мощная, и хотелось бы знать, как ее правильно использовать при необходимости. Спасибо