如何为spring-cloud-stream-app-starters项目创建自定义源应用程序

时间:2017-11-08 08:44:07

标签: spring-boot websocket spring-integration spring-websocket spring-cloud-stream

我想创建一个Web套接字源(适用于 spring-cloud-stream-app-starters ),目前git hub上没有这个源代码。

我经历了一些可用的来源,但有一些混淆,可能是因为我不熟悉这个框架。

我是否可以使用Source binding创建一个spring boot应用程序,并以@InboundChannelAdapter(value = Source.OUTPUT)带注释的方法从Web套接字客户端返回收到的数据包。 ? 另外,我如何使用 WebSocketInboundChannelAdapter 启动websocket服务器并将数据包推送到底层代理。?

2 个答案:

答案 0 :(得分:2)

@Krishas我肯定会看看可用的来源,找到一个与你想要完成的东西非常相似的东西,并在它之后为你的新资源建模。 一般来说,你的建议是正确的。 。 。它应该是使用@Source注释的Spring启动应用程序。但当然魔鬼在细节中。所以我建议创建一个PR,这样我们就可以对它进行审核并帮助你将它带到我们可以将它包含在可用的初学者池中的状态。

答案 1 :(得分:2)

您可以在Reference Manual中找到一些想法。

WebSocketInboundChannelAdapter是一个事件驱动的通道适配器,它不是可轮询的源。所以,你需要的只是这个@Bean以及对Source.OUTPUT的适当引用。

WebSocketInboundChannelAdapter无法启动服务器。这是:

的责任
/**
 * The {@link IntegrationWebSocketContainer} implementation for the {@code server}
 * {@link org.springframework.web.socket.WebSocketHandler} registration.
 * <p>
 * Registers an internal {@code IntegrationWebSocketContainer.IntegrationWebSocketHandler}
 * for provided {@link #paths} with the {@link WebSocketHandlerRegistry}.
 * <p>
 * The real registration is based on Spring Web-Socket infrastructure via {@link WebSocketConfigurer}
 * implementation of this class.
 *
 * @author Artem Bilan
 * @author Gary Russell
 * @since 4.1
 */
public class ServerWebSocketContainer extends IntegrationWebSocketContainer
        implements WebSocketConfigurer, SmartLifecycle {

我们也有documentation的问题。

还有一个stomp-chat示例来演示服务器行为。

我认为您在这种source应用程序中不需要“底层代理”:您只需通过Web套接字接收消息并将其发布到Source.OUTPUT。你为什么在这里需要STOMP经纪人?

<强>更新

刚刚对Rabbit Binder测试了这段代码:

@SpringBootApplication
@EnableBinding(Source.class)
public class CloudStreamWebSocketSourceApplication {

    @Bean
    public WebSocketInboundChannelAdapter webSocketInboundChannelAdapter() {
        WebSocketInboundChannelAdapter webSocketInboundChannelAdapter =
                new WebSocketInboundChannelAdapter(serverWebSocketContainer());
        webSocketInboundChannelAdapter.setOutputChannelName(Source.OUTPUT);
        return webSocketInboundChannelAdapter;
    }

    @Bean
    public IntegrationWebSocketContainer serverWebSocketContainer() {
        return new ServerWebSocketContainer("/test")
                .withSockJs()
                .setAllowedOrigins("*");
    }

    public static void main(String[] args) throws IOException {
        SpringApplication.run(CloudStreamWebSocketSourceApplication.class, args);
        System.out.println("Done");
    }

}

我的测试用例如下:

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class CloudStreamWebSocketSourceApplicationTests {

    @LocalServerPort
    private String port;

    @Test
    public void testWebSocketStreamSource() throws IOException, InterruptedException {
        StandardWebSocketClient webSocketClient = new StandardWebSocketClient();

        ClientWebSocketContainer clientWebSocketContainer =
                new ClientWebSocketContainer(webSocketClient, "ws://localhost:" + this.port + "/test/websocket");
        clientWebSocketContainer.start();

        WebSocketSession session = clientWebSocketContainer.getSession(null);

        session.sendMessage(new TextMessage("foo"));

        Thread.sleep(10000);
    }

}

这是我的依赖项:

<dependencies>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-stream-rabbit</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-integration</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-websocket</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.integration</groupId>
        <artifactId>spring-integration-websocket</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>