Створення автономної web-служби в delphi 7 за допомогою комплекту indy

З цього повідомлення можна зробити висновок, що з'єднання TSoapConnection завжди отримує інтерфейс IAppServer з модуля TSoapDataModule незалежно від назви інтерфейсу, заданого для даного покажчика URL. Спочатку відсилання здійснюється за допомогою операцій SOAPAction, але в разі невдачі, врешті-решт, буде використовуватися покажчик URL. Інтерфейс IAppServer завжди посилається назад додатку-клієнта, а конструктором цього інтерфейсу є перший зареєстрований модуль даних (швидше за все, це відбувається через те, що переміщення SDM-модуля в Delphi-проект раніше за інших модулів призводить до зміни постачальника послуг).

Рекомендується спробувати відтворити описану вище ситуацію, перш ніж переходити до розглянутого нижче рішенням. Це допоможе ознайомитися з іншими корисними технічними прийомами.

По-перше, необхідно стандартним чином створити нову Web-сервісів з системи DataSnap (File-> New-> Other, WebServices, а потім вибрати SOAP Server Application). SOAP-додаток буде створено як файл, що виконується сервером Web App Debugger, з ім'ям класу (Class Name) TheThreeSDMs. В даний момент не потрібно створювати ніякого додаткового інтерфейсу.

Тепер, коли є каркас SOAP-сервера, потрібно додати три модулі даних SOAP Data Module. У даній статті вони названі SDM1, SDM2 і SDM3. Для кожного модуля даних потрібно задати параметр, що визначає постачальника послуг. Далі будуть використані три набори даних ClientDataSets, а також будуть завантажені деякі дані з бази прикладів MyBase і додані деякі компоненти TDataSetProviders. Тепер є діючий SOAP-сервер і потрібно запустити даний проект, принаймні, один раз, щоб зареєструвати його на сервері WebApp Debugger. Після цього слід звернути увагу на мову WSDL, генерований для даної служби.

Час прогону, період проектування ... Робота ніколи не йде так, як хотілося б. А хотілося б просто використовувати покажчик URL, а не конструктор інтерфейсу IappServer. Як же досягти цього? Щоб відповісти на це питання важливо розуміти суть самої проблеми. Слід звернути увагу на те, що в Delphi 7 існує властивість SOAPServerIID для з'єднання TSoapConnection. Для нього завжди встановлено значення "IAppServerSOAP -". Це значення можна змінити, але тоді для властивості Connected не можна встановити значення True (це можна зробити, якщо задати значення False для параметра UseSOAPAdapter, але це призводить до виклику інтерфейсу IAppServer замість IAppServerSOAP, нового інтерфейсу, введеного в Delphi 6). Заглянувши в модуль SOAPConn, можна помітити, що, швидше за все, не відбувається створення основного RIO-компонента. У той же час, якщо подивитися на демонстраційну версію модуля SOAPDataModule можна побачити, що існує можливість зміни властивості SOAPServerIID. Однак в цьому випадку необхідно мати можливість імпортування мови WSDL з сервера і, крім того, це призводить до втрати низки можливостей в період проектування.

Пропоноване рішення засноване на розумінні того, як з'єднання TSoapConnection отримує інформацію в залежності від інтерфейсу модуля SOAP-даних. На серверній стороні інтерфейс зазвичай реєструється за допомогою модуля InvokeRegistry. Під час імпорту мови WSDL, як і в демонстраційній версії, він реєструє себе в додатку-клієнті теж за допомогою модуля InvokeRegistry. Це необхідно для того, щоб під час прогону з'єднання TSoapConnection могло знайти правильний інтерфейс для обслуговування звернень до даної службі (в разі демонстраційної версії це інтерфейс IDataMod). Однак це призводить до втрати деяких можливостей в період проектування. Далі буде розглянуто, як подолати цю проблему, яка, схоже, є єдиною перешкодою на шляху досягнення мети цієї статті. Якщо добре подумати, ця проблема не так вже й складна. Інтегроване середовище розробки нічого не знає про те, як викликати розділи ініціалізації модулів поточного проекту, так що в період проектування в модулі InvokeRegistry інтерфейси відсутні. Рішенням проблеми є створення для періоду проектування спеціального пакету з модулем, що містить інтерфейси-нащадки (такі як ISDM2).

Знову відкрийте проект сервера і додайте новий модуль під назвою uTheThreeSDMsIntf. Спочатку потрібно об'єднати всі SDM-інтерфейси сервера в цей модуль і задати оператор uses clause кожного SDM-модуля для використання нового модуля інтерфейсів. Крім того, звернення до служби повинно бути передано функції InvRegistry.RegisterInterface () для виклику розділу ініціалізації нового модуля. Нижче наведено відповідний програмний код для модуля uTheThreeSDMsIntf.