雪浪OS前后端对接 - xuelang-group/suanpan-docs GitHub Wiki

雪浪OS对接

1. 准确前端镜像

1.1 设置算盘变量占位符

修改项目代码,使得如下代码片段出现在前端打包后的 index.html 中。

<script>
    window.appConfig = {url: '{{host}}', appId: '{{appId}}', nodeId: '{{nodeId}}'}
</script>

对于使用 ant design pro 的项目,修改的方法是在 document.ejs 中添加。

1.2 Docker镜像

server.js 文件在使用 express 对外提供服务前,会依据算盘传入的命令行参数,替换 index.html 中的host, appId, nodeId 占位符。

前端使用的 Dockerfile 如下:

FROM registry.cn-shanghai.aliyuncs.com/shuzhi/base_express_server:1
WORKDIR /home/app/
COPY dist /home/app/dist
EXPOSE 7000
CMD tail -f /dev/null

使用的基础镜像为:registry.cn-shanghai.aliyuncs.com/shuzhi/base_express_server:1。

该镜像的代码可以参考:Base_Express_Server.zip

构建前端镜像的步骤如下:

  1. 编译前端项目源码,生成 dist 产物。
  2. 将 Dockerfile 与 dist 目录放置在同一个目录下
  3. docker build -f Dockerfile -t your_tag . (依据需求,替换your_tag)

构建完成后,可以将生成的镜像 push 到 Docker 镜像仓库,供设置算盘组件时使用。

2.初始化 sp 对象

前端通过 suanpan-sdk-js.min.js 中提供的 window.sp 对象,与后端在算盘上进行交互。

2.1 引入 sp 资源文件

<script src="/common_public/dashboard/suanpan-sdk-js.min.js"></script>

2.2 构造函数

window.spSocket = window.sp({
    url: window.appConfig.url,
    path: `/socket/${window.appConfig.appId}`
});

通过替换后的 url 以及 appId 生成 spSocket。

2.3 订阅消息

window.spSocket.subscribe({
    eventName: `call-${window.appConfig.nodeId}`,
    callback: function (data) {
        console.log(data);
    }
});

每当后端返回新消息,spSockert 的 subscribe 方法中 传入的 callback 就会被执行。

2.4 发送消息

const userInstalledData = {
    event: 'queryInstalledApps',
    data: { id: '123' }
}

window.spSocket.send({
    eventName: `call-${window.appConfig.nodeId}`,
    data: {
      success :true,
      out1: JSON.stringify(userInstalledData),
    }
});

spSocket 的 send 方法用于前端主动向后端传递消息。

例子中通过了一个 userInstalledData 对象,定义了与后台交互的信息格式。

  • event:封装了前端期待后端完成的任务
  • data:传递的数据

3. Java 后端

Java 后端使用 suanpan-java-sdk 对接算盘中基于 Redis stream 的消息队列。

suanpan-java-sdk 使用 Github 作为 maven 公网地址。

添加repo

<repositories>
    <repository>
        <id>RockingJavaBean-maven-master-repository</id>
        <name>RockingJavaBean-maven-master-repository</name>
        <url>https://raw.githubusercontent.com/RockingJavaBean/maven2/maven2/</url>
    </repository>

    ...
</repositories>

添加依赖

<dependency>
    <artifactId>com.xuelang</artifactId>
    <groupId>suanpan-java-sdk</groupId>
    <version>1.0.1</version>
</dependency>

使用 mvn 命令强制更新依赖

mvn clean
mvn package -U -Dmaven.test.skip=true

这是目前雪浪OS后端的代码,可以进行参考。

spos-backend.zip

下面会先介绍一下代码中如何与前端进行交互。

3.1 subscribeQueue

public class ApplicationStartup implements ApplicationListener<ApplicationReadyEvent> {

    @Autowired
    private GlobalEnv globalEnv;
    @Autowired
    private AliyunStoreOption aliyunStoreOption;
    @Autowired
    private StreamOption streamOption;
    @Autowired
    private MessageRecvHandler messageRecvHandler;
    @Autowired
    private UserAppService userAppService;

    private void subscribeToMq() {
        MqClient mqClient = streamOption.buildRedisClient();
        Consumer consumer = Consumer.builder()
                .queue(streamOption.getRecvQueue())
                .group(streamOption.getNodeGroup())
                .name(streamOption.getNodeId())
                .delay(streamOption.getRecvQueueDelay())
                .build();
        log.info("subscribe queue: {}, group: {}, consumer: {}",
                consumer.getQueue(), consumer.getGroup(), consumer.getName());

        mqClient.subscribeQueue(
                consumer,
                this.messageRecvHandler,
                new LogExceptionMessageHandler()
        );
    }

    @Override
    public void onApplicationEvent(ApplicationReadyEvent applicationReadyEvent) {
        loggingInputOptions();

        userAppService.syncInitialAppInformation();
        log.info("app data synced to aliyun oss");

        ExecutorService executorService = Executors.newFixedThreadPool(1);
        Future future = executorService.submit(this::subscribeToMq);
        try {
            future.get();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        executorService.shutdown();
    }

    private void loggingInputOptions() {
        ...
    }
}

当程序完成启动时,subscribeToMq 方法会被执行,监听消息队列。

当有新消息发送过来时,subscribeToMq 会将封装好的消息数据交给 MessageRecvHandler 进行处理。

3.2 MqEventDto

// com.xuelang.spos.mq.dto.MqEventDto
public class MqEventDto {
    public static final String EMPTY_EVENT = "empty_event";

    private String event = EMPTY_EVENT;

    private JSONObject data;
}

MqEventDto 与 2.4 节中的 userInstalledData 对应,用于接收前端传入的数据。

3.3 MessageRecvHandler

该类中的 dispatchEvent 依据传入 event 类型,将数据分发给不同的业务类进行处理。

  • 处理成功:使用 sendSuccessMessage 方法向队列发送成功信息,消息中包括了事件类型以及业务类返回的信息
  • 捕获异常:使用sendErrorMessage 方法向队列发送失败的消息
private void dispatchEvent(MqEventDto eventDto) {
        MqClient mqClient = streamOption.buildRedisClient();
        try {
            switch (eventDto.getEvent()) {
                case MqEventType.QUERY_INSTALLED_APP: {
                    String installedApp = aliyunStoreUserAppService.fetchInstalledAppContent();
                    sendSuccessMessage(mqClient, eventDto.getEvent(), installedApp);
                    break;
                }
                case MqEventType.QUERY_ALL_APP: {
                    String allApp = aliyunStoreUserAppService.fetchAllAppContent();
                    sendSuccessMessage(mqClient, eventDto.getEvent(), allApp);
                    break;
                }
                ...
            }
        } catch (Exception e) {
            log.error("dispatchEvent {} failed", eventDto.getEvent());
            sendErrorMessage(mqClient, eventDto.getEvent());
        } finally {
            mqClient.destroy();
        }
    }

4. 算盘前期准备

4.1 新建算盘服务

登陆算盘主页,在左侧菜单中选择 应用部署,右键 我的项目 中的目录。 在弹出的对话框中选择 新建服务


输入服务名,点击确认。

4.2 新建服务组件

点击全部组件上的 加号 按钮,选择服务组件。

接下来的步骤和配置服务组件相关,对于前端和后端组件会分别介绍。

4.2.1 前端组件

  • 代码类型: 选择 DashboardPage
  • 自定义Docker镜像: 填入自己镜像的地址
  • 自定义入口命令: node /home/app/server.js
  • 第1操作:标签填写为“打开页面”,端口选择 7000 。

4.2.2 后端组件

这里以 Java 后端为例。

  • 代码类型: 选择 Runtime
  • 自定义Docker镜像: 填入自己镜像的地址
  • 自定义入口命令: java -jar /home/app/app.jar

其中 app.jar 为 Spring-boot 框架打包的产物,在构建 Docker 镜像的时候被放置在了 /home/app 目录下。

可以参考 spos-backend 项目中的 Dockerfile,也可以跟据自己项目的构建配置进行修改。

4.2.3 配置数据

对于 1-1 关系的前端/后端组件,请依据以下截图进行设置。

4.3 连接组件

经过 0.2.3 的配置数据,组件已经可以相互连接。

请依据以下截图,将前端/后端组件的 输入1输出1 连接起来

如果一个后端节点需要连接多个前端节点,除了要配置输入/输出数据,还需修改后端节点的接收方式

点击部署按钮,启动服务。

4.4 启动服务

服务启动好后,组件的图标中会出现绿色的勾。

在页面的右侧菜单中,可以参看到组件启动日志。此外,对于前端应用,可以点击 打开界面 按钮,访问部署后的页面。

⚠️ **GitHub.com Fallback** ⚠️