<!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 &trade;</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 &amp;&amp; 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 &amp;&amp; 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&lt;SharedStruct&gt;();

    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 &copy; 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>
