Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/325.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Netty-阻塞操作在完成之前不接受客户端请求_Java_Server_Netty_Nio_Blocking - Fatal编程技术网

Java Netty-阻塞操作在完成之前不接受客户端请求

Java Netty-阻塞操作在完成之前不接受客户端请求,java,server,netty,nio,blocking,Java,Server,Netty,Nio,Blocking,[问题]:我有一个Netty服务器,它将通过TCP侦听客户端,处理请求并发送回响应。问题是处理部分需要时间,因为它需要应用程序用户的验证。客户端一个接一个地发送多个请求,服务器似乎在前一个请求完成之前不接受客户端的请求 我已经复制了这样一个场景:客户机将一个接一个地发送两个请求,服务器将接收请求并花一些时间进行处理。通过将阻塞操作传递给另一个线程并完成剩余的操作,我可以很好地处理单个请求阻塞请求。但它仍然不接受来自客户端的第二个请求。它仍将等待阻塞操作完成,然后再接受来自客户端的另一个请求 客户

[问题]:我有一个Netty服务器,它将通过TCP侦听客户端,处理请求并发送回响应。问题是处理部分需要时间,因为它需要应用程序用户的验证。客户端一个接一个地发送多个请求,服务器似乎在前一个请求完成之前不接受客户端的请求

我已经复制了这样一个场景:客户机将一个接一个地发送两个请求,服务器将接收请求并花一些时间进行处理。通过将阻塞操作传递给另一个线程并完成剩余的操作,我可以很好地处理单个请求阻塞请求。但它仍然不接受来自客户端的第二个请求。它仍将等待阻塞操作完成,然后再接受来自客户端的另一个请求

客户端代码

int count=0;
长currentTime=System.currentTimeMillis();
长触发器=电流时间+5000;
长停止循环=当前时间+130000;
while(counttrigger){
触发器+=5000;
计数++;
循环=假;
}
}
System.out.println(“发送计数器-”+计数);
内容=未冷却的复制缓冲区(b);
System.out.println(“称为“+ctx”的通道激活方法);
写(内容);
ctx.flush();
}
服务器代码:

public void channelRead(ChannelHandlerContext ctx,Object msg){
final ExecutorService blockingThreadPool=Executors.newFixedThreadPool(10);
试一试{
System.out.println(“服务器接收命令:“+body+”计数器为:“+++counter”);
executor().execute(新的Runnable()){
公开募捐{
试一试{
新的MyBusinessLogicHandler(blockingThreadPool).channelRead(ctx,b_buf);
}
捕获(例外e){
logger.error(例如getMessage());
}
}
}
//ByteBuf resp=unoled.copiedBuffer(当前时间,CharsetUtil.UTF_8);
//ByteBuf resp=unmooled.wrappedBuffer(response.getBytes());
//ctx.writeAndFlush(分别);
//ctx.写入(resp);
//ctx.flush();
}
我的商业逻辑

@覆盖
公共无效channelRead(ChannelHandlerContext ctx,对象arg1)
抛出异常{
System.out.println(“内部业务处理程序-OBJ”);
系统输出打印项次(arg1);
字符串x=ctx.channel().attr(DiscardServerHandler.CHECKSUMKEY.get();
System.out.println(“X-”+X);
ChannelHandlerContext温度=ctx;
resp=unmooled.wrappedBuffer(x.getBytes());
ctx.写入(resp);
ctx.flush();
ByteBuf buf=(ByteBuf)arg1;
字节[]请求=新字节[buf.readableBytes()];
buf.读取字节(req);
字符串体=新字符串(req,CharsetUtil.UTF_8);
System.out.println(新日期());
System.out.println(“业务逻辑接收订单:+body”);
System.out.println(“服务器侦听器读取”);
布尔循环=真;
长currentTime=System.currentTimeMillis();
长触发器=电流时间+3000;
长停止循环=当前时间+20000;
整数计数=0;
System.out.println(“服务器读取”);
//String response=“服务器完成响应”;
while(循环){
long now=System.currentTimeMillis();
如果(现在触发){
计数++;
System.out.println(“现在触发@”+count+”--“+(count*5)+”秒通过”);
触发器+=5000;
}
}
else if(现在>停止循环){
循环=假;
System.out.println(“循环完成”);
}
}
String re=“业务逻辑响应”;
resp=unmooled.wrappedBuffer(re.getBytes());
临时写入(resp);
温度冲洗();
}

我只想接受所有的客户端请求,不管之前的请求是否已完成或未完成。

这是一种经典模式,您需要从同步服务切换到异步(“异步”)服务。异步服务的思想是,您接收来自客户端的请求,然后验证它,并将其存储在“待办事项”列表中服务器上的某个存储(通常是队列)中。然后返回响应(在本例中称为确认(“ack”))。在您的响应中,您将向客户端返回其请求的id和返回答案的介质(通常为队列)。这样客户端将知道在何处侦听结果。同时,您现在可以在服务器上处理收到的请求,而无需阻塞客户端。您还可以有多个“工作者”实例从存储中获取传入请求并对其进行处理。处理完请求后,工作进程将以您在“ack”中返回给客户端的相同id将其发布到您在“ack”中返回给客户端的介质(队列)中。有关更多信息,请查看此处:

这是一种经典模式,您需要从同步服务切换到异步(“异步”)服务。异步服务的概念是您接收来自客户端的请求,然后验证它并将其存储在“待办事项”中服务器上的某个存储(通常是队列)中然后返回响应(在本例中称为确认(“ack”)。在您的响应中,您将向客户端返回其请求的id和返回答案的介质。(通常是队列)。这样,客户端将知道在何处侦听结果。同时,您现在可以在服务器上处理收到的请求,而无需中断客户端。您还可以拥有多个“工作进程”实例,这些“工作进程”从您的存储中接收传入的请求并对其进行处理。处理完请求后,您的工作进程将以不受限制的方式发布该请求