<!--
 * 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.
-->
<!DOCTYPE html>
<html lang="en">
<head>
    <title>Apache Thrift JavaScript Browser Client Demo</title>
    <script src="thrift.js" type="text/javascript"></script>
    <script src="gen-js/HelloSvc.js" type="text/javascript"></script>
    <script src="gen-js/TimesTwo.js" type="text/javascript"></script>
</head>
<body>
    <h1>Apache Thrift JavaScript Browser Client Demo</h1>
    <p>This html file demonstrates Apache Thrift JavaScrpt RPC between a browser client to a node.js server. Clicking the button below will call the hello_func() hosted by the Apache Thrift server at localhost:8585. The file hello.js contains the JavaScript node.js server required. Here are the steps to get the example running:</p>
    <ol>
        <li>Install Node.js <pre><a href="http://nodejs.org">nodejs.org</a></pre></li>
        <li>Install Apache Thrift for node (note that the node package manager will create the node_modules folder in the current directory so make sure to run npm from the same directory as hello.js so that the server can find the Thrift libraries. This example requires Apache Thrift 0.9.2+) <pre>$ npm install thrift</pre></li>
        <li>Compile the hello.idl for JavaScript and Node.js (you'll need to have the Apache Thrift compiler installed for this step. This also needs to be executed in the same directory as hello.js because hello.js and hello.html look for the gen-nodejs and gen-js directories here.)<pre>$ thrift -gen js -gen js:node hello.thrift</pre></li>
        <li>Run the node server in the directory with the hello.html file<pre>$ node hello.js</pre></li>
        <li>Copy the Apache Thrift JavaScript library, thrift.js, into the directory with this html file.<pre>$ cp ...../thrift.js .</pre>
        <li>Reload this page in a browser through the node server using using the URL: <pre>http://localhost:8585/hello.html</pre>then click a button below to make an RPC call</li>
    </ol>
    <button id="btn">Get Message from Node Server</button>
    <button id="btnDbl">Double 25</button>
    <script type="text/javascript">
        document.getElementById("btn").addEventListener("click", getMessage, false);

        function getMessage() {
            var transport = new Thrift.Transport("http://localhost:8585/hello");
            var protocol  = new Thrift.Protocol(transport);
            var client = new HelloSvcClient(protocol);
            var msg = client.hello_func();
            document.getElementById("output").innerHTML = msg;
        }

        document.getElementById("btnDbl").addEventListener("click", dblMessage, false);

        function dblMessage() {
            var transport = new Thrift.Transport("http://localhost:8585/dbl");
            var protocol  = new Thrift.Protocol(transport);
            var client = new TimesTwoClient(protocol);
            var val = client.dbl(25);
            document.getElementById("output2").innerHTML = val;
        }
    </script>
    <h2>Server Response: <div id="output"></div></h2>
    <h2>Server Dbl: <div id="output2"></div></h2>
</body> 
</html>

