Filip Hanik - Dev Lists wrote:
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);
How can you not be able to write, since you didn't write anything at all
yet for this request.
}
//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
No. The situation where the end of the entity body is reached is
detected very easily, and handled using a sleep (the 6.0 code is very
close from that already).
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 (...) {
...
}
...
}
}
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 :)
Real world for the simple delayed response scenario means using a thread
to wait and generate an event. You then proceed to write the data. It's
a bit like your second example, but it should be doing far less.
1) begin event: add the connection to the background thread, and sleep
2) background thread: after a while, invokes callback on the connection
3) callback event: write the data, there are two options:
a) blocking style: write everything, without wondering if it blocks
b) non blocking style: write while using isWriteable, and finish
writing in write events if needed
Rémy
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]