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

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.

Grunt Build
------------
This is the base directory for the Apache Thrift JavaScript
library. This directory contains a Gruntfile.js and a
package.json. Many of the build and test tools used here
require a recent version of Node.js to be installed. To 
install the support files for the Grunt build tool execute
the command:
   $ npm install
This reads the package.json and pulls in the appropriate
sources from the internet. To build the JavaScript branch
of Apache Thrift execute the command:
   $ grunt
This runs the grunt build tool, linting all of the source 
files, setting up and running the tests, concatenating and
minifying the main libraries and generating the html 
documentation.

Tree
----
The following directories are present (some only after the
grunt build):
  /src  - The JavaScript Apache Thrift source
  /doc  - HTML documentation
  /dist - Distribution files (thrift.js and thrift.min.js)
  /test - Various tests, this is a good place to look for
          example code
  /node_modules - Build support files installed by npm


Example JavaScript Client and Server
------------------------------------
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 
### build with: $ thrift -gen js -gen js:node hello.thrift
    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.TXHRTransport("/hello");
            var protocol  = new Thrift.TJSONProtocol(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 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: thrift.TBufferedTransport,
      protocol: thrift.TJSONProtocol,
      processor: hello_svc,
      handler: hello_handler
    };
    
    var server_opt = {
      staticFilePath: ".",
      services: {
        "/hello": hello_svc_opt
      }
    }
    
    var server = Thrift.createWebServer(server_opt);
    var port = 9099;
    server.listen(port);
    console.log("Http/Thrift Server running on port: " + port);

