Zend_Amf-Server.xml 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!-- EN-Revision: 15034 -->
  3. <!-- Reviewed: no -->
  4. <sect1 id="zend.amf.server">
  5. <title>Zend_Amf_Server</title>
  6. <para>
  7. <classname>Zend_Amf_Server</classname> bietet einen RPC-artigen Server für die Behandlung der
  8. Anfragen die vom Adobe Flash Player durchgeführt werden indem das AMF Protokoll verwendet
  9. wird. Wie alle Zend Framework Serverklassen, folgt es der SoapServer API, und bietet ein
  10. einfach zu merkendes Interface für die Erstellung von Servern.
  11. </para>
  12. <example id="zend.amf.server.basic">
  13. <title>AMF Server Grundlagen</title>
  14. <para>
  15. Angenommen wir haben eine Klasse <code>Foo</code> mit einer Anzahl von öffentlichen
  16. Methoden erstellt. Man kann einen AMF Server erstellen indem der folgende Code
  17. verwendet wird:
  18. </para>
  19. <programlisting role="php"><![CDATA[
  20. $server = new Zend_Amf_Server();
  21. $server->setClass('Foo');
  22. $response = $server->handle();
  23. echo $response;
  24. ]]>
  25. </programlisting>
  26. <para>
  27. Alternativ kann stattdessen man eine einfache Funktion als Callback anhängen:
  28. </para>
  29. <programlisting role="php"><![CDATA[
  30. $server = new Zend_Amf_Server();
  31. $server->addFunction('myUberCoolFunction');
  32. $response = $server->handle();
  33. echo $response;
  34. ]]>
  35. </programlisting>
  36. <para>
  37. Man kann auch mehrere Klassen und Funktionen mischen und verwenden. Wenn man das macht
  38. wird empfohlen das jede von Ihnen einen Namespace erhält um sicherzustellen das keine
  39. Kollision von Methodennamen stattfindet; das kann durchgeführt werden indem man einfach
  40. ein zweites Stringargument entweder an <code>addFunction()</code> oder an
  41. <code>setClass()</code> übergibt:
  42. </para>
  43. <programlisting role="php"><![CDATA[
  44. $server = new Zend_Amf_Server();
  45. $server->addFunction('myUberCoolFunction', 'my')
  46. ->setClass('Foo', 'foo')
  47. ->setClass('Bar', 'bar');
  48. $response = $server->handle();
  49. echo $response;
  50. ]]>
  51. </programlisting>
  52. <para>
  53. <code>Zend Amf Server</code> erlaubt es auch Services das Sie dynamisch geladen werden, basierend
  54. auf dem angegebenen Verzeichnispfad. Man kann dem Server so viele Verzeichnisse wie man will
  55. hinzufügen. Die Reihenfolge in der man die Verzeichnisse zum Server hinzufügt ist die Reihenfolge
  56. in der die LIFO Suche auf den Verzeichnissen durchgeführt wird um die Klasse zu finden.
  57. Das Hinzufügen von Verzeichnissen wird mit der <code>addDirectory()</code> Methode durchgeführt.
  58. </para>
  59. <programlisting role="php"><![CDATA[
  60. $server->addDirectory(dirname(__FILE__) .'/../services/');
  61. $server->addDirectory(dirname(__FILE__) .'/../package/');
  62. ]]>
  63. </programlisting>
  64. <para>
  65. Wenn entfernte Services aufgerufen werden kann der Quellname einen Unterstrich (_) oder Punkt (.)
  66. Begrenzer im Verzeichnis haben. Wenn ein Unterstrich verwendet wird werden die Namenskonventionen
  67. der PEAR und Zend Framework Klassen verwendet. Das bedeutet das wenn man das Sevice
  68. <code>com_Foo_Bar</code> aufruft wird der Server nach der Datei Bar.php suchen, und zwar in jedem
  69. der eingefügten Pfade unter <code>com/Foo/Bar.php</code>. Wenn die Punkt Notation für entfernte
  70. Services wie für <code>com.Foo.Bar</code> verwendet wird, wird jedem eingefügten Pfad
  71. <code>com/Foo/Bar.php</code> am Ende hinzugefügt um Bar.php automatisch zu laden.
  72. </para>
  73. <para>
  74. Alle AMF Anfragen die an das Skript gesendet werden, werden dan durch den Server
  75. behandelt, und eine AMF Antwort wird zurückgegeben.
  76. </para>
  77. </example>
  78. <note>
  79. <title>Alle angehängten Methoden und Funktionen benötigen einen Docblock</title>
  80. <para>
  81. Wie alle anderen Serverkomponenten im Zend Framework müssen die Klassenmethoden
  82. dokumentiert werden indem PHP Docblocks verwendet werden. Mindestens muß für
  83. jedes benötigte Argument eine Beschreibung angegeben werden sowie ein Rückgabewert.
  84. Als Beispiel:
  85. </para>
  86. <programlisting role="php"><![CDATA[
  87. // Funktion zum Anhängen:
  88. /**
  89. * @param string $name
  90. * @param string $greeting
  91. * @return string
  92. */
  93. function helloWorld($name, $greeting = 'Hello')
  94. {
  95. return $greeting . ', ' . $name;
  96. }
  97. ]]>
  98. </programlisting>
  99. <programlisting role="php"><![CDATA[
  100. // Angehängte Klasse
  101. class World
  102. {
  103. /**
  104. * @param string $name
  105. * @param string $greeting
  106. * @return string
  107. */
  108. public function hello($name, $greeting = 'Hello')
  109. {
  110. return $greeting . ', ' . $name;
  111. }
  112. }
  113. ]]>
  114. </programlisting>
  115. <para>
  116. Andere anmerkungen können verwendet werden, werden aber ignoriert.
  117. </para>
  118. </note>
  119. <sect2 id="zend.amf.server.flex">
  120. <title>Zum Server von Flex aus verbinden</title>
  121. <para>
  122. Zum eigenen <classname>Zend_Amf_Server</classname> von einem Flex Projekt aus zu verbinden
  123. ist recht einfach; man muß zur Endpunkt URI des <classname>Zend_Amf_Server</classname>
  124. Sripts zeigen.
  125. </para>
  126. <para>
  127. Nehmen wir zum Beispiel an das man einen Server erstellt hat und Ihn in der
  128. <code>server.php</code> Datei im Anwendungsroot platziert, und die URI deswegen
  129. <code>http://example.com/server.php</code> ist. In diesem Fall würde man die
  130. services-config.xml Datei so modifizieren das das channel endpoint URI Attribut
  131. auf diesen Wert gesetzt ist.
  132. </para>
  133. <para>
  134. Wenn man noch keine service-config.xml Datei erstellt hat kann man das tun, indem
  135. man das Projekt im Navigator Fenster öffnet. Auf dem Projektnamen rechts-klickt und
  136. ‘properties’ auswählt. Im Fenster der Projekteigenschaften muß man in das
  137. ‘Flex Build Path’ Menü, auf den ‘Library path’ Tab und sicherstellen das die ‘rpc.swc’
  138. Datei bei den Projektpfaden hinzugefügt ist und auf Ok drücken um das Fenster zu
  139. schließen.
  140. </para>
  141. <para>
  142. Man muß dem Compiler auch mitteilen das er die service-config.xml verwenden soll um
  143. den Endpunkt des RemoteObjects zu finden. Um das zu tun muß das Fenster der
  144. Projekteigenschaften nochmals durch einen rechts-klick auf das Projektverzeichnis
  145. vom Navigator aus geöffnet und Eigenschaften ausgewählt werden. Vom Eigenschaften-Popup
  146. muß ‘Flex Compiler’ aufgewählt und der String: -services “services-config.xml”
  147. hinzugefügt werden. Auf Apply drücken, anschließend auf OK um die Option zu aktualisieren.
  148. Was man jetzt getan hat, ist dem Flex Compiler zu sagen das er in der services-config.xml
  149. Datei nach Laufzeitvariablen schauen soll die von der RemotingObject Klasse verwendet
  150. werden.
  151. </para>
  152. <para>
  153. Jetzt müssen wir Flex mitteilen welche Konfigurationsdateien der Services für die
  154. Verbindung zu unseren entfernten Methoden zu verwenden sind. Aus diesem Grund muß eine
  155. neue ‘services-config.xml’ Datei im Flexprojekt src Verzeichnis erstellt werden. Um das
  156. zu tun, muß man auf den Projektfolder rechts klicken und ‘new’ ‘File’ auswählen was
  157. ein neues Fenster öffnet. Anschließend das Projektverzeichnis auswählen und dann die
  158. Datei ‘services-config.xml’ benennen und auf beenden drücken.
  159. </para>
  160. <para>
  161. Flex hat eine neue services-config.xml erstellt und Sie geöffnet. Verwende den folgenden
  162. Beispieltext für die services-config.xml Datei. Es muß sichergestellt werden das der
  163. Endpunkt so aktualisiert wird das er zu dem des eigenen Testservers passt. Anschließend
  164. sicherstellen das die Datei gespeichert wird.
  165. </para>
  166. <programlisting role="xml"><![CDATA[
  167. <?xml version="1.0" encoding="UTF-8"?>
  168. <services-config>
  169. <services>
  170. <service id="zend-service"
  171. class="flex.messaging.services.RemotingService"
  172. messageTypes="flex.messaging.messages.RemotingMessage">
  173. <destination id="zend">
  174. <channels>
  175. <channel ref="zend-endpoint"/>
  176. </channels>
  177. <properties>
  178. <source>*</source>
  179. </properties>
  180. </destination>
  181. </service>
  182. </services>
  183. <channels>
  184. <channel-definition id="zend-endpoint"
  185. class="mx.messaging.channels.AMFChannel">
  186. <endpoint uri="http://example.com/server.php"
  187. class="flex.messaging.endpoints.AMFEndpoint"/>
  188. </channel-definition>
  189. </channels>
  190. </services-config>
  191. ]]>
  192. </programlisting>
  193. <para>
  194. Es gibt zwei Schlüsselpunkt im Beispiel. Erstens, aber letztes im Code, erstellen wir
  195. einen AMF Kanal, und spezifizieren den Endpunt als die URL zu unserem
  196. <classname>Zend_Amf_Server</classname>:
  197. </para>
  198. <programlisting role="xml"><![CDATA[
  199. <channel-definition id="zend-endpoint"
  200. <endpoint uri="http://example.com/server.php"
  201. class="flex.messaging.endpoints.AMFEndpoint"/>
  202. </channel-definition>
  203. ]]>
  204. </programlisting>
  205. <para>
  206. Es ist zu beachten das wir diesem Kanal einen Identifikator, "zend-endpoint", gegeben
  207. haben. Das Beispiel erstellt ein Ziel für den Service auf zu diesen Kanal zeigt,
  208. und fügt es auch als ID hinzu -- in diesem Zall "zend".
  209. </para>
  210. <para>
  211. In unseren Flex MXML Dateien müssen wir ein RemoteObject an das Service binden. In MXML
  212. kann das wie folgt getan werden:
  213. </para>
  214. <programlisting role="xml"><![CDATA[
  215. <mx:RemoteObject id="myservice"
  216. fault="faultHandler(event)"
  217. showBusyCursor="true"
  218. destination="zend">
  219. ]]>
  220. </programlisting>
  221. <para>
  222. Hier haben wir ein neues entferntes Objekt definiert das durch "myservice" identifiziert
  223. an das Serviceziel "zend" gebunden ist das wir in der <code>services-config.xml</code>
  224. Datei definiert haben. Dann rufen wir die Methoden auf Ihnen in unserem ActionScript
  225. einfach durch Aufruf von "myservice.&lt;method&gt;" auf. Als Beispiel:
  226. </para>
  227. <programlisting role="ActionScript"><![CDATA[
  228. myservice.hello("Wade");
  229. ]]>
  230. </programlisting>
  231. <para>
  232. Wenn wir Namespaces aktivieren würden wir "myservice.&lt;namespace&gt;.&lt;method&gt;"
  233. verwenden:
  234. </para>
  235. <programlisting role="ActionScript"><![CDATA[
  236. myservice.world.hello("Wade");
  237. ]]>
  238. </programlisting>
  239. <para>
  240. Für weitere Informationen über den Aufruf von Flex RemoteObject,
  241. <ulink url="http://livedocs.adobe.com/flex/3/html/help.html?content=data_access_4.html">besuchen
  242. Sie die Adobe Flex 3 Hilfeseite</ulink>.
  243. </para>
  244. </sect2>
  245. <sect2 id="zend.amf.server.errors">
  246. <title>Fehlerbehandlung</title>
  247. <para>
  248. Standardmäßig werden alle Exceptions die in den angehängten Klassen oder Funktionen
  249. geworfen werden gefangen und als AMF Fehlermeldungen zurückgegeben. Trotzdem wird der
  250. Inhalt des ErrorMessage Objekts variieren basierend darauf ob der Server im "Produktions"
  251. Modus ist (der Standardzustand) oder nicht.
  252. </para>
  253. <para>
  254. Wenn er in Produktionsmodus ist wird nur der Exceptioncode zurückgegeben. Wenn der
  255. Produktionsmodus ausgeschaltet wird -- etwas das nur für das Testen getan werden sollte
  256. -- werden die meisten Exceptiondetails zurückgegeben: Die Meldung der Exception, die Zeile,
  257. und der Backtrace werden alle angehängt.
  258. </para>
  259. <para>
  260. Um den Produktionsmodus auszuschalten muß das folgende getan werden:
  261. </para>
  262. <programlisting role="php"><![CDATA[
  263. $server->setProduction(false);
  264. ]]>
  265. </programlisting>
  266. <para>
  267. Um Ihn wieder einzuschalten, muß stattdessen einfach ein boolscher true Wert übergeben werden:
  268. </para>
  269. <programlisting role="php"><![CDATA[
  270. $server->setProduction(true);
  271. ]]>
  272. </programlisting>
  273. <note>
  274. <title>Der Produktionsmode sollte sparsam deaktiviert werden!</title>
  275. <para>
  276. Wir empfehlen den Produktionsmode nur wärend der Entwicklung auszuschalten.
  277. Exceptionmeldungen und Backtraces können sensitive Systeminformationen enthalten
  278. auf die nicht von Aussenstehenden zugegriffen werden darf. Selbst wenn AMF ein
  279. binäres Format ist, ist die Spezifikation offen, was bedeutet das jeder den
  280. Payload potentiell deserialisieren kann.
  281. </para>
  282. </note>
  283. <para>
  284. Ein Feld bei dem man im speziellen Vorsichtig sein muß ist bei PHP Fehlern selbst.
  285. Wenn die INI Direktive <code>display_errors</code> aktiviert ist, wird jeder PHP
  286. Fehler für das aktuelle Error Reporting Level direkt in der Ausgabe dargestellt --
  287. was den AMF Antwortpayload potentiell unterbrechen kann. Wir empfehlen die
  288. <code>display_errors</code> Direktive in der Produktion auszuschalten um solche
  289. Probleme zu verhindern.
  290. </para>
  291. </sect2>
  292. <sect2 id="zend.amf.server.response">
  293. <title>AMF Antworten</title>
  294. <para>
  295. Fallweise ist es gewünscht das Antwortobjekt leicht zu manipulieren, typischerweise um
  296. zusätzliche Nachrichtenheader zurückzugeben. Die <code>handle()</code> Methode des Servers
  297. gibt das Antwortobjekt zurück, was es erlaubt das zu tun.
  298. </para>
  299. <example id="zend.amf.server.response.messageHeaderExample">
  300. <title>Nachrichtenheader der AMF Antwort hinzufügen</title>
  301. <para>
  302. In diesem Beispiel fügen wir einen 'foo' Nachrichtenheader mit dem Wert 'bar' zu der
  303. Antwort hinzu bevor sie zurückgegeben wird.
  304. </para>
  305. <programlisting role="php"><![CDATA[
  306. $response = $server->handle();
  307. $response->addAmfHeader(new Zend_Amf_Value_MessageHeader('foo', true, 'bar'))
  308. echo $response;
  309. ]]>
  310. </programlisting>
  311. </example>
  312. </sect2>
  313. <sect2 id="zend.amf.server.typedobjects">
  314. <title>Typ Objekte</title>
  315. <para>
  316. Ähnlich wie SOAP, erlaubt es AMF Objekte zwischen dem Client und dem Server zu übergeben.
  317. Das erlaubt eine große Flexibilität und Bindung zwischen den zwei Umgebungen.
  318. </para>
  319. <para>
  320. <classname>Zend_Amf</classname> bietet drei Methoden für das Mappen von ActionScript und PHP Objekten.
  321. </para>
  322. <itemizedlist>
  323. <listitem>
  324. <para>
  325. Erstens kann man explizite Bindungen auf Serverlevel erstellen indem die
  326. <code>setClassMap()</code> Methode verwendet wird. Das erste Argument ist der
  327. ActionScript Klassenname, das zweite ist der Name der PHP Klasse auf die gemappt wird:
  328. </para>
  329. <programlisting role="php"><![CDATA[
  330. // Die ActionScript Klasse 'ContactVO' auf die PHP Klasse 'Contact' mappen:
  331. $server->setClassMap('ContactVO', 'Contact');
  332. ]]>
  333. </programlisting>
  334. </listitem>
  335. <listitem>
  336. <para>
  337. Zweitens kann die öffentliche Eigenschaft <code>$_explicitType</code> in der
  338. PHP Klasse gesetzt werden, wobei der Wert die ActionScript Klasse repräsentiert
  339. auf die gemappt wird:
  340. </para>
  341. <programlisting role="php"><![CDATA[
  342. class Contact
  343. {
  344. public $_explicitType = 'ContactVO';
  345. }
  346. ]]>
  347. </programlisting>
  348. </listitem>
  349. <listitem>
  350. <para>
  351. Drittens, in ähnlicher Art und Weise, kann eine öffentliche Methode
  352. <code>getASClassName()</code> in der PHP Klasse definiert werden; diese Methode
  353. sollte die passende ActionScript Klasse zurückgeben:
  354. </para>
  355. <programlisting role="php"><![CDATA[
  356. class Contact
  357. {
  358. public function getASClassName()
  359. {
  360. return 'ContactVO';
  361. }
  362. }
  363. ]]>
  364. </programlisting>
  365. </listitem>
  366. </itemizedlist>
  367. <para>
  368. Auch wenn wir nun den ContactVO auf dem Server erstellt have müssen wir nun seine
  369. korrespondierende Klasse in AS3 für das Server Objekt erstellen das gemappt werden soll.
  370. </para>
  371. <para>
  372. Einen Rechtsklick auf das src Verzeichnis des Flex Projekts und New -> ActionScript File
  373. auswählen. Name der Datei ContactVO und finish drücken um die neue Datei zu sehen.
  374. Den folgenden Code in die Datei kopieren um die Erstellung der Klasse fertigzustellen.
  375. </para>
  376. <programlisting role="as"><![CDATA[
  377. package
  378. {
  379. [Bindable]
  380. [RemoteClass(alias="ContactVO")]
  381. public class ContactVO
  382. {
  383. public var id:int;
  384. public var firstname:String;
  385. public var lastname:String;
  386. public var email:String;
  387. public var mobile:String;
  388. public function ProductVO():void {
  389. }
  390. }
  391. }
  392. ]]>
  393. </programlisting>
  394. <para>
  395. Die Klasse ist syntaktisch identisch zu der von PHP mit dem gleichen Namen. Die
  396. Variablennamen sind exakt die gleichen und müssen im gleichen Fall sein um korrekt
  397. zu arbeiten. Es gibt zwei eindeutige AS3 Metatags in dieser Klasse. Das Erste kann
  398. gebunden werden was ein Änderungsevent wirft wenn es aktualisiert wird. Das zweite Tag
  399. ist das RemoteClass Tag welches definiert das diese klasse ein gemapptes entferntes
  400. Objekt haben kann, in diesem Fall mit dem Aliasnamen <code>ContactVO</code>. Es ist
  401. erforderlich das dieses Tag und der Wert der in der PHP Klasse gesetzt wurde, strikt
  402. identisch sind.
  403. </para>
  404. <programlisting role="as"><![CDATA[
  405. [Bindable]
  406. private var myContact:ContactVO;
  407. private function getContactHandler(event:ResultEvent):void {
  408. myContact = ContactVO(event.result);
  409. }
  410. ]]>
  411. </programlisting>
  412. <para>
  413. Das folgende Ergebnisevent vom Serviceaufruf wird sofort zu Flex ContactVO gecastet.
  414. Alles das bei myContact gebunden ist, wird mit den von ContactVO zurückgegebenen
  415. Daten aktualisiert.
  416. </para>
  417. </sect2>
  418. <sect2 id="zend.amf.server.flash">
  419. <title>Von Flash aus auf den Server verbinden</title>
  420. <para>
  421. Auf den <classname>Zend_Amf_Server</classname> vom Flash Projekt aus zu verbinden ist etwas anders
  422. als von Flex aus. Trotzdem sind die Funktionen mit <classname>Zend_Amf_Server</classname> die gleichen
  423. wie mit Flex sobald die Verbindung erstellt wurde. Das folgende Beispiel kann auch von einer
  424. Flex AS3 Datei aus verwendet werden. Wir werden die selbe <classname>Zend_Amf_Server</classname>
  425. Konfiguration mit der World Klasse unserer Verbindung wiederverwenden.
  426. </para>
  427. <para>
  428. Öffne Flash CS und erstelle eine neue Flash Datei (ActionScript 3). Benenne das Dokument
  429. ZendExample.fla und speichere das Dokument in einem Verzeichnis das wir für dieses Beispiel
  430. verwenden werden. Erstelle eine neue AS3 Datei im selben Verzeichnis und benenne die Datei
  431. Main.as. Öffne beide Dateien im Editor. Wir werden jetzt diese zwei Dateien über die Document
  432. Klasse verbinden. Wähle ZendExample aus und klicke auf "stage". Im Eigenschaftsfenster von "stage"
  433. ändere die Document Klasse auf Main. Das verbindet die Main.as ActionScript Datei mit dem Benutzer
  434. Interface von ZendExample.fla. Wenn die Flashdatei ZendExample ausgeführt wird, dann wird die
  435. Klasse Main.as gestartet. Als nächstes werden wir ein ActionScript hinzufügen um den AMF
  436. Aufruf durchzuführen.
  437. </para>
  438. <para>
  439. Jetzt werden wir eine Main Klasse erstellen damit wir die Daten zum Server schicken und das
  440. Ergebnis anzeigen lassen können. Kopiere den folgenden Code in die Main.as Datei und wird werden
  441. den Code anschauen um zu erklären was die Rolle eines jeden Elements ist.
  442. </para>
  443. <programlisting role="as"><![CDATA[
  444. package {
  445. import flash.display.MovieClip;
  446. import flash.events.*;
  447. import flash.net.NetConnection;
  448. import flash.net.Responder;
  449. public class Main extends MovieClip {
  450. private var gateway:String = "http://example.com/server.php";
  451. private var connection:NetConnection;
  452. private var responder:Responder;
  453. public function Main() {
  454. responder = new Responder(onResult, onFault);
  455. connection = new NetConnection;
  456. connection.connect(gateway);
  457. }
  458. public function onComplete( e:Event ):void{
  459. var params = "Zum Server geschickt";
  460. connection.call("World.hello", responder, params);
  461. }
  462. private function onResult(result:Object):void {
  463. // Die zurückgegebenen Daten anzeigen
  464. trace(String(result));
  465. }
  466. private function onFault(fault:Object):void {
  467. trace(String(fault.description));
  468. }
  469. }
  470. }
  471. ]]>
  472. </programlisting>
  473. <para>
  474. Wir müssen zuerst zwei ActionScript Bibliotheken importieren die den Haufen an Arbeit erledigen.
  475. Das erste ist NetConnection welches wie eine Zweiwege-Leitung, zwischen dem Client und dem Server,
  476. funktioniert. Das zweite ist ein Responder Objekt welches die Rückgabewerte des Servers behandelt
  477. relativ zum Erfolg oder Mißerfolg des Aufrufs.
  478. </para>
  479. <programlisting role="as"><![CDATA[
  480. import flash.net.NetConnection;
  481. import flash.net.Responder;
  482. ]]>
  483. </programlisting>
  484. <para>
  485. In der Klasse benötigen wir drei Variable um NetConnection, Responder, und die Gateway URL zu
  486. unserer <classname>Zend_Amf_Server</classname> Installation zu repräsentieren.
  487. </para>
  488. <programlisting role="as"><![CDATA[
  489. private var gateway:String = "http://example.com/server.php";
  490. private var connection:NetConnection;
  491. private var responder:Responder;
  492. ]]>
  493. </programlisting>
  494. <para>
  495. Im Main Contructor erstellen wir einen Responder und eine neue Verbindung zum
  496. <classname>Zend_Amf_Server</classname> Endpunkt. Der Responder definiert zwei unterschiedliche Methoden
  497. für die Behandlung des Servers. Der Einfachheit halber haben wir Sie onResult und onFault
  498. benannt.
  499. </para>
  500. <programlisting role="as"><![CDATA[
  501. responder = new Responder(onResult, onFault);
  502. connection = new NetConnection;
  503. connection.connect(gateway);
  504. ]]>
  505. </programlisting>
  506. <para>
  507. In der onComplete Funktion, welche ausgeführt wird sobald das Konstrukt fertiggestellt wurde,
  508. senden wir die Daten zum Server. Wird benötigen eine weitere zusätzliche Zeile die den Aufruf
  509. der <classname>Zend_Amf_Server</classname> World->hello Funktion durchführt.
  510. </para>
  511. <programlisting role="as"><![CDATA[
  512. connection.call("World.hello", responder, params);
  513. ]]>
  514. </programlisting>
  515. <para>
  516. Als wir die Responder Variable erstellt haben, haben wir auch eine onResult und eine onFault
  517. Funktion definiert die die Antwort des Servers behandeln. Wir haben diese Funktionen für ein
  518. ergolfreiches Ergebnis der Servers hunzugefügt. Ein erfolgreicher Eventhandler wird immer dann
  519. ausgeführt wenn die Verbindung zum Server richtig handgehabt wird.
  520. </para>
  521. <programlisting role="as"><![CDATA[
  522. private function onResult(result:Object):void {
  523. // Display the returned data
  524. trace(String(result));
  525. }
  526. ]]>
  527. </programlisting>
  528. <para>
  529. Die onFault Funktion wird aufgerufen wenn eine ungültige Antwort vom Server zurückgekommen ist.
  530. Das passiert wenn auf dem Server ein Fehler stattgefunden hat, die URL zum Server ungültig ist,
  531. der entfernte Service oder die Methode nicht existiert, und bei jedem anderen Verbindungsrelevanten
  532. Problem.
  533. </para>
  534. <programlisting role="as"><![CDATA[
  535. private function onFault(fault:Object):void {
  536. trace(String(fault.description));
  537. }
  538. ]]>
  539. </programlisting>
  540. <para>
  541. Das ActionScripts für die Erstellung der entfernten Verbindung ist jetzt fertiggestellt.
  542. Der Aufruf der ZendExample Datei führt jetzt die Verbindung zu Zend Amf aus. Rückblickend
  543. haben wir die benötigten Variablen hinzugefügt um eine Verbindung zum entfernten Server zu
  544. öffnen, definiert welche Methoden in der Anwendung verwendet werden sollen wenn die Anwendung
  545. eine Antwort vom Server empfängt, und schlußendlich die Anzeige der zurückgegebenen Daten über
  546. trace().
  547. </para>
  548. </sect2>
  549. </sect1>
  550. <!--
  551. vim:se ts=4 sw=4 et:
  552. -->