简体   繁体   English

客户端=>与Vaadin + GWT的服务器通信

[英]Client => Server communication with Vaadin + GWT

I'm developing a GWT widget for an existing vaadin application and so far everything has worked out fine, until I needed to call a server-side function from the client and get a value from it to the client. 我正在为现有的vaadin应用程序开发GWT窗口小部件,到目前为止一切工作都很好,直到需要从客户端调用服务器端函数并从中获取值为止。

more detailed issue: There is a server-side function that gets certain values from a connected database. 更详细的问题:有一个服务器端函数可从连接的数据库中获取某些值。 Now I want to get access this function from the client-side, since I need the values to update something in the widget. 现在,我想从客户端访问此功能,因为我需要这些值来更新小部件中的某些内容。

According to Vaadin and GWT documentations you're supposed to use RPC for this, and I already implemented multiple functions on the server-side that bascially do the opposite (send something from the server to the client, initiate a call of a client function from server code etc.) 根据Vaadin和GWT文档,您应该为此使用RPC,并且我已经在服务器端实现了多个功能,而这些功能基本上是相反的(将某些内容从服务器发送到客户端,从客户端调用客户端功能服务器代码等)

From my understanding I'm supposed to call a void return function on the server by using rpc (the part I can't get to work) then I could make that function on the server use a server=>client rpc to send that value back to the client (already working) 根据我的理解,我应该使用rpc在服务器上调用void返回函数(这是我无法工作的部分),然后我可以使服务器上的该函数使用server => client rpc发送该值回到客户(已经工作)

Is this the definite solution and if so how do I properly implement the client=>server part and if not, what would be a good solution? 这是绝对的解决方案吗?如果是的话,如何正确实现client => server部分?如果不是,那么什么是好的解决方案?

I've already tried something like https://vaadin.com/wiki/-/wiki/Main/Sending+events+from+the+client+to+the+server+using+RPC but somehow can't figure out how to call the method while in the widget class and not in the connector class There just seems to be something missing? 我已经尝试过类似https://vaadin.com/wiki/-/wiki/Main/Send+events+from+the+client+to+the+server+using+RPC的方法,但是不知如何解决在widget类而不是connector类中调用该方法似乎缺少了一些东西? and is this even the right approach? 这甚至是正确的方法吗?

parts of the current code: 当前代码的一部分:

DrawwServerRPC DrawwServerRPC

public interface DrawwServerRPC extends ServerRpc {
   public void updateE(String e);
}

relevant part of Draww.java on server 服务器上Draww.java的相关部分

protected DrawwServerRPC = new DrawwServerRPC () {
    public void updateE(String e){
        // gets some values from a db and then sends them back to the client 
        // via rpc (both points working fine)
    }
};

public Draww() {
    registerRpc(rpc);
}

part of the connector class, this is supposed to be called when a specific method in the DrawwWidget class (client) is called, instead of on a click 连接器类的一部分,应该在调用DrawwWidget类(客户端)中的特定方法时调用它,而不是单击

getWidget().addClickHandler(new ClickHandler() {
        public void onClick(ClickEvent event) {
            final MouseEventDetails mouseDetails = MouseEventDetailsBuilder
                .buildMouseEventDetails(event.getNativeEvent(),
                            getWidget().getElement());
            rpc.updateE("test");
        }
    });

So my main issue is, how do I now properly access this method (most likely over the connector method) when a specific function in the DrawwWidget class on the Client is called? 所以我的主要问题是,当在客户端上的DrawwWidget类中调用特定功能时,我现在应该如何正确访问此方法(很可能是通过连接器方法)?

And how do I then pass the value from the client method to the connector (or even server side) method? 然后,如何将值从客户端方法传递到连接器(甚至服务器端)方法? => need to somehow call the updateE method on the server from client side code (by using connector/rpc) =>需要以某种方式从客户端代码(通过使用connector / rpc)调用服务器上的updateE方法

edit : so here is a bit longer explanation of how I solved it in the end according to the idea I got from Mika's answer and this 编辑 :所以这是根据我从米卡的答案得到的想法,最后如何解决它的更长的解释,

added an Interface 添加了一个接口

public interface customListener {
    void customEvent (String s);
}

adjusted the DrawwWidget: 调整了DrawwWidget:

public class DrawwWidget extends Label{
private customListener MyListener;
//...
private void someFunction() {
    String something = ...;
    if (myListener != null) myListener.customEvent(something);
    }

public void setMyListener(customListener listener) {
    this.myListener = listener;
    }

}

and finally implemented the listener in the connector class: 最后在连接器类中实现了侦听器:

public class DrawwConnector extends AbstractComponentConnector implements customListener {
DrawwServerRpc rpc = RpcProxy.create(DrawwServerRpc.class, this);
public DrawwConnector () {
    //lots of irrelevant Server => Client rpc things
    getWidget().setMyListener(this);
}

@Override
public void customEvent(String s) {
    rpc.doSomething(s);
}

Now I can call the server side "doSomething" method from wherever I want in the widget by using the "customEvent (String s)" Method 现在,我可以使用“ customEvent(String s)”方法从小部件中的任何位置调用服务器端的“ doSomething”方法

You can interact with client side with custom widgets or javascript extensions. 您可以使用自定义窗口小部件或javascript扩展与客户端进行交互。 For visible components custom widget is usually suitable solution. 对于可见组件,自定义小部件通常是合适的解决方案。

You can follow similar convention in client side as Vaadin generally follows in server side and register a listener from connector to your widget. 您可以在客户端遵循类似的约定,就像Vaadin通常在服务器端遵循的约定一样,并从连接器向小部件注册一个侦听器。 For example: 例如:

@Override
protected Widget createWidget() {
    MyWidget widget = GWT.create(MyWidget.class);
    widget.addMyListener(new MyListener() {
        @Override
        public void onSomeEvent(ClientData data) {
            rpc.onEventFromClient(data);
        }
    });
    return widget;
}

Widget is a GWT component and usually you can find some existing GWT component that you can extend. 小部件是GWT组件,通常您可以找到一些可以扩展的现有GWT组件。 If not, then it is possible to create plain HTML elements from the widget, good reference for this is the source code for existing GWT components. 如果不是,则可以从小部件创建纯HTML元素,对此的良好参考是现有GWT组件的源代码。

Here is an example of a widget that has a text and you can click on the widget. 这是一个具有文本的窗口小部件的示例,您可以单击该窗口小部件。

import com.google.gwt.user.client.ui.Label;
// ... only relevant imports included
public class MyWidget extends Label {
    private List<MyListener> listeners = new ArrayList<MyListener>();

    public MyWidget() {
        addStyleName("m-my-label");
        // Add GWT event listeners for events that you want to capture.
        addClickHandler(new ClickHandler() {
            @Override
            public void onClick(ClickEvent event) {
                notifyListeners();
            }
        });
    }

    private void notifyListeners() {
        for (MyListener listener : listeners) {
            listener.onSomeEvent(new ClientData("Hello from widget"));
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM