Spring Webflux Async PostgreSQL Publisher在第一个结果后停止

时间:2018-03-21 15:42:31

标签: spring postgresql websocket rx-java spring-webflux

我正在尝试用反应异步postgres-async-driver替换PostgreSQL数据库轮询器,并将新插入的行流式传输到Spring {5个Webflux Reactive websocket客户端,例如Josh Long真棒示例演示{{ 3}}并基于here Sébastien Deleuze's

我的Publisher获得第一个row,但之后不返回后续行。 我的Observable,我的Publisher或我使用postgres-async-driver Db的方式有问题吗?

public Observable<WebSocketMessage> getObservableWSM(WebSocketSession session){
    return
        // com.github.pgasync.Db
        db.queryRows(sql)
        // ~RowMapper method
        .map(row -> mapRowToDto(row))
        // serialize dto to String for websocket
        .map(dto -> { return objectMapper.writeValueAsString(dto); })
        // finally, write to websocket session 
        .map(str -> { return session.textMessage((String) str);
        });
}

然后,我使用Observable转换器将WebSocketHandler连接到我的RxReactiveStream.toPublisher

@Bean
WebSocketHandler dbWebSocketHandler() {
    return session -> {
        Observable<WebSocketMessage> o = getObservableWSM(session);
        return session.send(Flux.from(RxReactiveStreams.toPublisher(o)));
    };
}

这将从我的row语句中获取第一个sql,但没有其他行。如何继续传输其他行?

理想情况下,我认为我希望PostgreSQL等同于MongoDB spring-reactive-playground

1 个答案:

答案 0 :(得分:2)

我创建了一个Postgres Trigger,基于INSERT在我的桌面上触发 this example

CREATE OR REPLACE FUNCTION table_update_notify() RETURNS trigger AS $$
DECLARE
  id bigint;
BEGIN
  IF TG_OP = 'INSERT' THEN
    id = NEW.id;
  ELSE
    id = OLD.id;
  END IF;
  PERFORM pg_notify('my_trigger_name', json_build_object('table', TG_TABLE_NAME, 'id', id, 'type', TG_OP)::text);
  RETURN NEW;
END;
$$ LANGUAGE plpgsql;

然后我使用reactive-pg-client订阅了Postgres触发器。 以下是其Pub / Sub示例中的代码:

@Bean
PgPool subscribedNotificationHandler() {
    PgPool client = pgPool();
    client.getConnection(asyncResult -> {
        if (asyncResult.succeeded()) {
            PgConnection connection = asyncResult.result();
            connection.notificationHandler(notification -> {
                notification.getPayload();
                // do things with payload
            });
            connection.query("LISTEN my_trigger_name", ar -> {
                log.info("Subscribed to channel");
            });
        }
    });
    return client;
}