Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2008/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
GWT如何减少RPC调用的代码序列化程序的大小_Gwt_Gwt Rpc - Fatal编程技术网

GWT如何减少RPC调用的代码序列化程序的大小

GWT如何减少RPC调用的代码序列化程序的大小,gwt,gwt-rpc,Gwt,Gwt Rpc,我发现GWT在我的应用程序上生成的javaScript代码中有60%以上是用于RPC序列化程序的。 我还发现服务接口之间不共享序列化程序,我的意思是,如果我在2个rpc服务接口上引用了AccountDTO类型,那么对于同一类型,我将得到2个序列化程序类,而不是1个。 为了减少编译代码的大小,我在想,也许我可以使用延迟绑定来替换一个大接口中的所有服务接口。如果这是可能的,那么GWTCompiler将只生成一个AccountDTO序列化程序,而不是2个 我不确定这是否是一个好主意,也不确定是否有更好

我发现GWT在我的应用程序上生成的javaScript代码中有60%以上是用于RPC序列化程序的。 我还发现服务接口之间不共享序列化程序,我的意思是,如果我在2个rpc服务接口上引用了AccountDTO类型,那么对于同一类型,我将得到2个序列化程序类,而不是1个。 为了减少编译代码的大小,我在想,也许我可以使用延迟绑定来替换一个大接口中的所有服务接口。如果这是可能的,那么GWTCompiler将只生成一个AccountDTO序列化程序,而不是2个

我不确定这是否是一个好主意,也不确定是否有更好的方法解决我的问题

我试图实现的是这样的:

// Define new interface that extends all service interfaces
public interface GenericService extends RemoteService,
                    AccountingService,
                    FinancialService,..., { }

public interface GenericServiceAsync extends AccountingServiceAsync,
                         FinancialServiceAsync, ..., { }

// At Application.gwt.xml do:

<module>
...
...
    <replace-with class="com.arballon.gwt.core.client.GenericService">
        <when-this-is class="com.arballon.gwt.core.client.AccountingService>
    </replace-with>
    <replace-with class="com.arballon.gwt.core.client.GenericService">
        <when-this-is class="com.arballon.gwt.core.client.FinancialService>
    </replace-with>
    ...
    ...
package com.arballon.gwt.core.client;

import com.google.gwt.user.client.rpc.RemoteService;

public interface GenericBigService extends RemoteService,
                                       AccountingService,
                                       ActionClassifierService,
                                       AFIPWebService,
                                       AnalyticalService,
                                       AuthorizationService,
                                       BudgetService,
                                       BusinessUnitService,
                                       CatalogPartService,
                                       CategoryService,
                                       ClientDepositService,
                                       .....
                                       .....
{ }
public interface FinancialPeriodBalanceCategoryService extends RemoteService {
    /**
 * Utility class for simplifying access to the instance of async service.
 */
public static class Util {
    private static FinancialPeriodBalanceCategoryServiceAsync instance;
    public static FinancialPeriodBalanceCategoryServiceAsync getInstance() {
        if (instance == null) {
            instance = GWT.create(GenericBigService.class);
((ServiceDefTarget)instance).setServiceEntryPoint(GWT.getModuleBaseURL()+"FinancialPeriodBalanceCategoryService");
        }
        return instance;
    }
}
//定义扩展所有服务接口的新接口
公共接口GenericService扩展了RemoteService,
会计服务,
金融服务,{}
公共接口GenericServiceAsync扩展AccountingServiceAsync,
金融服务同步,{}
//在Application.gwt.xml上执行以下操作:
...
...
...
...
但在我收到错误的那一刻:

“文件:/C:/Users/Daniel/EclipseWorkspace/ADK/src/com/arballon/gwt/core/client/FinancialService.java”中的[ERROR]错误 [错误]第31行:找不到重新绑定结果'com.arballon.gwt.core.client.GenericService'

如果您对这个问题有任何想法,我们将不胜感激。 问候


Daniel据我所知,GWT代码生成应该提供接口的具体实现。然后将此实现转换为javascript以进行特定排列

另一方面,您的示例正在用另一个接口替换一个接口。如果从GWT编译器的角度来看,您可能会看到此配置的问题

假设您是GWT编译器,您将在客户端代码中看到下面一行代码,并将其转换为JavaScript

AccountingServiceAsync accountingServiceAsync = (AccountingServiceAsync) GWT.create(AccountingService.class);
accountingServiceAsync.recordTransaction(transaction,callback);
因此,您需要在第2行了解应该发生什么。具体来说,您需要知道在哪里可以找到accountingServiceAsync.recordTransaction()的实现。因此,您需要查看所有配置,以确定是否有规则指定AccountingService(非异步)应使用哪个实现类。但遗憾的是你找不到。但是您注意到AccountingService也是一个远程服务。因此,您需要再次深入了解您的配置。而且,啊哈,这是一条规则,规定你可以。您很高兴地将提供AccountingService实现的任务移交给ServiceInterfaceProxyGenerator

但是,假设您的配置告诉您AccountingService可以是GenericService,而不是这个圆满的结局,您会说,“嘿,酷,开始吧”。但就在这时,您发现GenericService也是一个接口。显然,你会被关闭,说“现在,我要用另一个接口做什么,我所需要的只是AccountingService的实现”。在这一点上,你想通过向程序员抛出一个神秘的错误来报复他


到目前为止,所有这些都解释了为什么你的解决方案(理论上)不起作用。至于您对臃肿javascript的实际关注,我很惊讶,考虑到GWT人员在优化已编译javascript方面付出的努力,这个问题竟然存在。您是如何测试编译的输出的重复性的?

对于任何GWT-RPC服务,GWT都将生成一个代理和一个TypeSerializer。对于可能通过GWT传递的每个对象,您将有一个FieldSerializer类。每个类只能有一个FieldSerializer。因此,一个AccountDTO不能有两个FieldSerializer

您尝试使用的延迟绑定规则将不起作用。例如,您有如下内容: MyServiceAsync sync=GWT.create(MyService.class)

延迟绑定规则将其更改为:

MyServiceAsync sync=new myServiceAsyncu Proxy()

您的规则实际上会执行以下操作:

// Define new interface that extends all service interfaces
public interface GenericService extends RemoteService,
                    AccountingService,
                    FinancialService,..., { }

public interface GenericServiceAsync extends AccountingServiceAsync,
                         FinancialServiceAsync, ..., { }

// At Application.gwt.xml do:

<module>
...
...
    <replace-with class="com.arballon.gwt.core.client.GenericService">
        <when-this-is class="com.arballon.gwt.core.client.AccountingService>
    </replace-with>
    <replace-with class="com.arballon.gwt.core.client.GenericService">
        <when-this-is class="com.arballon.gwt.core.client.FinancialService>
    </replace-with>
    ...
    ...
package com.arballon.gwt.core.client;

import com.google.gwt.user.client.rpc.RemoteService;

public interface GenericBigService extends RemoteService,
                                       AccountingService,
                                       ActionClassifierService,
                                       AFIPWebService,
                                       AnalyticalService,
                                       AuthorizationService,
                                       BudgetService,
                                       BusinessUnitService,
                                       CatalogPartService,
                                       CategoryService,
                                       ClientDepositService,
                                       .....
                                       .....
{ }
public interface FinancialPeriodBalanceCategoryService extends RemoteService {
    /**
 * Utility class for simplifying access to the instance of async service.
 */
public static class Util {
    private static FinancialPeriodBalanceCategoryServiceAsync instance;
    public static FinancialPeriodBalanceCategoryServiceAsync getInstance() {
        if (instance == null) {
            instance = GWT.create(GenericBigService.class);
((ServiceDefTarget)instance).setServiceEntryPoint(GWT.getModuleBaseURL()+"FinancialPeriodBalanceCategoryService");
        }
        return instance;
    }
}
MyServiceAsync sync=新建MyGenericService()//无效,因为MyGenericService是一个接口

因此,您的解决方案将不起作用

既然您说应用程序生成的代码中有60%是与RPC相关的东西,我怀疑您有RPC类型爆炸的问题


检查GWT在编译过程中是否没有抛出任何警告,或者是否为RPC类型序列化程序生成存根,很可能您在服务中有一些非常常见的接口。

GWT的RPC生成代码构建了几个类来完成它的工作,正如您所指出的那样:一个
*\u FieldSerializer
用于连接的每种类型,以及用于RemoteService异步类型的
*\u代理
类。该代理类型需要一个
*\u TypeSerializer
,这是问题的根源-出于某种原因,GWT将所有序列化/反序列化方法连接在一个string->js函数映射中,可能是为了方便快速查找-但此设置代码以需要在最终构建中的代码行为代价。更优化的方法可以让每个
FieldSerializer
都有一个注册方法,将其方法添加到代理所拥有的静态映射中-然而,这是一个难题,但是GWT优化了尝试不引用
实例化()
反序列化()
序列化()
方法如果不出现,将调用它们

您的问题源于具有许多可以序列化的类型,以及您试图构建每个描述特定功能单元的
RemoteService
类型,但重复使用了许多模型类型。这是一个令人钦佩的目标,特别是因为它可能会使您的服务器端代码看起来更好,但显然GWT为此咬了您一口

我试图在freenode上为您提供的解决方案