set InputBufferSize and Timeout of connection for Netty (Reactive Spring) and heartbeats in Reactive WebSocket? - spring-boot

Maybe somebody has experienced this and can help me out.
I have a Reactive WebSocket server (WebFlux Spring Boot).
I checked the connection to the server by Postman and all is good, the connection lasts a long time, but I don't know how long this connection will last with another clients, so I want to set a couple of parameters: InputBufferSize and Timeout, I found how can do it for some servers (Jetty, TomCat,..):
https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#websocket-server-runtime-configuration
But I cannot find how can do it for Netty (I use Reactive WebSocket, based on Netty).
How can set InputBufferSize and Timeout of connection for Netty (Reactive Spring)?
And another question is how to send ping-pong (heartbeats), I think I can do it in MyHandler (that implements org.springframework.web.reactive.socket.WebSocketHandler), in
#Override
public Mono handle(WebSocketSession session)
WebSocketMessage has field type (enum: TEXT, BINARY, PING, PONG) I can use it for ping-pong (heartbeats) between any client and my server part. But many forums write that the Netty has already implemented this process (ping-pong) and it will be superfluous - to add it manually in WebSocketHandler. I'm confused here, should I write additional processing (ping-pong in WebSocketHandler) or it will be an unnecessary layer on top of the already made part in Netty?

Related

Get the stomp client used internally by Spring Broker Relay

I'm trying to setup a broker relay in Spring with RabbitMQ being the broker. Things work as intended when all events originate from my browser, however, sometimes I have events generated on the server side dynamically. I want to send these too to RabbitMQ to take advantage of things like durable topics or TTL for messages. As far as my understanding goes, using SimpleMessagingTemplate.convertAndSend() and convertAndSendToUser both end up sending the event to the browser instead of broker.
As of now, I'm trying to create a new stomp client to rabbitmq and send events through that. But I can't help feel it to be a bit hacky. Is there a way to get a hold on the stomp client used by Spring and forward my messages easily? Or am I missing something here?
Any help is appreciated, thanks!
Took a while but turns out you don't need to get a hold of the internal stomp client (it's actually an internal TcpClient from Reactor Netty though) or anything like that. Following are the steps you need to do when you want a little bit of customization:
Spring uses #EnableWebSocketMessageBroker to configure the broker or you can extend DelegatingWebSocketMessageBrokerConfiguration. I ended up extending it, it makes little difference though.
In configureMessageBroker(MessageBrokerRegistry registry), use the registry and enable stomp relay and the important part: for the registry in the same method, add ChannelInterceptors. You can get the stomp command and process it as required. The idea is identical to Spring Intercetpors. Add the headers needed inside that.
final StompHeaderAccessor headerAccessor = StompHeaderAccessor.wrap(message);
StompCommand command = headerAccessor.getCommand();
Then finally, recreate the message for sending.
MessageBuilder.createMessage(new byte[0], accessor.getMessageHeaders());
Lastly, you can test if things are actually going to RabbitMQ management console to observe if messages are actually being sent.

How to make a socket server that listens for client connections and opens a socket once an Endpoint is called in Spring?

I have an application that opens a "HttpURLConnection" to a printer. The printer is listening for socket connection and makes a connection when a new TCP socket connection is opened on the Application side (In this case through a new "HttpURLConnection"). Now, I want to mock this printer.
In the Application an Http call is made to the printer server and a socket connection is established between the Application and the server. How do I mock this printer as a spring boot application.
Sounds like you need to take a look into Spring Test Framework and especially its part about a Web: https://docs.spring.io/spring/docs/5.2.0.RELEASE/spring-framework-reference/testing.html#spring-mvc-test-client
I would really investigate a possibility to interact via a RestTemplate instead of direct HttpURLConnection and then use that MockRestServiceServer for mocking requests and responses.
Another way is to use a #SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) and implement controller with appropriate mappings and possible return results. This way you would be able to use the mentioned HttpURLConnection to connect to randomly allocated port for HTTP server and perform requests as in production.

RestTemplate (or WebClient) per destination socket and connect timeouts

Is there a way with either client (RestTemplate or the newer WebClient) to set per destination socket or connect timeouts? For example in an API aggregation web service, where I talk to several different services/hosts, it's often desirable to have different socket timeouts based on if the services are internal or external/3rd party. The only solution I know of (with RestTemplate, I haven't used WebClient) is to instantiate a separate RestTemplate with a different socket timeout/connect timeout (and do this for each host that requires a different timeout).
This is fairly annoying because the amount of setup code required for a RestTemplate configured with HttpComponents is non-trivial, and having to add #Qualifier at every use of RestTemplate injection is also non-ideal. Further, the fact that HttpComponents allows for max total connections and max routes to host implies that one RestTemplate talking to all outbound traffic is the expected usage.

Detecting disconnects using Spring messaging (websockets / STOMP)

We're using spring-messaging websocket with STOMP. Now we've defined multiple #SubscribeMapping methods, but is there also some sort of callback that gets fired when a client application disconnects from the socket?
We got a list of connect clients and some additional properties, like status. Status field needs to be updated when the client application disconnects.
Any suggestions on how to achieve this in Spring? I've tried implementing ApplicationListener however, there's no usefull information in the OnSessionDisconnect object.

A webapp that uses Spring AMQP is that consired to be 1 client?

Hi there i am wondering if i create a webapp that uses Spring AMQP. Is that single webapp 1 AMQP client? Or is every request made by a user that results into an AMQP call a client, so potentially x numbers of clients?
I don't know AMQP much, but I suspect it has the same terminology as jms. In that sense your application is probably pooling connections to AMQP broker for better performance. Each connection in a pool is treated as a separate client (competing consumer).
Thus each request is not really creating a new connection (client), but your application isn't a single client as well. In fact, when your application tries to access AMQP broker, it picks any connection from the pool and puts it back once it's done. Another request can reuse the same connection (client) or use a different, idle one.

Resources