Using Spring RSocket in a traditional Servlet-based Spring application

193 views Asked by At

Is it somehow possible to use Spring's RSocket integration in a "traditional" servlet-based Spring application without having to sacrifice functionality that Spring offers according to the documentation if you do not mix the two variants?

If so, how? Are there any pitfalls to be aware of?

The objective would be to allow an existing Servlet-based Spring application to talk to various clients over RSocket. A fully reactive experience with backpressure is neither expected nor necessary on the server side. Having to start a separate Netty-based server that runs alongside the servlet container is okay and expected.

To address questions raised in the comments, there is some functionality I am especially concerned about:

  • Does declarative transaction support work for requests that come in via RSocket without having to use R2DBC? According to Reactive Transactions with Spring imperative and reactive transaction management differ significantly.
  • Does Spring Security "just" work? Or is special configuration necessary, for example, to use @PreAuthorize on methods that are invoked by the servlet-based parts and the RSocket-based parts of the application?
1

There are 1 answers

4
Franck Besson On

Yes, it is possible to use Spring's RSocket integration in a traditional Servlet-based Spring application without sacrificing declarative transaction support or Spring Security integration. Spring provides flexibility and modularity, allowing you to mix different technologies and features based on your requirements. You can run a separate Netty-based RSocket server alongside your existing servlet-based Spring application. Here's how you can achieve this:

Create an RSocket Server Configuration:

Start by creating an RSocket server configuration class. This class will define your RSocket server and how it handles incoming requests.

@Configuration
public class RSocketServerConfig {

    @Bean
    public RSocketServer rSocketServer() {
        return RSocketServer.create();
    }

    @Bean
    public RSocketMessageHandler messageHandler() {
        RSocketMessageHandler handler = new RSocketMessageHandler();
        handler.setRSocketStrategies(rSocketStrategies());
        return handler;
    }

    @Bean
    public RSocketStrategies rSocketStrategies() {
        return RSocketStrategies.builder().build();
    }
}

Define Your RSocket Controllers:

Create RSocket controllers similar to how you create Spring MVC controllers. These controllers will handle incoming RSocket requests. For example:

@Controller
public class RSocketController {

    @MessageMapping("your.rsocket.route")
    public Mono<String> handleRSocketRequest(String request) {
        // Handle the request here
        return Mono.just("Response");
    }
}

Enable RSocket in Your Application:

You need to enable RSocket in your Spring application. To do this, add the @EnableRSocket annotation to one of your configuration classes:

@SpringBootApplication
@EnableRSocket
public class YourServletBasedApplication {

    public static void main(String[] args) {
        SpringApplication.run(YourServletBasedApplication.class, args);
    }
}

Configure Spring Security:

If you have Spring Security configured in your application, ensure that you also secure your RSocket endpoints appropriately. You can use Spring Security's features to secure your RSocket controllers.

Transaction Management:

Spring's transaction management should work as expected in your servlet-based Spring application. Ensure that your RSocket controllers are within the transaction boundaries when necessary, and configure your transaction manager accordingly.

Pitfalls to Be Aware Of:

Concurrency: Be mindful of the concurrency model of your servlet-based Spring application and ensure that RSocket interactions don't cause contention or concurrency issues.

Resource Management: Managing resources (e.g., database connections, thread pools) between the servlet-based application and the RSocket server should be done carefully to avoid resource exhaustion or contention.

Cross-Origin Resource Sharing (CORS): If your RSocket clients are web-based, you may need to handle CORS settings appropriately to allow RSocket connections from different origins.

Error Handling: Implement robust error handling for your RSocket controllers to handle failures gracefully.

Remember that while you're integrating RSocket into your servlet-based Spring application, the level of reactivity and backpressure handling is up to you. You can keep your servlet-based code as is and provide a more traditional request-response experience over RSocket if that fits your requirements.