当前位置: 首页 > 知识库问答 >
问题:

使用Spring+Netty的UDP服务器

吕奇
2023-03-14

我试图使用Netty来设置一个简单的UDP服务器,遵循这里的示例,但使用Spring来连接依赖项。

我的Spring配置类:

@Configuration
@ComponentScan("com.example.netty")
public class SpringConfig {

    @Value("${netty.nThreads}")
    private int nThreads;

    @Autowired
    private MyHandlerA myHandlerA;

    @Autowired
    private MyHandlerB myHandlerB;

    @Bean(name = "bootstrap")
    public Bootstrap bootstrap() {
        Bootstrap b = new Bootstrap();
        b.group(group())
                .channel(NioDatagramChannel.class)
                .handler(new ChannelInitializer<DatagramChannel>() {
                    @Override
                    protected void initChannel(DatagramChannel ch) throws Exception {
                        ch.pipeline().addLast(myHandlerA, myHandlerB);
                    }
                });
        return b;
    }

    @Bean(name = "group", destroyMethod = "shutdownGracefully")
    public NioEventLoopGroup group() {
        return new NioEventLoopGroup(nThreads);
    }

    @Bean
    public static PropertySourcesPlaceholderConfigurer propertyPlaceholderConfigurer() {
        return new PropertySourcesPlaceholderConfigurer();
    }

}
@Component
public class MyUDPServer {

    @Autowired
    private Bootstrap bootstrap;

    @Value("${host}")
    private String host;

    @Value("${port}")
    private int port;

    @PostConstruct
    public void start() throws Exception {
        bootstrap.bind(host, port).sync().channel().closeFuture().await();
        /* Never reached since the main thread blocks due to the call to await() */
    }
}

为了避免阻塞主线程(用于Spring配置),我创建了一个新线程,如下所示:

@Component
public class MyUDPServer extends Thread {

    @Autowired
    private Bootstrap bootstrap;

    @Value("${host}")
    private String host;

    @Value("${port}")
    private int port;

    public MyUDPServer() {
        setName("UDP Server");
    }

    @PostConstruct
    @Override
    public synchronized void start() {
        super.start();
    }

    @Override
    public void run() {
        try {
            bootstrap.bind(host, port).sync().channel().closeFuture().await();
        } catch (InterruptedException e) {

        } finally {
            bootstrap.group().shutdownGracefully();
        }
    }

    @PreDestroy
    @Override
    public void interrupt() {
        super.interrupt();
    }
}

我可以看到新线程被阻塞,等待通道关闭(如示例所示)。主线程可以继续Spring配置。然而,这仍然不起作用。

共有1个答案

郗浩言
2023-03-14

不需要在@postconstruct中等待通道的终止。尝试删除await()

 类似资料:
  • 我有一个基于UDP网络的服务器。它有一个流水线,我在其中重写方法。 我需要时不时地写些信息。我只能通过使用中的套接字信息和中的通道来实现。为了能够重用这些信息,我保留在一个静态映射中。 我做错什么了吗? 有没有比将通道和远程地址保留在某个成员中更好的回写方法?

  • 当涉及到TCP时,Netty确实有很好的文档记录,但我想尝试一个简单的UDP服务器-客户机示例,但没有找到任何好的代码。(主要是邮件列表和据称有错误代码的用户) 有人愿意提供一些简单的例子吗?谢谢!

  • netty文档讨论TCP客户端。 但对UDP来说,这句话似乎无关紧要?!我找到了仅使用引导程序的UDP服务器的示例,如:1,2,3 我对此感到很困惑,所以我的两个问题是: null

  • 然后是数据报通道、pipelineFactory和Bootstrap: 在pipelineFactory中,getPipeline()添加自定义处理程序。 就像中所说的:UDP消息的多线程处理 然后我根据这些条目修改了一些代码。现在创建线程池的条件是: 和ExecutionHandler的pipelineFactory: getPipeline()添加处理程序,如所描述的: 但它们不同时处理。me

  • 我正在使用编写负载均衡器。 负载平衡器侦听本地传输地址。就Netty而言,只创建了一个频道来监听该地址。然后,(单线程事件循环组的)单线程将传入的UDP数据包调度到工作线程池进行处理(这里,处理意味着执行负载平衡)。 在出站端,可以使用多个服务器。对于每个接收到的UDP数据包,关联的工作线程选择一个服务器,并将UDP数据包转发到此服务器。为了转发UDP数据包,需要一个通道。 我可以看到四种方法:

  • 程序代码 udp_server.php //创建Server对象,监听 127.0.0.1:9502端口,类型为SWOOLE_SOCK_UDP $serv = new Swoole\Server("127.0.0.1", 9502, SWOOLE_PROCESS, SWOOLE_SOCK_UDP); //监听数据接收事件 $serv->on('Packet', function ($serv,