簡體   English   中英

使用Javascript客戶端的Thrift Java服務器OutOfMemoryError

[英]Thrift Java server OutOfMemoryError with Javascript client

我昨天開始學習節儉。

經過大量的努力,我成功地執行了Java教程。 Java服務器和客戶端運行正常。

但現在,我想要一個javascript客戶端與Java Thrift服務器進行通信。

為此,我將所有js文件移動到js/文件夾中。

並粘貼index.html代碼如下:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <title>Thrift Javascript Bindings - Tutorial Example</title>

  <script src="js/thrift.js"  type="text/javascript"></script>
  <script src="js/tutorial_types.js"    type="text/javascript"></script>
  <script src="js/shared_types.js"      type="text/javascript"></script>
  <script src="js/SharedService.js"     type="text/javascript"></script>
  <script src="js/Calculator.js"        type="text/javascript"></script>

  <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>


  <script type="text/javascript" charset="utf-8">
  //<![CDATA[
  $(document).ready(function(){
    // remove pseudo child required for valid xhtml strict
    $("#op").children().remove();
    // add operations to it's dropdown menu
    $.each(Operation, function(key, value) {
      $('#op').append($("<option></option>").attr("value",value).text(key)); 
    });

     $('table.calculator').attr('width', 500);
  });

  function calc() {
    var transport = new Thrift.Transport("http://localhost:9090");
    var protocol  = new Thrift.Protocol(transport);
    var client    = new CalculatorClient(protocol);

    var work = new Work()
    work.num1 = $("#num1").val();
    work.num2 = $("#num2").val();
    work.op = $("#op").val();

    try {
      result = client.calculate(1, work);
      $('#result').val(result);
      $('#result').css('color', 'black');
    } catch(ouch){
      $('#result').val(ouch.why);
      $('#result').css('color', 'red');
    }
  }

  function auto_calc() {
    if ($('#autoupdate:checked').val() !== undefined) {
      calc();
    }
  }
  //]]>
  </script>

</head>
<body>
  <h2>Thrift Javascript Bindings</h2>
  <form action="">
  <table class="calculator">
    <tr>
      <td>num1</td>
      <td><input type="text" id="num1" value="20" onkeyup="javascript:auto_calc();"/></td>
    </tr>
    <tr>
      <td>Operation</td>
      <td><select id="op" size="1" onchange="javascript:auto_calc();"><option></option></select></td>
    </tr>
    <tr>
      <td>num2</td>
      <td><input type="text" id="num2" value="5" onkeyup="javascript:auto_calc();"/></td></tr>
    <tr>
      <td>result</td>
      <td><input type="text" id="result" value=""/></td></tr>
    <tr>
      <td><input type="checkbox" id="autoupdate" checked="checked"/>autoupdate</td>
      <td><input type="button" id="calculate" value="calculate" onclick="javascript:calc();"/></td>
    </tr>
  </table>
  </form>

  <p>This Java Script example uses <a href="https://git-wip-us.apache.org/repos/asf?p=thrift.git;a=blob;f=tutorial/tutorial.thrift;hb=HEAD">tutorial.thrift</a> and a Thrift server using JSON protocol and HTTP transport.
  </p>
    <p>
        <a href="http://validator.w3.org/check/referer"><img
            src="http://www.w3.org/Icons/valid-xhtml10"
            alt="Valid XHTML 1.0!" height="31" width="88" /></a>
    </p>
</body>
</html>

我換了線

var transport = new Thrift.Transport("/thrift/service/tutorial/");

var transport = new Thrift.Transport("http://localhost:9090");

因為,我的服務器在端口9090上。而/thrift/service/tutorial對我來說沒有任何意義,它既不工作也沒有。

然后,當我打開我的頁面。

Java thrift服務器崩潰,出現以下錯誤:

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
    at org.apache.thrift.protocol.TBinaryProtocol.readStringBody(TBinaryProtocol.java:339)
    at org.apache.thrift.protocol.TBinaryProtocol.readMessageBegin(TBinaryProtocol.java:202)
    at org.apache.thrift.TBaseProcessor.process(TBaseProcessor.java:27)
    at org.apache.thrift.server.TSimpleServer.serve(TSimpleServer.java:83)
    at thrift.server.CalculatorServer.main(CalculatorServer.java:23)

這是CalculatorServer java類。

package thrift.server;

import org.apache.thrift.server.TServer;
import org.apache.thrift.server.TServer.Args;
import org.apache.thrift.server.TSimpleServer;
import org.apache.thrift.transport.TServerSocket;
import org.apache.thrift.transport.TServerTransport;
import org.apache.thrift.transport.TTransportException;

import tutorial.Calculator;

public class CalculatorServer {

    public static void main(String[] args) {
        CalculatorHandler handler = new CalculatorHandler();
        Calculator.Processor<CalculatorHandler> processor = new Calculator.Processor<>(handler);        

        try {
            TServerTransport serverTransport = new TServerSocket(9090);
            TServer server = new TSimpleServer(new Args(serverTransport).processor(processor));

            System.out.println("Starting the simple server...");
            server.serve();
        } catch (TTransportException e) {
            e.printStackTrace();
        }
    }

}

其余代碼用於Thrift教程。 事實上,Java Thrift服務器與Java Thrift客戶端完美配合。 我認為Java Server端沒有任何問題。

任何人都可以說出了什么問題嗎?

Javascript客戶端有什么替代方案嗎?

我正在使用thrift在我的Java SE應用程序和本地計算機上的網站之間進行通信。 所以,我可以使用HTML + CSS + JS開發我的GUI,而不是使用Java Swing。

我一直在尋找一種在聚合物javascript中使用thrift的簡單方法。 最后,這是我用三天時間分析其他解決方案之后的解決方案。 他們在哪里工作,但他們都需要從我的http:// localhost:8088 / view.html請求中讀取view.html本地位置文件。 我發現這很昂貴,因為我同時使用谷歌應用程序引擎和計算引擎。 我無法在應用程序引擎上找到本地目錄,所以這就是做了什么。

  1. 寫你的java服務器就像這樣
  2. 像這樣寫你的聚合物元素

     <dom-module id="thrift-client"> <template> </template> <script> Polymer({ is:'thrift-client', ready:function(){ var transport = new Thrift.TXHRTransport("http://localhost:8088/service"); var protocol = new Thrift.TJSONProtocol(transport); var client = new NtvApiClient(protocol); var result = client.ping(); // ping the java server. custom console.log(result); } }); </script> 

  3. 請注意, http:// localhost可以更改為http:// Your_server_ip_address

  4. 請確保java服務器的檢查點完全命名為service

  5. bravo,我們現在只需從javascript Web客戶端訪問java服務器,而無需提供任何文件路徑。

  6. 請注意,有了這個,你可以很容易地使用普通的js。 像這樣

      var transport = new Thrift.TXHRTransport("http://localhost:8088/service"); var protocol = new Thrift.TJSONProtocol(transport); var client = new NtvApiClient(protocol); var result = client.ping(); 

    干杯。

默認'TTransport'不是基於http協議的服務器。 如果你想使用http作為通信協議,這似乎是客戶端js的唯一方法,你應該使用基於http的'TTransport'。 看看'org.apache.thrift.server.TServlet',這是在servlet中構建基於http的thrift服務器的簡單方法。

您還應該在服務器端使用'TJSONProtocol'而不是'TBinaryProtocol',因為thrift js無法很好地處理二進制數據。 這是我以前用過的代碼片段。

public class CalculatorServlet extends TServlet 
{
   public CalculatorServlet() 
   {
      //'Calculator' is the generated class from thrift, 
      //'CalculatorHandler' is the implement class for thrift rpc
      super(new Calculator.Processor(
            new CalculatorHandler()),
            new TJSONProtocol.Factory());
  }
}

IIRC,JavaScript僅支持JSON協議。 這(當然)與二進制不兼容。

因此, 解決方案是:在服務器中使用JSON協議而不是二進制協議

Thrift的一個經驗法則是, 總是在兩端使用相同的傳輸/協議棧 在這個特殊情況下,這意味着:

  • HTTP服務器
  • JSON協議
  • 沒有額外的framed協議(緩沖將工作,順便說一句)

(有一些例外,因為某些服務器類型本質上需要框架,但這是另一個故事並且與您的問題無關)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM