DataSnap ограничивает входящий запрос до 16 КБ

Я создал сервер DataSnap с Delphi XE2, который реализует TDSHTTPService. Когда приходит входящий запрос, TIdIOHandler.InitComponent вызывается в потоке до того, как выполнение будет передано методу, вызванному в TServerMethods. У меня нет компонентов Indy на сервере, поэтому DataSnap использует Indy 10 под капотом.

.InitComponent() задает для максимальной длины строки обработчика ввода-вывода жестко запрограммированное значение (FMaxLineLength := IdMaxLineLengthDefault;), равное 16384. Я не могу найти способ увеличить значение. Я даже пытался скопировать IdIOHandler Unit в папку проекта и изменить постоянное значение. Но он по-прежнему подбирает IdIOHandler.dcu из сборки Indy 10 и игнорирует скопированный файл в папке моего проекта. Я также пытался добавить компонент TIdIOHandlerStream в серверный проект и установить его MaxLineLength безрезультатно.

  • План A = Правильно установите значение MaxLineLength на сервере DataSnap.
  • План Б = Каким-то образом скомпилировать модифицированный файл IdIOHandler.pas в мой проект.

Возможны ли какие-либо из них? Я работаю над этим часами и не могу найти ничего похожего во всех своих поисках, и, похоже, не могу добиться каких-либо успехов, экспериментируя.


person James L.    schedule 05.09.2012    source источник
comment
Очень странно, сущность HTTP представляет собой произвольную последовательность октетов — может быть, разработчики Indy думали только о данных HTML? В объекте HTML нет строк. Вы можете попробовать полностью удалить Indy из Delphi и установить модифицированную сборку из доступного исходного кода. В любом случае, весь стек Datasnap — это куча плохо спроектированных библиотек, я бы поискал лучшие решения для удаленного взаимодействия.   -  person Mad Hatter    schedule 06.09.2012
comment
Есть две настройки: максимальная длина строки и необходимость разделения запроса при превышении максимальной длины или возбуждение исключения. По умолчанию 16 384, и возникает исключение. Оба эти параметра легко установить для исходящих запросов со стороны клиента. Я не вижу возможности установить их для входящих запросов к серверу DataSnap на стороне сервера.   -  person James L.    schedule 06.09.2012


Ответы (2)


Перекомпилировав все пакеты Indy в Delphi XE3, изменив константу IdMaxLineLengthDefault на 512*1024 и заработав после этого как положено, я начал искать самое простое решение этой проблемы. Итак, я обнаружил, что это простой обходной путь для этого ограничения.

Вы можете реализовать процедуру для события OnContextCreated объекта TIdHTTPWebBrokerBridge, используемого в основном блоке проекта DataSnap REST Server. В этом случае принимается объект AContext, который создается для каждого запроса к серверу DataSnap. Итак, в коде этой процедуры вам просто нужно переопределить значение по умолчанию для этого свойства следующим образом:

procedure TForm1.FormCreate(Sender: TObject);
begin
  FServer := TIdHTTPWebBrokerBridge.Create(Self);

  {Here you assign the new procedure for this event}
  FServer.OnContextCreated:= OnContextCreated; 
end;

procedure TForm1.OnContextCreated(AContext: TIdContext);
begin
   AContext.Connection.IOHandler.MaxLineLength:= 512*1024 {or whatever value you need);
end;
person David O.    schedule 25.07.2013

Если не считать удаления установки Delphi XE2 Indy 10 и загрузки исходного кода, настройки постоянных значений и компиляции/поддержки моей собственной сборки навсегда в будущем..., я решаю проблему.

Я создал дополнительный метод на сервере DataSnap, чтобы я мог создать запись в базе данных с вызовом первого метода, а затем поэтапно передать остальные данные, передавая их второму методу по 16 КБ за раз — буферизация на сервере DataSnap, пока не будут получены все части. Затем я обновляю запись в базе данных полностью буферизованным значением с сервера DataSnap.

Возможно, это не самое эффективное решение, но оно работает и будет масштабироваться по мере необходимости.

person James L.    schedule 07.09.2012