Ok, one use case scenario would be AJAX requests with asynchronous
responses on the server, I can see this be extremely common,
I've tried to add in comments to make the example clear, and I don't see
this example as stupid, as there are a lot more AJAX client frameworks
than Comet client frameworks.
So there are two things we are show casing
1. The ability to write asynchronously
2. The ability to pipeline HTTP requests (assumption: only dealing with
GET requests, no HTTP request body)
3. Difference between Comet non blocking and Comet blocking read and
writes (note, not related to sockets, API only)
What I'd like to point out is that this example, becomes easier with
blocking read/writes, so I've added that at the bottom for comparison
Let me know if I've made any mistakes here, so that we can work with a
correct example.
Non blocking read and writes
public class ExampleDelayedAjaxResponse implements CometProcessor {
...
public class DelayedResponder extends Thread {
public void run() {
...
Client[] clients = getClients();
for (int i=0; i<clients.length; i++ ) {
CometEvent event = client.getEvent();
byte[] data = getDelayedResponse(event);
if (data!=null) {
if (event.isWriteable()) {
event.getHttpServletResponse().getOutputStream().write(data);
if (event.isWriteable()) { //did we write it all?
event.close(); //close the event, in anticipation of the next
request
event.register(OP_CALLBACK); //triggers an END event
} else { //we didn't write it all, trigger a WRITE event when we are done with the write
event.register(OP_WRITE);
}
} else {
//we are not able to write, let us know when we can
event.register(OP_WRITE);
}
//remove the client from the async thread
//since we have received the data for this client.
clients.remove(event);
}
}
...
}
}
...
public void event(CometEvent event) throws IOException, ServletException {
...
if ( event.getEventType() == CometEvent.EventType.BEGIN ) {
//configure non blocking
event.configureBlocking(false);
//deregister for READ since we want to enable pipe lining on the connection
//for the next HTTP request
event.unregister(OP_READ);
//add the client to the list
clients.add(event);
} if ( event.getEventType() == CometEvent.EventType.READ ) {
//read client Id and stock list from client
//and add the event to our list
assert("this should never happen");
} if ( event.getEventType() == CometEvent.EventType.WRITE ) {
//unregister from the write event
event.unregister(OP_WRITE);
//we can now write
byte[] data = getDelayedResponse(event);
if ( data != null ) {
event.getHttpServletResponse().getOutputStream().write(data);
}
if( data==null || event.isWriteable() ) {
event.close();
}
} if ( event.getEventType() == CometEvent.EventType.END ) {
clients.remove(event);
} else if (...) {
...
}
...
}
}
Blocking read and writes
public class ExampleDelayedAjaxResponse implements CometProcessor {
...
public class DelayedResponder extends Thread {
public void run() {
...
Client[] clients = getClients();
for (int i=0; i<clients.length; i++ ) {
CometEvent event = client.getEvent();
byte[] data = getDelayedResponse(event);
if (data!=null) {
//register for a write, better do that on a thread pool thread
//since write is blocking
event.register(OP_WRITE);
//remove the client from the async thread
clients.remove(event);
}
}
...
}
}
...
public void event(CometEvent event) throws IOException, ServletException {
...
if ( event.getEventType() == CometEvent.EventType.BEGIN ) {
//configure non blocking
event.configureBlocking(false);
//deregister for READ since we want to enable pipe lining on the connection
//for the next HTTP request
event.unregister(OP_READ);
//add the client to the list
clients.add(event);
} if ( event.getEventType() == CometEvent.EventType.READ ) {
//read client Id and stock list from client
//and add the event to our list
assert("this should never happen");
} if ( event.getEventType() == CometEvent.EventType.WRITE ) {
//unregister from the write event
event.unregister(OP_WRITE);
//we can now write
byte[] data = getDelayedResponse(event);
//note we don't have to check for null data here
event.getHttpServletResponse().getOutputStream().write(data);
event.close();
} if ( event.getEventType() == CometEvent.EventType.END ) {
clients.remove(event);
} else if (...) {
...
}
...
}
}
I think this makes a good use case of where blocking makes life easier, and less complex code. Big difference for both the async thread and the Comet processor.
And this is why I think we should support both, please note
event.configureBlocking has nothing to do with the underlying socket, just the
inputstream.read/write.
the underlying socket is an implementation detail.
Remy, would you mind showing this example with sandbox API, I think with a real
world example, I can understand your API better, and maybe you mine :)
Filip
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]