我的情况如下:单个“服务器”有一个队列,其上放置了来自其他地方的消息(建模为传输字符串)。此队列将由连接到服务器的所有客户端和任何客户端使用。每个客户端都可以看作是一种工作流/ 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。
答案 0 :(得分:0)
Netty : Blocking call to get a connected Server Channel?建议方法,同时提供使用Collections.rotate编写循环法的自定义ChannelGroup
implementatino。