I'm writing an application that needs to be able to listen to UDP datagrams and also expose some HTTP endpoints.
I'm using a Spring Boot with Web Starter for HTTP part and Netty for UDP.
To set up UDP I'm using the following code:
@Configuration
class NettyConfig(
@Value("\${netty.port}")
val port: Int,
@Value("\${netty.epoll}")
val epoll: Boolean
) {
val log = LoggerFactory.getLogger(NettyConfig::class.java)!!
@Bean
fun executor() = Executors.newFixedThreadPool(threads)!!
@Bean
fun bootstrap(handlerService: HandlerService): Bootstrap {
val master: EventLoopGroup
val clazz: Class<out Channel>
log.info("Starting Netty Server. EPoll enable: $epoll")
if (epoll) {
master = EpollEventLoopGroup(1)
clazz = EpollDatagramChannel::class.java
} else {
master = NioEventLoopGroup(1)
clazz = NioDatagramChannel::class.java
}
val bootstrap = Bootstrap()
.group(master)
.channel(clazz)
.option(ChannelOption.SO_SNDBUF, 1048576)
.option(ChannelOption.SO_RCVBUF, 1048576)
.option(ChannelOption.RCVBUF_ALLOCATOR, AdaptiveRecvByteBufAllocator(2048, 2048, 64 * 2048))
.option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT)
.option(ChannelOption.SO_BROADCAST, true)
.handler(object: ChannelInitializer<DatagramChannel>() {
override fun initChannel(ch: DatagramChannel) {
ch.pipeline().addLast(
LineBasedFrameDecoder(1048576),
handler(handlerService))
}
})
val channel = bootstrap.bind(port).sync().channel()
log.info("Started Netty Server. Listening on {}", port)
channel.closeFuture().sync()
log.info("Stopped Netty Server.")
return bootstrap
}
...
And an HTTP part is managed by Spring Starter Web, which is implemented by Tomcat.
What I want to achieve:
Both parts are working, but not together. By trial and error I've got the following problem: If I comment out this line (ie do not start Netty):
val channel = bootstrap.bind(port).sync().channel()
HTTP part works (and UDP obv. do not). If I leave it in place - everything starts, but, any request to 8080 port gives a connection refused error.
From my understing there should be no problems, as both servers are listening on the different ports (5432 vs 8080) and that's what I'm getting in the log messages. So there is some non-trivial interaction between two servers, which I'm not aware of.
How can I solve it, so both servers will run together in the same JVM/Spring Boot App?
I suspect that your application isn't completing startup due to channel.closeFuture().sync()
in the bootstrap
@Bean
method. Due to startup not completing, Tomcat doesn't get a chance to start so it cannot accept any incoming connections.
Rather than blocking the bean's creation, you should use a destroy method to call channel.closeFuture().sync()
as part of application context close processing. To do this you could implement DisposibleBean
or annotated a method with @PreDestroy
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.