Skip to content

Latest commit

 

History

History
178 lines (150 loc) · 5.45 KB

javafx-netty-communication.md

File metadata and controls

178 lines (150 loc) · 5.45 KB

页面如何将用户信息传递给服务端

UI组件的介绍

  • UIObject:继承于Stage的一个抽象类,用于用户视图扩展
  • Controller:基础于UIObject,代表一个自定义视图
  • Method:定义视图上可以进行的操作
  • EventRegister:用于视图上元素的事件注册
  • IEvent:定义事件可以进行的操作

ui类结构

ui类结构UML图

  1. Controller通过EventRegister进行页面元素的事件注册
  2. EventRegisterIEvent注册为页面元素上的事件回调函数
  3. IEvent的实现类DemoEvent可以操纵channelnetty服务端进行通信

以上组件的简单流程图如下:

// 注册元素事件
controller -> init -> EventRegister.registerEvent -> element.setOnAction
  
// 元素事件响应
elemnt -> onAction -> event -> channel -> netty server

示例

场景:编写一个页面,点击页面上的退出按钮向netty服务端发送退出房间信号

  1. 编写一个demo.fxml视图文件
<AnchorPane xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
   <children>
      <Button fx:id="quitButton">退出房间</Button>
   </children>
</AnchorPane>    
  1. 编写一个Controller用于视图展示
public class Controller extends UIObject implements Method {
    private IEvent event;
    private EventRegister demoEventRegister;

     public Controller(IEvent event) throws IOException {
        super();

        // 加载fxml视图文件
        root = FXMLLoader.load(getClass().getClassLoader().getResource("demo.fxml"));
        setScene(new Scene(root));

        this.roomEvent = roomEvent;

        // 注册元素事件
        registerEvent();
    }
    
    @Override
    public void registerEvent() {
        demoEventRegister = new DemoEventRegister(this, event);
    }
}
  1. 编写一个Event用于事件处理
public interface Event {
    void quit();
}

public class DemoEvent implements Event {
    @Override
    public void quit() {
        // 获取channel,通过工具类向netty服务端发送退出房间信号
        Channel channel = BeanUtil.getBean("channel");
        ChannelUtil.pushToServer(channel, ServerEventCode.CODE_CLIENT_EXIT, null);
    }
}
  1. 编写一个EventDefiner用于页面元素事件注册
public class DemoEventRegister implements EventRegister {

    private UIObject uiObject;
    private IEvent event;

    public DemoEventRegister(UIObject uiObject, IEvent event) {
        this.uiObject = uiObject;
        this.event = event;

        registerEvent();
    }

    @Override
    public void registerEvent() {
        quitRoom();
    }
    
    private void quitRoom() {
        // 为退出按钮设置点击事件回调函数
        uiObject.$("#quitButton", Button.clas).setOnAction(e -> event.quit());
    }
}

服务端如何将信息传递给页面

如果您还不清楚netty服务端和netty客户端之间的事件通信,请先阅读ratel部分协议

编写客户端事件监听器

编写自己的事件监听器,设置感兴趣的服务端事件编码,当对应事件出现时,会执行事件监听器中的代码。实现ClientListener或者继承AbstractClientListener编写自己的客户端事件监听器:

public class ClientExitListener extends AbstractClientListener {

    public ClientExitListener() {
        // 设置感兴趣的服务端事件编码(CODE_CLIENT_EXIT 客户端退出事件编码)
        super(ClientEventCode.CODE_CLIENT_EXIT);
    }

    /**
     * 事件处理业务
     * @param channel   客户端通信channel
     * @param json      事件数据
     */
    @Override
    public void handle(Channel channel, String json) {
        // do something ...
    }
}

在客户端事件监听器中改变页面

每一个客户端事件监听器中都有uiService属性,通过uiService可以获取各个Method对页面进行操作:

@Override
public void handler(Channel channel, String json) {
    Method method = uiService.getMethod(Controller.METHOD_NAME);
    
    // 一定要在javafx线程中进行视图的更改
    Platform.runLater(() -> method.updateView(json));
}

示例

场景:客户端退出后服务端向客户端发送退出成功事件响应,客户端接收事件后弹出弹框提示退出成功。

  1. 编写一个Method定义视图的弹出弹框行为
public interface Method {
    void alert(String message);
}

public class Controller extends UIObject implements Method {
    private static final String METHOD_NAME = "method";

    @Override
    public void alert(String message) {
        Alert alert = new Alert(Alert.AlertType.INFORMATION);
        alert.setContentText(message);
        alert.showAndWait();
    } 
}
  1. 编写一个客户端事件监听器
public class ClientExitListener extends AbstractClientListener {

    public ClientExitListener() {
        // 设置感兴趣的服务端事件编码(CODE_CLIENT_EXIT 客户端退出事件编码)
        super(ClientEventCode.CODE_CLIENT_EXIT);
    }

    /**
     * 事件处理业务
     * @param channel   客户端通信channel
     * @param json      事件数据
     */
    @Override
    public void handle(Channel channel, String json) {
        Method method = uiService.getMethod(Controller.METHOD_NAME);
        
        Platform.runLater(() -> method.alert(json));
    }
}