Netty 4 - 单个服务器,具有中央队列处理的多个客户端

时间:2014-05-20 11:15:52

标签: netty

我的情况如下:单个“服务器”有一个队列,其上放置了来自其他地方的消息(建模为传输字符串)。此队列将由连接到服务器的所有客户端和任何客户端使用。每个客户端都可以看作是一种工作流/ BPM引擎,即接收到的String转换为POJO,然后进行评估,看它是否符合标准,如果是,则进一步处理。

我正在尝试使用服务器 - 客户端方法,即服务器(托管队列)由客户端连接(接收消费)。我为每个服务器和客户端设置了一个基本的管道工厂:

public class ServerPipelineFactory extends ChannelInitializer { @Override public void initChannel( SocketChannel ch ) throws Exception {
pipeline.addLast( "fieldLengthPrepender", new LengthFieldPrepender( 4 ) ); pipeline.addLast( "channelEventHandler", new ClientConnectHandler() ); pipeline.addLast( "gzipMessageDeflator", ZlibCodecFactory.newZlibEncoder( ZlibWrapper.GZIP ) ); } }
public class ClientConnectHandler extends SimpleChannelInboundHandler { public static final ChannelGroup allConnected = new DefaultChannelGroup( GlobalEventExecutor.INSTANCE ); .... @Override public void channelActive( ChannelHandlerContext ctx ) throws Exception { LOGGER.info( "Client Connected" ); allConnected.add( ctx.channel() ); super.channelActive( ctx ); } }

服务器的设置方式(片段)如下:

... EventLoopGroup bossGroup = new NioEventLoopGroup( 1 ); EventLoopGroup workerGroup = new NioEventLoopGroup( ); ScheduledExecutorService svc = Executors.newSingleThreadScheduledExecutor(); try { ServerBootstrap b = new ServerBootstrap(); b.group( bossGroup, workerGroup ).channel( NioServerSocketChannel.class ) .childHandler( new ServerPipelineFactory() ); Channel ch = b.bind( port ).sync().channel(); int count = 0; while ( ClientConnectHandler.allConnected.isEmpty() ) { .... do nothing, ie don't poll the queue }

客户 - 处理程序和工厂。

@Component @DependsOn( { "clientSpringConfig", "demoWorkflowProcessor" } ) public class ClientPipelineFactory extends ChannelInitializer { @Override public void initChannel( SocketChannel ch ) throws Exception { ChannelPipeline pipeline = ch.pipeline(); pipeline.addLast( createInboundHandlers() ); pipeline.addLast( createOutboundHandlers() ); pipeline.addLast( createLogicHandlers() ); } ... private ChannelHandler[] createLogicHandlers() { List handlers = new ArrayList<>( 1 ); ClientChannelHandler handler = ( ClientChannelHandler ) AppContext.getBean( AppContext.CLIENT_HANDLER ); handlers.add( handler ); return handlers.toArray( new ChannelHandler[ 1 ] ); } }

public class ClientChannelHandler extends SimpleChannelInboundHandler { @Override protected void channelRead0( ChannelHandlerContext ctx, String msg ) throws Exception { LOGGER.info( "ADDING QUEUE: " + msg ); rcvdQueue.put( msg ); }
}

客户端的队列由单独的ExecutorService实例读取和处理。

我的ServerSide @Component邮件发件人可以成功调用ClientConnectHandler.allConnected.writeAndFlush( buffer );,它会将检索到的元素从队列写入所有频道 - 而不是我想要的。有人可以帮忙吗?

我已经成功地让它在客户端工作 - &gt; (发送消息“给我输入”) - &gt;服务器 - &gt; (民意调查队列) - &gt; (发送回复) - &gt;客户 - &gt; (坚持客户端处理队列)并从服务器到客户端进行“广播”,但是我没想到的是没有客户端启动消息的循环。

提前致谢,

的Al。

1 个答案:

答案 0 :(得分:0)

Netty : Blocking call to get a connected Server Channel?建议方法,同时提供使用Collections.rotate编写循环法的自定义ChannelGroup implementatino。