如何使SuggestBox在GWTP(Gwt平台)框架中可靠地RPC调用服务器数据库?

时间:2013-06-22 12:59:33

标签: gwt gwt-rpc gwt-platform gwtp

我花了很多时间来搜索这个信息“如何使SuggestBox可靠地在GWTP(Gwt平台)框架中对服务器数据库进行RPC调用”,但找不到任何答案。

事实上,有一些答案,但它们适用于不使用GWTP的人。例如,我找到了一个网站(http://jagadesh4java.blogspot.com.au/2009/03/hi-every-one-this-is-my-first-blog.html),指导代码SuggestBox& RPC&它暗示了这些课程:


    -Client Side:
    + interface SuggestService extends RemoteService
    + interface SuggestServiceAsync
    + class Suggestions implements IsSerializable, Suggestion
    + class SuggestionOracle extends SuggestOracle

    -Server Side:
    + class SuggestServiceImpl extends RemoteServiceServlet implements
    SuggestService

我试图跟进该网站,但我收到了错误:


    [WARN] failed SelectChannelConnector@127.0.0.1:8888
    java.net.BindException: Address already in use: bind..........

上述指南显然不适用于使用GWTP的用户。

我的任务是我有一个包含200k英文单词的词典&我想要一个建议框,当用户输入任何字符或单词时,它会查找到DB&因此建议。例如,当用户键入“c”时会显示“猫,车,切割等”,在输入“汽车”时会显示“汽车服务”,“碳”等。

所以我提出了自己的解决方案,即使它有效,但我觉得我做得不对。我的解决方案非常简单,我只需将数据从DB下载并放大。将它们添加到MultiWordSuggestOracle中。每当它在DB中找到一个单词列表时,它就不会清除旧数据,只是继续将新列表添加到MultiWordSuggestOracle中。但是,每次用户键入char时,我的程序都不会经常调用DB,但只有在wordInTheMultiWordSuggestOracleList.indexOf(suggestBox.getText(),0)>0时才会调用DB。但是,无法在MultiWordSuggestOracle中循环每个字符串,因此我使用List<String> accumulatedSuggestedWordsList=new ArrayList<String>()来存储数据。请参阅前文:

    private final MultiWordSuggestOracle mySuggestions = new MultiWordSuggestOracle();
    private List<String> accumulatedSuggestedWordsList=new ArrayList<String>();

    private void updateSuggestions(List<String> suggestedWordsList) {
        // call some service to load the suggestions
        for(int i=0;i<suggestedWordsList.size(); i++){
            mySuggestions.add(suggestedWordsList.get(i));
            accumulatedSuggestedWordsList.add(suggestedWordsList.get(i));
        }
    }

    @Override
    protected void onBind() {
        super.onBind();

        final SuggestBox suggestBox = new SuggestBox(mySuggestions);

        getView().getShowingTriplePanel().add(suggestBox);


        suggestBox.addKeyDownHandler(new KeyDownHandler(){

            @Override
            public void onKeyDown(KeyDownEvent event) {
                // TODO Auto-generated method stub
                String word=suggestBox.getText();
                int index=-1;
                for(int i=0; i<accumulatedSuggestedWordsList.size();i++){
                    String w=accumulatedSuggestedWordsList.get(i);
                    index=w.indexOf(word,0);
                    if(index>0)
                        break;
                }
                if(index==0 || index==-1){
                    GetWordFromDictionary action=new      tWordFromDictionary(suggestBox.getText());
                    action.setActionType("getSuggestedWords");
                    dispatchAsync.execute(action, getWordFromDictionaryCallback);
                }

            }


        });
    }
    private AsyncCallback<GetWordFromDictionaryResult> getWordFromDictionaryCallback=new AsyncCallback<GetWordFromDictionaryResult>(){

        @Override
        public void onFailure(Throwable caught) {
            // TODO Auto-generated method stub

        }

        @Override
        public void onSuccess(GetWordFromDictionaryResult result) {
            // TODO Auto-generated method stub
            List<String> suggestedWordsFromDictionaryList=result.getSuggestedWordsFromDictionaryList();
            updateSuggestions(suggestedWordsFromDictionaryList);

        }

    };

结果:它有效,但只有在我输入“Backspace”按钮时才显示建议。例如,当我输入单词“car”然后没有建议的列表弹出窗口时,它只会弹出“汽车服务,汽车销售等”,当我点击退格按钮时。

那么,你可以评估我的解决方案吗?我觉得我做得不对。如果我做得不对,你可以为GWTP框架提供一个SuggestBox PRC吗?



非常重要的注意事项:

如何构建可靠的SuggestBox PRC,以防止我们自己的服务器上的拒绝服务攻击?

如果许多人在快速输入建议框中产生了过多的电话怎么办?

其实我刚发现一个错误: SQL例外:数据源拒绝建立连接,来自服务器的消息:“连接太多” - &gt;所以我的解决方案一定有问题

我知道为什么我收到“Too many connections”错误。例如,当我在“建议”框中键入“ambassador”时,&amp;我看到我的服务器连续9次拨打Db。 第1次调用,它将搜索任何单词,如'a%' 在第二次通话时,它会搜索任何像'am%'这样的单词 -3,电话,它将搜索任何像'amb%'

这样的单词

第一个问题是它一次创建了太多的调用,第二个问题是第一次调用like 'a%'可能已经包含将在第二次like 'am%'调用的单词时无效。它复制数据。问题是如何编码以避免这种无效。

有人建议使用RPCSuggestOracle.java(https://code.google.com/p/google-web-toolkit-incubator/source/browse/trunk/src/com/google/gwt/widgetideas/client/RPCSuggestOracle.java?spec=svn1310&r=1310

如果您可以提供使用RPCSuggestOracle.java的示例,那将非常棒。 我希望你的回答能够帮助很多其他人。

2 个答案:

答案 0 :(得分:0)

有一篇来自Lombardi Development的旧的鼓舞人心的博客文章,我记得几乎解决了你正在寻找的所有问题。我花了一段时间才找到它,但幸运的是,它已经被移动了!资料来源可用。 Have a look

虽然年纪不大,但该帖子中的内容仍然适用。特别是:

  • 使用单个连接以避免请求爆炸,并释放其他任务用于其他任务(即避免使用所有2到8个最大并行浏览器http连接);
  • 重复使用先前请求中的数据(例如,如果您的请求是前一个请求的子字符串,您可能已经有了建议,因此只需在客户端过滤它们。)

我想到的其他事情是:

  • 使用Timer来模拟快速写入器的一点延迟,所以你只需要稍微调用服务器(可能是过度优化,但仍然是个想法);
  • 仅允许在最小输入长度(例如,最少3个字符)上获取建议。如果你有很多可能的建议,那么返回的数据即使是解析也可能很昂贵,特别是如果 - 对于搜索 - 你决定采用 contains 而不是策略开始;
  • 如果您仍有大量建议,可以尝试实施延迟加载SuggestionDisplay,只显示第一个,比如50个建议,然后滚动,所有其他建议使用增量方式相同的输入字符串。

无法从GWTP部分说出任何内容,我从未使用过它。但AFAICS似乎就像旧的gwt-dispatch一样,GWT-RPC +调度机制(命令模式)。不应该难以使用而不是香草GWT-RPC。

另请参阅上面其中的其他2篇文章。可能包含一些其他有用的提示。

答案 1 :(得分:0)

使用key Up处理程序代替按键处理程序可能会解决您的问题。 这是因为在渲染角色之前会触发keyDown事件。