是从Tomcat 6 CometProcessor内部进行的写操作是非阻塞的
时间:2020-03-06 14:29:34 来源:igfitidea点击:
我有一个CometProcessor实现,可以有效地对潜在的大量客户端进行多播。当需要传播到所有客户端的事件发生时,CometProcessor将需要遍历客户端列表以写出响应。如果阻止写响应,则可能是潜在的慢客户端可能对事件的分发产生不利影响。例子:
public class MyCometProcessor implements CometProcessor { private List<Event> connections = new ArrayList<Event>(); public void onEvent(byte[] someInfo) { synchronized (connections) { for (Event e : connections) { HttpServletResponse r = e.getHttpResponse(); // -- Does this line block while waiting for I/O -- r.getOutputStream().write(someInfo); } } } public void event(CometEvent event) { switch (event.getEventType()) { case READ: synchronzied (connections) { connections.add(event); } break; // ... } } }
更新:回答我自己的问题。来自CometProcessor的写入被阻止:
http://tomcat.apache.org/tomcat-6.0-doc/config/http.html
请参阅页面底部的表格。
解决方案
Tomcat6的HttpServlerResponse实现是Response类。在内部,它使用包装在OutputBuffer周围的CoyoteOutputStream。顾名思义,此类是一个缓冲区,默认大小为8k。因此,我至少要说的是,如果我们写的字数少于8k,那么我们将无法进行阻塞。但是,我们可能需要刷新才能让客户端看到数据,这意味着最终它取决于我们使用的连接器型号。在连接器配置中,如果要进行非阻塞写入,请指定
protocol = org.apache.coyote.http11.Http11NioProtocol
该连接器/协议是可大规模配置的:
http://tomcat.apache.org/tomcat-6.0-doc/config/http.html