| <!DOCTYPE html> |
| <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> |
| <head> |
| <meta content="text/html; charset=utf-8" http-equiv="Content-Type" /> |
| <meta content="en-us" http-equiv="Content-Language" /> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| |
| <link href="/static/images/favicon.ico" rel="shortcut icon" /> |
| <link href="/static/css/style.css" rel="stylesheet" type="text/css" /> |
| <link href="/static/css/codehilite.css" rel="stylesheet" type="text/css" /> |
| <link href="/static/css/bootstrap.css" media="screen, projection" rel="stylesheet" type="text/css" /> |
| <link href="/static/css/thrift.css" media="screen, projection" rel="stylesheet" type="text/css" /> |
| |
| <script src="/static/js/jquery.min.js"></script> |
| <script src="/static/js/bootstrap-dropdown.js"></script> |
| <script src="/static/js/bootstrap-tab.js"></script> |
| <script src="/static/js/thrift.js"></script> |
| |
| <title>Apache Thrift - Haxe Framework</title> |
| </head> |
| <body> |
| <div class="navbar"> |
| <div class="navbar-inner"> |
| <div class="container"> |
| <a class="brand" href="/">Apache Thrift ™</a> |
| <div class="nav-collapse"> |
| <ul class="nav pull-right"> |
| <li><a href="/download">Download</a></li> |
| <li><a href="/docs">Documentation</a></li> |
| <li><a href="/developers">Developers</a></li> |
| <li><a href="/lib">Libraries</a></li> |
| <li><a href="/tutorial">Tutorial</a></li> |
| <li><a href="/test">Test Suite</a></li> |
| <li><a href="/about">About</a></li> |
| <li class="dropdown"> |
| <a href="#" class="dropdown-toggle" data-toggle="dropdown">Apache <b class="caret"></b></a> |
| <ul class="dropdown-menu"> |
| <li><a href="http://www.apache.org/" target="_blank">Apache Home</a></li> |
| <li><a href="http://www.apache.org/licenses/" target="_blank">Apache License v2.0</a></li> |
| <li><a href="http://www.apache.org/foundation/sponsorship.html" target="_blank">Donate</a></li> |
| <li><a href="http://www.apache.org/foundation/thanks.html" target="_blank">Thanks</a></li> |
| <li><a href="http://www.apache.org/security/" target="_blank">Security</a></li> |
| </ul> |
| </li> |
| </ul> |
| </div> |
| </div> |
| </div> |
| </div> |
| |
| <div class="container"> |
| <h2>Haxe Framework Tutorial</h2> |
| |
| <h3>Introduction</h3> |
| |
| <p> |
| All Apache Thrift tutorials require that you have: |
| |
| <ol> |
| <li>The Apache Thrift Compiler and Libraries, see <a href="/download">Download</a> and <a href="/docs/BuildingFromSource">Building from Source</a> for more details.</li> |
| <li>Generated the <a href="https://github.com/apache/thrift/blob/master/tutorial/tutorial.thrift">tutorial.thrift</a> and <a href="https://github.com/apache/thrift/blob/master/tutorial/shared.thrift">shared.thrift</a> files:<br> |
| <pre><code>thrift -r --gen haxe tutorial.thrift</code></pre> |
| </li> |
| <li>Followed all prerequisites listed below.</li> |
| </ol> |
| |
| <h3 id="prerequisites">Prerequisites</h3> |
| <ul> |
| <li>Thrift requires at least Haxe 3.1.3. (You may try with older versions on your own luck).</li> |
| </ul> |
| |
| <h3 id="client">Client</h3> |
| <p>For this tutorial, we put both the server and the client main code into one single program. |
| Depending on the arguments passed, it runs as a server or as a client program.</p> |
| |
| <div class="highlight"><pre class="codehilite"><code>package; |
| |
| import org.apache.thrift.*; |
| import org.apache.thrift.protocol.*; |
| import org.apache.thrift.transport.*; |
| import org.apache.thrift.server.*; |
| import org.apache.thrift.meta_data.*; |
| |
| import tutorial.*; |
| import shared.*; |
| |
| |
| enum Prot { |
| binary; |
| json; |
| compact; |
| } |
| |
| enum Trns { |
| socket; |
| http; |
| } |
| |
| class Main { |
| |
| private static var server : Bool = false; |
| private static var framed : Bool = false; |
| private static var buffered : Bool = false; |
| private static var prot : Prot = binary; |
| private static var trns : Trns = socket; |
| |
| private static var targetHost : String = "localhost"; |
| private static var targetPort : Int = 9090; |
| |
| static function main() { |
| |
| #if ! (flash || js || phpwebserver) |
| try { |
| ParseArgs(); |
| } catch (e : String) { |
| trace(e); |
| trace(GetHelp()); |
| return; |
| } |
| |
| #elseif phpwebserver |
| //forcing server |
| server = true; |
| trns = http; |
| initPhpWebServer(); |
| //check method |
| if(php.Web.getMethod() != 'POST') { |
| Sys.println('http endpoint for thrift test server'); |
| return; |
| } |
| #end |
| |
| try { |
| if (server) |
| RunServer(); |
| else |
| RunClient(); |
| } catch (e : String) { |
| trace(e); |
| } |
| |
| trace("Completed."); |
| } |
| |
| #if phpwebserver |
| private static function initPhpWebServer() |
| { |
| //remap trace to error log |
| haxe.Log.trace = function(v:Dynamic, ?infos:haxe.PosInfos) |
| { |
| // handle trace |
| var newValue : Dynamic; |
| if (infos != null && infos.customParams!=null) { |
| var extra:String = ""; |
| for( v in infos.customParams ) |
| extra += "," + v; |
| newValue = v + extra; |
| } |
| else { |
| newValue = v; |
| } |
| var msg = infos != null ? infos.fileName + ':' + infos.lineNumber + ': ' : ''; |
| Sys.stderr().writeString('${msg}${newValue}\n'); |
| } |
| } |
| #end |
| |
| |
| #if ! (flash || js) |
| |
| private static function GetHelp() : String { |
| return Sys.programPath+" modus layered transport protocol\n" |
| +"Options:\n" |
| +" modus: client, server (default: client)\n" |
| +" layered: framed, buffered (default: none)\n" |
| +" transport: socket, http (default: socket)\n" |
| +" protocol: binary, json, compact (default: binary)\n" |
| +"\n" |
| +"All arguments are optional.\n"; |
| } |
| |
| |
| private static function ParseArgs() : Void { |
| var step = 0; |
| for (arg in Sys.args()) { |
| |
| // server|client |
| switch(step) { |
| case 0: |
| ++step; |
| if ( arg == "client") |
| server = false; |
| else if ( arg == "server") |
| server = true; |
| else |
| throw "First argument must be 'server' or 'client'"; |
| |
| case 1: |
| if ( arg == "framed") { |
| framed = true; |
| } else if ( arg == "buffered") { |
| buffered = true; |
| } else if ( arg == "socket") { |
| trns = socket; |
| ++step; |
| } else if ( arg == "http") { |
| trns = http; |
| ++step; |
| } else { |
| throw "Unknown transport "+arg; |
| } |
| |
| case 2: |
| if ( arg == "binary") { |
| prot = binary; |
| ++step; |
| } else if ( arg == "json") { |
| prot = json; |
| ++step; |
| } else if ( arg == "compact") { |
| prot = compact; |
| ++step; |
| } else { |
| throw "Unknown protocol "+arg; |
| } |
| |
| default: |
| throw "Unexpected argument "+arg; |
| } |
| |
| if ( framed && buffered) |
| { |
| trace("WN: framed supersedes buffered"); |
| } |
| |
| } |
| } |
| |
| #end |
| |
| private static function ClientSetup() : Calculator { |
| trace("Client configuration:"); |
| |
| // endpoint transport |
| var transport : TTransport; |
| switch(trns) |
| { |
| case socket: |
| trace('- socket transport $targetHost:$targetPort'); |
| transport = new TSocket( targetHost, targetPort); |
| case http: |
| var uri = 'http://${targetHost}:${targetPort}'; |
| trace('- HTTP transport $uri'); |
| transport = new THttpClient(uri); |
| default: |
| throw "Unhandled transport"; |
| } |
| |
| |
| // optinal layered transport |
| if ( framed) { |
| trace("- framed transport"); |
| transport = new TFramedTransport(transport); |
| } else if ( buffered) { |
| trace("- buffered transport"); |
| transport = new TBufferedTransport(transport); |
| } |
| |
| |
| // protocol |
| var protocol : TProtocol; |
| switch(prot) |
| { |
| case binary: |
| trace("- binary protocol"); |
| protocol = new TBinaryProtocol( transport); |
| case json: |
| trace("- JSON protocol"); |
| protocol = new TJSONProtocol( transport); |
| case compact: |
| trace("- compact protocol"); |
| protocol = new TCompactProtocol( transport); |
| default: |
| throw "Unhandled protocol"; |
| } |
| |
| |
| // put everything together |
| transport.open(); |
| return new CalculatorImpl(protocol,protocol); |
| } |
| |
| |
| private static function RunClient() : Void { |
| var client = ClientSetup(); |
| |
| try { |
| client.ping(); |
| trace("ping() successful"); |
| } catch(error : TException) { |
| trace('ping() failed: $error'); |
| } catch(error : Dynamic) { |
| trace('ping() failed: $error'); |
| } |
| |
| try { |
| var sum = client.add( 1, 1); |
| trace('1+1=$sum'); |
| } catch(error : TException) { |
| trace('add() failed: $error'); |
| } catch(error : Dynamic) { |
| trace('add() failed: $error'); |
| } |
| |
| |
| var work = new tutorial.Work(); |
| work.op = tutorial.Operation.DIVIDE; |
| work.num1 = 1; |
| work.num2 = 0; |
| try { |
| var quotient = client.calculate( 1, work); |
| trace('Whoa we can divide by 0! Result = $quotient'); |
| } catch(error : TException) { |
| trace('calculate() failed: $error'); |
| } catch(error : Dynamic) { |
| trace('calculate() failed: $error'); |
| } |
| |
| work.op = tutorial.Operation.SUBTRACT; |
| work.num1 = 15; |
| work.num2 = 10; |
| try { |
| var diff = client.calculate( 1, work); |
| trace('15-10=$diff'); |
| } catch(error : TException) { |
| trace('calculate() failed: $error'); |
| } catch(error : Dynamic) { |
| trace('calculate() failed: $error'); |
| } |
| |
| |
| try { |
| var log : SharedStruct = client.getStruct( 1); |
| var logval = log.value; |
| trace('Check log: $logval'); |
| } catch(error : TException) { |
| trace('getStruct() failed: $error'); |
| } catch(error : Dynamic) { |
| trace('getStruct() failed: $error'); |
| } |
| } |
| |
| |
| private static function ServerSetup() : TServer { |
| trace("Server configuration:"); |
| |
| // endpoint transport |
| var transport : TServerTransport = null; |
| switch(trns) |
| { |
| case socket: |
| #if (flash || js) |
| throw 'current platform does not support socket servers'; |
| #else |
| trace('- socket transport port $targetPort'); |
| transport = new TServerSocket( targetPort); |
| #end |
| case http: |
| #if !phpwebserver |
| throw "HTTP server not implemented yet"; |
| //trace("- http transport"); |
| //transport = new THttpClient( targetHost); |
| #else |
| trace("- http transport"); |
| transport = new TWrappingServerTransport( |
| new TStreamTransport( |
| new TFileStream("php://input", Read), |
| new TFileStream("php://output", Append), |
| null |
| ) |
| ); |
| |
| #end |
| default: |
| throw "Unhandled transport"; |
| } |
| |
| // optional: layered transport |
| </code></pre></div> |
| <p class="snippet_footer">This snippet was generated by Apache Thrift's <strong>source tree docs</strong>: |
| <a href="https://gitbox.apache.org/repos/asf?p=thrift.git;a=blob;hb=HEAD;f=tutorial/haxe/src/Main.hx">tutorial/haxe/src/Main.hx</a> |
| </p> |
| |
| <p>Were done with the client, but need some more for the server: A service handler implementaion.</p> |
| |
| <h3 id="server">Server</h3> |
| <p>As the name suggests, the service handler implements the Thrift service on the server side. |
| The code to achieve this is as follows:</p> |
| |
| <div class="highlight"><pre class="codehilite"><code>package; |
| |
| import haxe.ds.IntMap; |
| |
| import org.apache.thrift.*; |
| import org.apache.thrift.protocol.*; |
| import org.apache.thrift.transport.*; |
| import org.apache.thrift.server.*; |
| import org.apache.thrift.meta_data.*; |
| |
| import tutorial.*; |
| import shared.*; |
| |
| |
| class CalculatorHandler implements Calculator_service { |
| |
| private var log = new IntMap<SharedStruct>(); |
| |
| public function new() { |
| } |
| |
| public function ping() : Void { |
| trace("ping()"); |
| } |
| |
| |
| public function add( num1 : haxe.Int32, num2 : haxe.Int32) : haxe.Int32 { |
| trace('add( $num1, $num2)'); |
| return num1 + num2; |
| } |
| |
| public function calculate( logid : haxe.Int32, work : Work) : haxe.Int32 { |
| trace('calculate( $logid, '+work.op+","+work.num1+","+work.num2+")"); |
| |
| var val : haxe.Int32 = 0; |
| switch (work.op) |
| { |
| case Operation.ADD: |
| val = work.num1 + work.num2; |
| |
| case Operation.SUBTRACT: |
| val = work.num1 - work.num2; |
| |
| case Operation.MULTIPLY: |
| val = work.num1 * work.num2; |
| |
| case Operation.DIVIDE: |
| if (work.num2 == 0) |
| { |
| var io = new InvalidOperation(); |
| io.whatOp = work.op; |
| io.why = "Cannot divide by 0"; |
| throw io; |
| } |
| val = Std.int( work.num1 / work.num2); |
| |
| default: |
| var io = new InvalidOperation(); |
| io.whatOp = work.op; |
| io.why = "Unknown operation"; |
| throw io; |
| } |
| |
| var entry = new SharedStruct(); |
| entry.key = logid; |
| entry.value = '$val'; |
| log.set(logid, entry); |
| |
| return val; |
| } |
| |
| public function getStruct( key : haxe.Int32) : SharedStruct { |
| trace('getStruct($key)'); |
| return log.get(key); |
| } |
| |
| // oneway method, no args |
| public function zip() : Void { |
| trace("zip()"); |
| } |
| |
| } |
| </code></pre></div> |
| <p class="snippet_footer">This snippet was generated by Apache Thrift's <strong>source tree docs</strong>: |
| <a href="https://gitbox.apache.org/repos/asf?p=thrift.git;a=blob;hb=HEAD;f=tutorial/haxe/src/CalculatorHandler.hx">tutorial/haxe/src/CalculatorHandler.hx</a> |
| </p> |
| |
| <h3 id="additional-information">Additional Information</h3> |
| |
| <p>Similar to Thrift, Haxe supports different compiler targets. Depending on the target, some features |
| may or may not be supported. For example, if you plan to use Flash or JavaScript targets, |
| there is currently no way to pass command line arguments to the program.</p> |
| |
| |
| |
| |
| </div> |
| <div class="container"> |
| <hr> |
| <footer class="footer"> |
| <div class="row"> |
| <div class="span3"> |
| <h3>Links</h3> |
| <ul class="unstyled"> |
| <li><a href="/download">Download</a></li> |
| <li><a href="/developers">Developers</a></li> |
| <li><a href="/tutorial">Tutorials</a></li> |
| </ul> |
| <ul class="unstyled"> |
| <li><a href="/sitemap">Sitemap</a></li> |
| </ul> |
| </div> |
| <div class="span3"> |
| <h3>Get Involved</h3> |
| <ul class="unstyled"> |
| <li><a href="/mailing">Mailing Lists</a></li> |
| <li><a href="http://issues.apache.org/jira/browse/THRIFT">Issue Tracking</a></li> |
| <li><a href="/docs/HowToContribute">How To Contribute</a></li> |
| </ul> |
| </div> |
| <div class="span6"> |
| <a href="http://www.apache.org/"><img src="/static/images/feather.svg" onerror="this.src='/static/images/feather.png';this.onerror=null;" /></a> |
| Copyright © 2024 <a href="http://www.apache.org/">Apache Software Foundation</a>. |
| Licensed under the <a href="http://www.apache.org/licenses/">Apache License v2.0</a>. |
| Apache, Apache Thrift, and the Apache feather logo are trademarks of The Apache Software Foundation. |
| </div> |
| </div> |
| </footer> |
| </div> |
| |
| </body> |
| </html> |