Sapunul este usor

Destul de ciudat, SOAP-ul este într-adevăr simplu, deși când am început să lucrez cu el pe tehnologia Delphi, SOAP (tehnologia de lansare a obiectelor transfrontaliere pe mai multe platforme). nu putea să-și dea seama de ce parte să se apropie de el. De fapt, proiectarea de aplicatii SOAP, trebuie să îndeplinească condițiile destul de un pic, și apoi totul va funcționa bine, iar aceste condiții simple și voi încerca să abordeze aici.







În primul rând, de ce este necesar acest SOAP? Există două avantaje principale: SOAP este un standard public de comunicare interprogram și clientul nu are nevoie să știe nimic despre server - nici despre limba sa, nici despre platformă; Interfețele SOAP sunt auto-documentare, adică serverul trebuie să furnizeze clientului o descriere detaliată a interfeței, a funcțiilor sale, a parametrilor de intrare și ieșire.

Condiția principală pentru programarea SOAP: serverul trebuie să fie apatrid. și anume rezultatul interogării nu trebuie să depindă de comenzile anterioare primite de server. Aceasta înseamnă că toți parametrii sesiunilor trebuie să fie stocați pe client și să fie trimiși serverului ca parte a solicitării (dacă este necesar). Acest lucru asigură o stabilitate ridicată și o scalabilitate a sistemului (clientul poate fi comutat la un alt server fără să-l realizeze), deși o serie de deliciosități ale sistemului obișnuit cu două legături devin indisponibile:

  • Nu puteți gestiona în mod explicit tranzacțiile de la client (acesta este serverul),
  • prin urmare, nu puteți bloca înregistrarea pentru timpul de editare (cu excepția cazului în care faceți flag-uri speciale în baza de date)
  • Este imposibil ca parametrii să fie transferați de o comandă, iar altul să ia în considerare rezultatul - totul ar trebui să se întâmple în cadrul aceleiași comenzi
  • Nu puteți lucra cu banda clasică a părții principale (cu toate acestea, TClientDataset oferă un instrument excelent pentru acest lucru: seturi de date imbricate - tabele imbricate),
  • Nu puteți utiliza proprietatea ClientDataSet.PacketRecords> 0. serverul "nu-și amintește" ce a trimis deja clientului și ce nu - o astfel de funcționalitate trebuie implementată utilizând parametri suplimentare de interogare,
  • . dacă am uitat ceva, o să termin mai târziu.

Aplicație simplă SOAP

Exemple similare sunt luate în considerare în orice literatură dedicată dezvoltării SOAP pe Delphi.
Rulați Delphi și selectați File | Nou | Altele. . accesați fila WebServices și selectați aplicația SoapServer.

Veți fi oferit o gamă de 5 opțiuni:

  • ISAPI / NSAPI Dinamic Link Libarry este o bibliotecă plug-in pentru serverele IIS / Netscape. fiecare cerere este transmisă ca o structură și procesată de un fir separat.
  • CGI Stand-alone Executable - aplicație consola, primește o cerere pentru o intrare standard, returnează un răspuns la ieșirea standard, fiecare cerere este procesată de o instanță de aplicație separată,
  • Win-CGI Stand-alone Executable este o aplicație Windows. schimbul de date are loc prin fișierul INI (nu este recomandat pentru utilizare, este depășit);
  • Apache Modul partajat (DLL) - o bibliotecă plug-in pentru serverul Apache. fiecare cerere este transmisă ca o structură și procesată de un fir separat,
  • WebAppDebugger Executable - o bibliotecă plug-in pentru serverul de depanare furnizat împreună cu Delphi. deoarece WebAppDebugger este, de asemenea, un server COM, trebuie să specificați (arbitrar) numele CoClass pentru obiectul COM care va fi folosit pentru a apela modulul dvs. web.

Selectați executabilul stand-alone CGI. ca cel mai ușor pentru depanarea format, atunci aplicația poate fi ușor convertită în orice altul. Trucul este că, dacă toate logica aplicației este concentrată în module scrise de tine, pur și simplu creați o nouă aplicație de tipul necesar, conectați la Nimu modulele lor, și funcționează!

După ce faceți clic pe OK, va fi generată o nouă aplicație care conține un WebModule cu trei componente:

  • THTTPSoapDispatcher - primește pachetele SOAP primite și le transmite către componenta definită de proprietatea Dispecer (de obicei THTTPSoapPascalInvoker),
  • THTTPSoapPascalInvoker - primește o cerere SOAP de intrare, găsește metoda invocată în Registrul de invocare, o invocă, generează un răspuns și o trimite înapoi la THTTPSoapDispatcher.
  • TWSDLHTMLPublish - generează WSDL (W eb Services D escription L anguage), o descriere a datelor și interfețelor suportate de modulul dumneavoastră.

Salvați aplicația creată, acesta va fi scheletul serverului nostru.

Strangeness: mai târziu am observat că WebModule. create pentru WebAppDebugger. ușor diferită de alte opțiuni de aplicare

În ceea ce afaceri de aici nu am înțeles, dar fără ei aplicarea în WebAppDebugger th nu funcționează.

Îl vom umple cu logică. Deoarece serverul și clientul vor trebui să descrie structurile datelor și interfețelor transmise, este mai bine să le punem într-un modul separat, iar implementarea întregului server în altul. Pentru a face acest lucru, creați două module (File | New | Unit) și salvați unul dintre acestea sub numele CentimeterInchIntf.pas. și altul - CentimeterInchImpl.pas. În interiorul CentimeterInchIntf.pas tastați următoarele:

Așa că am definit interfața ICmInch. Acesta oferă două funcții: conversia centimetrilor în inci și inci în centimetri și înregistrarea în InvokeRegistry.

Să abordăm implementarea. În CentimeterInchImpl.pas, definim descendentul TInvokableClass. care implementează interfața noastră ICmInch.

După cum puteți vedea, în TCmInch am implementat ambele funcții ale interfeței ICmInch. și, de asemenea, am înregistrat noua clasă invocabilă în InvokeRegistry (în general, tot ceea ce va fi transmis prin rețea trebuie înregistrat în acesta, cu excepția tipurilor scalare).

Creați o nouă aplicație (de tip obișnuit), specificați în secțiunea noastră de utilizare modulul de interfață CentimeterInchIntf. Plasați cele două butoane, două câmpuri de introducere și componenta THTTPRIO din paleta WebServices din formularul principal.

Acum, după compilarea și rularea aplicației, puteți converti centimetri în centimetri și invers.

Î: Și dacă serverul SOAP este scris de altcineva și nu avem un modul de interfață?






R: Apoi trebuie să utilizați importatorul de servicii web. care se află în fișierul | Nou | Altele. . în fila WebServices. Acest expert va genera un modul de interfață pentru serviciul WSDL.

Transmiterea tipurilor complexe

componenta noastră THTTPSOAPPascalInvoker știe deja cum de a transmite tipuri scalare și matrice dinamice (acestea din urmă trebuie să fie pre-înregistrate în InvokeRegistry. cm. de mai jos), dar pentru transportul de tipuri de complexe, cum ar fi matrice statică. interfață. înregistrare. set sau clasă. mai întâi trebuie să le descrieți ca descendenți ai clasei TRemotable. care are informații de tip RunTime (RTTI). De exemplu, dacă dorim să declarăm o clasă care returnează rata monedei și numele său, modul nostru de interfață va arăta astfel:

Aici am declarat, de asemenea, matricea dinamică TCurrencyArray. în cazul în care doriți să îl transferați (rețineți diferența dintre comenzile de înregistrare ale clasei și matricei).
De fapt, sintaxa completă a comenzii de înregistrare a clasei este ceva mai largă, cei care doresc pot citi despre aceasta în documentația pentru Delphi.

Notă: dacă există un tip care este scalar în documentul WSDL, dar nu are o potrivire directă în Object Pascal (de exemplu, DateTime), atunci TRemotableXS ar trebui să fie utilizat ca clasă de bază. care declară două metode XSToNative și NativeToXS pentru conversia unei reprezentări șir la Object Pascal și înapoi (aceste metode trebuie, bineînțeles, implementate).
Delphi include modulul XSBuiltIns. în care sunt deja implementate multe funcții utile (cu toate acestea, în versiunea 6.0 au existat erori în procesarea datei, dacă setările naționale din sistem nu erau engleze).

Există o întrebare interesantă cu crearea-distrugerea obiectelor transmise ca parametri. Iată ce spune documentația TRemotable despre el:
"Pe partea de server, descendenții TREMotabili, care sunt parametri de intrare, sunt creați automat atunci când unmarshaling apelul metodă și sunt distruse automat după pachetul marshal al parametrilor de ieșire pentru transmiterea către client.
Descendenți ai lui Tremotabil. Creat într-o metodă numită printr-o interfață invocabilă. sunt șterse automat după ce valoarea lor este împachetată (marshal) pentru a fi transmisă clientului.
Un client invocând o interfață invocabilă. este responsabil pentru crearea obiectelor folosite ca parametri de intrare și pentru distrugerea tuturor descendenților care se pot deplasa. pe care a creat-o, precum și metoda rezultată. "

Transfer de date

Aici totul este simplu. Fiind în proiectul Application Server Server. selectați Fișier | Nou | Altele. . accesați fila WebServices și selectați modulul de date SoapServer. Dezvoltarea în continuare nu este diferită de aplicarea convențională MIDAS, cu două caracteristici: serverul trebuie să fie apatrid - primit solicitarea, am spus uitat (de exemplu, modulul CGI literalmente după fiecare apel este finalizată), și să nu aibă mai mult de un SoapDataModule.
Plasați componentele de acces la date pe modulul rezultat (de exemplu, TClientDataset), setați toate proprietățile necesare pentru lucrare. Plasați TDataSetProvider. conectați-l la componenta de acces la date.

Compilați aplicația și puneți-o unde poate fi rulată de serverul Web (din anumite motive nu am putut rula sub WebAppDebugger, probabil că am folosit WebModule greșit.

În aplicația client, plasați TSoapConnection și TClientDataset pe formular. în SoapConnection.URL specificați calea spre interfața serverului dvs.:

puteți utiliza o interfață specifică SoapDataModule. și este posibil și mai general - IAppServer. La punctul TClientDataset.RemoteServer la TSoapConnection. Acum, prin setarea TClientDataset.Active:=true. vom primi datele noastre despre client.

Dacă aveți nevoie de anumiți parametri pentru a deschide un set de date pe server, este convenabil să utilizați interogarea DataRequest în loc de Active: = true (Vă reamintesc că pentru aplicațiile SOAP toți parametrii ar trebui trimise ca parte a unei singure cereri, și apoi să solicităm date, deoarece, cu o mare probabilitate, a doua cerere va merge la o altă instanță a serverului). Arată așa.
Pe client.

și anume serverul poate transfera orice date (tipul transmis este OleVariant) și poate prelua din nou datele de orice tip, de exemplu pachetul de date. ca în cazul de mai sus.

Dacă ați modificat datele de pe client și doriți să le salvați pe server, există mai multe moduri de a face acest lucru. Cel mai simplu - instalat TDataSetProvider.ResolveToDataSet: = false și pot provoca TClientDataset ApplyUpdates metoda. Cererile de actualizare pot fi generate de TDataSetProvider în sine. și controlul (destul de slab, cu toate acestea) pentru formarea acestor interogări pot fi efectuate folosind proprietățile TField.ProviderFlags.

Alt mod: instalați TDataSetProvider.ResolveToDataSet: = true. Cu toate acestea, în acest caz, evenimentul TDataSetProvider.OnBeforeApplyUpdates va trebui să deschidă setul de date asociat. astfel încât acesta să fie încărcat în evidența pe care o veți schimba. Dar acum puteți utiliza metodele din setul de date BeforeInsert-BeforePost.

Și ultima opțiune: utilizați propria metodă, a adăugat la interfața, așa cum anterior a fost făcut cu Cm2Inch, și trimite-l ClientDataset.Delta. sau un set de instrucțiuni pentru actualizare sau ceea ce vă impune imaginația dezvoltatorului. De exemplu.

În acest exemplu, metoda SaveChanges ia un pachet de date Delta și returnează un tabel de erori care au apărut în timpul actualizării.

Pentru curiozitate: formatul pachetului de date transmis este descris pe site-ul community.borland.com. dar, în realitate, acesta este trimis ca un pachet binar (base64Binary), în același format ca și fișierul (*. CD-uri), descrierea acestui format nu am putut găsi.
Pentru a vedea cum arată într-adevăr pachetele transmise prin rețea, puteți folosi programul tcpTrace. sau jurnalul WebAppDebugger.

Lucrul cu partea principală

Tot aici, totul este simplu, dar - oarecum neobișnuit, deoarece elementul trebuie să fie trecut ca un imbricat în setul de date de bază. deoarece partea principală obișnuită a legării pentru TClientDataSet nu este posibilă. Acest lucru se face astfel.

Modulul de date pentru serverul de săpun conține datele pentru tabela de master și pentru detaliu și, ca de obicei, este conectat prin intermediul TDataSource. Există, de asemenea, un TDatasetProvider. care este asociat cu tabela de master. Serverul este compilat și pus unde poate fi lansat de serverul Web.

Al doilea TClientDataSet (aceasta va fi partea noastră) a stabilit o singură proprietate: DataSetField (selectați un nume din lista pentru primul set de date TDataSetField). Acum, dacă conectați TClientDataSet cu grilele. vom vedea datele noastre - separat tabelul master și elementul.

Există o opțiune alternativă: comandantul și partea sunt trimise prin seturi de date separate. în timp ce partea este încărcată în întregime. și pentru a selecta setul de înregistrări de piese care corespund unei anumite linii a expertului, se folosește filtrarea pe client, cu toate acestea vor apărea probleme cu actualizarea sincronă a expertului și a detaliilor.

Mergeți la alt tip de aplicație

Dacă ați jucat deja suficient cu WebAppDebugger și CGI, atunci puteți să vă mișcați la modul "a spune așa, Shakespeare", modulul ISAPI / NSAPI.

În general, trecerea de la un tip de aplicație la altul (de exemplu, de la WebAppDebugger la CGI) este extrem de simplă. Creați o nouă aplicație de tipul de care avem nevoie, adăugați toate modulele noastre și aplicația nouă funcționează! Dacă sigur nu ați pus niciun cod în modulele generate automat, pe care eu personal nu le recomand.

Cu toate acestea, trebuie amintit despre diferențele WebModule menționate anterior pentru WebAppDebugger și CGI, precum și diferența de aplicații CGI și ISAPI: în primul caz, o copie a cererii de pe conexiunea (de exemplu, cu fiecare aplicație are un singur utilizator), al doilea - cererea unul, dar pentru fiecare conexiune din cadrul aplicației este creat un fir separat, care necesită o manipulare atentă a datelor generale și altfel - fără probleme.

Notă: serverul SOAP, compilate în Delphi 7 (și, probabil, mai mare) chuvsvitelny Locale la serverul pe care lucrează - se bazează pe ea, ei converti caractere rusești de la Win1251 la UTF8. Ie în setările naționale ale sistemului de operare al serverului este necesar să se expună țara "Rusia", altfel în loc de litere rusești obține kryakozubry.
sau adăugați orice linie la codul de inițializare a oricărui modul

care va determina modulul dvs. să utilizeze codificarea implicită rusă.

Ca o literatură suplimentară vă sfătuiesc să arătați:

  1. Capitolul BizSnap al Ghidului dezvoltatorului Kylix (în special părțile 4-6)
  2. InterBase într-o lume multi-nivel
  3. Proiectarea aplicatiilor ISAPI pentru lucrul cu bazele de date
  4. . și bineînțeles - RTFM. adevăr cu căutarea în aceste secțiuni din anumite motive mari probleme, dar informațiile din ajutor este, de asemenea, destul de detaliate,
  5. precum și acele aplicații demo. care vin cu Delphi

Dorințe pentru dezvoltarea acestui articol sunt binevenite pe. [email protected]







Articole similare

Trimiteți-le prietenilor: