Tomcat 6 CometProcessor 中的写入是非阻塞的
我有一个 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
请参阅页面底部的表格。
I have a CometProcessor implementation that is effectively doing a Multicast to a potentially large number of clients. When an event occurs that needs propagated to to all the clients, the CometProcessor will need to loop through the list of clients writing out the response. If writing responses block then there is the possibility that potentially slow clients could have an adverse effect on the distribution of the event. Example:
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;
// ...
}
}
}
Update: Answering my own question. Writes from a CometProcessor are blocking:
http://tomcat.apache.org/tomcat-6.0-doc/config/http.html
See the table at the bottom of the page.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
Tomcat6对HttpServlerResponse的实现是Response类。 在内部,它使用包裹在 OutputBuffer 周围的 CoyoteOutputStream。 顾名思义,这个类是一个缓冲区,默认大小8k。 所以我想说,至少如果你写的代码少于 8k 那么你就不会阻塞。 您可能需要刷新才能让您的客户看到数据,这意味着最终取决于您使用的连接器变体。 在连接器配置中,如果您想要非阻塞写入,请指定
protocol=org.apache.coyote.http11.Http11NioProtocol
此连接器/协议是可大规模配置的:
http://tomcat.apache.org/tomcat-6.0-doc/config/http.html
Tomcat6's implementation of HttpServlerResponse is the Response class. Internally it uses a CoyoteOutputStream wrapped around an OutputBuffer. As the name suggests, this class is a buffer, default size 8k. So I would say at the very least if you are writing less than 8k then you arent going to block. You may need to flush though for your clients to see the data which means that ultimately it depends on which connector variant you are using. In your Connector config if you want non-blocking writes then specify
protocol=org.apache.coyote.http11.Http11NioProtocol
This Connector/Protocol is massively configurable:
http://tomcat.apache.org/tomcat-6.0-doc/config/http.html