Zend_Amf-Server.xml 26 KB

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