由weblogic.servlet.FutureResponseServlet引发的思考
|
apolloty
2007-11-08
FutureResponseServlet 和 FutureServletResponse 的特性令人咂舌.
Look!
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;
import java.util.Stack;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import weblogic.servlet.FutureResponseServlet;
import weblogic.servlet.FutureServletResponse;
// An AsynchronousServlet that handles HTTP requests from a "separate" thread and
// not the execute thread used to invoke this servlet.
public class AsynchronousServerResponseServlet extends FutureResponseServlet {
private final Notifier notifier;
private static Stack clients = new Stack();
public AsynchronousServerResponseServlet () {
this.notifier = new Notifier();
this.notifier.start();
}
public void service(HttpServletRequest request, FutureServletResponse response)
throws IOException, ServletException {
// push this client's request to a buffer and return immediately.
// asynchronous processing occurs in the run method of the Notifier Thread
notifier.poll(request, response);
}
class Notifier extends Thread {
void poll (HttpServletRequest request, FutureServletResponse response) {
clients.push(new Client(request, response));
}
public void run() {
while (!clients.empty()) {
Client client = null;
try
{
client = (Client) clients.pop();
PrintWriter pw = client.response.getWriter();
for(int j = 0; j < 10; j++) {
pw.println("Time is:" + new Date() + "");
pw.flush();
}
pw.close();
} catch(Throwable t) {
t.printStackTrace();
} finally {
try {
client.response.send();
} catch(IOException ioe) {
ioe.printStackTrace();
}
}
}
}
}
// inner class that holds on to the clients http request and response
class Client {
private HttpServletRequest request;
private FutureServletResponse response;
private Client(HttpServletRequest request, FutureServletResponse response) {
this.request = request;
this.response = response;
}
}
}
此特性将一次请求丢进任意容器即完成操作,释放资源。而通过后台轮询处理后居然可以client.response.send();到客户端!不可思议。 此特性让我无限YY,我能想到好多应用, 比如: 页面渲染分成多次,而且不需要前台AJAX的请求,纯后台push。 页面及时信息提示,不需要AJAX轮询,或者后台多线程阻塞队列。 在线及时通讯,甚至传非文本数据等等。 对与把YY变成现实的追求,我开始了探索之路,首先再google,baidu狂搜FutureServletResponse无果,没人提供此类源码,另外weblogic的对此的实现我也没有找到,于是乎我自己来尝试实现这种特殊的response。 我从最干净的ServerSocket着手试图突破这些谜团
……
//localSocket为接受的浏览器socket
from = new BufferedReader( new InputStreamReader( localSocket.getInputStream() ) );
to = new PrintWriter( new OutputStreamWriter( localSocket.getOutputStream() ), true );
toBin = localSocket.getOutputStream();
do
{
httpText = from.readLine();
}
while ( httpText.length() != 0 );
sendHeader( toBin );//写正常状态的头,比如"HTTP/1.0 200 OK\n"
int i=0;
while(i<50)
{
try
{
Thread.sleep(500);
}
catch (InterruptedException e){}
to.write("this is Response"+i);
to.write("\n");
to.flush();
i++;
}
然后在页面上写个请求
Function doAjaxRequest()
{
Var xmlhttp;
if(window.ActiveXObject)
{
xmlhttp =new ActiveXObject("Microsoft.XMLHTTP");
}
else if(window.XMLHttpRequest)
{
xmlhttp =new XMLHttpRequest();
}
xmlhttp.onreadystatechange= t_callback;
xmlhttp.open("GET","http://127.0.0.1/",true);
xmlhttp.send(null);
}
function t_callback()
{
//展现
var ret=this.xmlhttp.responseText;
document.write(ret);
}
执行,在一次通信间能够由后台像前台刷50次屏幕,但是到这里问题就出现了,浏览器上点击X后,断掉了socket,后台理所当然的无法push信息到页面,而且FutureServletServerlet主要是单线程就能处理多条response,很不理解FutureServletResponse的实现。 所以写到这里:我向看到此贴的朋友提问: 1. 莫非一个socket未必要绑定一个线程? 2. 莫非FutureServletResponse的实现就是将所有socket都缓存起来? 3. 莫非FutureServletResponse提交已经无视请求,无视socket想提就提!@#$%^&*? 本人还停留在定势思维上,请大家发表自己的想法!急切寻求解答! |

