Thrift Javascript Library
=========================
This browser based Apache Thrift implementation supports
RPC clients using the JSON protocol over Http[s] with XHR.

License
-------
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.

Example
-------
The listing below demonstrates a simple browser based JavaScript
Thrift client and Node.js JavaScript server for the hello_svc 
service. 

### hello.thrift - Service IDL
    service hello_svc {
      string get_message(1: string name)
    }

### hello.html - Browser Client
    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="utf-8">
        <title>Hello Thrift</title>
      </head>
      <body>
        Name: <input type="text" id="name_in">
        <input type="button" id="get_msg" value="Get Message" >
        <div id="output"></div>
  
        <script src="thrift.js"></script>
        <script src="gen-js/hello_svc.js"></script>
        <script>
          (function() {
            var transport = new Thrift.Transport("/hello");
            var protocol  = new Thrift.Protocol(transport);
            var client    = new hello_svcClient(protocol);
            var nameElement = document.getElementById("name_in");
            var outputElement = document.getElementById("output");
            document.getElementById("get_msg")
              .addEventListener("click", function(){
                client.get_message(nameElement.value, function(result) {
                  outputElement.innerHTML = result;
                });
              });
          })();
        </script>
      </body>
    </html>

### hello.js - Node Server
    var Thrift = require('thrift');
    var TBufferedTransport = require('thrift/lib/thrift/transport').TBufferedTransport;
    var TJSONProtocol = require('thrift/lib/thrift/protocol').TJSONProtocol;
    var hello_svc = require('./gen-nodejs/hello_svc.js');
    
    var hello_handler = {
      get_message: function(name, result) {
        var msg = "Hello " + name + "!";
        result(null, msg);
      }
    }
    
    var hello_svc_opt = {
      transport: TBufferedTransport,
      protocol: TJSONProtocol,
      cls: hello_svc,
      handler: hello_handler
    };
    
    var server_opt = {
      staticFilePath: ".",
      services: {
        "/hello": hello_svc_opt
      }
    }
    
    var server = Thrift.createStaticHttpThriftServer(server_opt);
    var port = 9099;
    server.listen(port);
    console.log("Http/Thrift Server running on port: " + port);`
