gpt4 book ai didi

java - Jetty 新手 - 等待响应数据并继续,ASYNCSTARTED 异常

转载 作者:行者123 更新时间:2023-12-01 05:26:27 25 4
gpt4 key购买 nike

我正在开发一个小型代理服务器,它管理一堆在选择器循环中运行的 tcp-ip 连接。外部服务通过代理服务器中嵌入的 http 服务器与代理服务器进行通信,这些请求会一直到达套接字,然后在原始 http 请求的响应中从该套接字返回响应。

我有并发请求(具有唯一的请求ID)传入http服务器,这些请求中的实际消息被困在队列中并传递到一堆套接字连接(某个套接字将对应于一条消息) ,然后响应被转储到哈希中。 http 请求定期检查哈希值,直到看到具有正确请求 ID 的响应,或者超时。如果这没有意义的话,这是一个很棒的系统图。

Awesome system diagram

我对使用 Java 进行 http 处理完全陌生,所以我想我应该使用 Jetty 并按照 Hello World 示例设置一个简单的请求处理程序。使用 thread.sleep 可以防止并发请求,并且据我所知,连续请求需要触发事件。我希望请求偶尔检查一次哈希值,而不是每次套接字在哈希值中放入响应时都触发连接事件,除非事件将通过请求 id 或其他内容触发。如果流量很大,这似乎不太实用。

悬崖:

  • 如何让处理程序(或 servlet,如果我需要走那么远)等待暂时或定期,当数据变得可用时,无需阻止其他一切?
  • 有没有更好的方法来使http请求知道它应该作为响应返回的数据吗?
  • 这个设计不好吗?如果不好,有什么替代方案吗?

编辑:

这是我对这个问题的第一次尝试。当 HTTP 请求指向与已连接的 tcp 客户端相对应的 id 时,它可以正常工作。如果 id 与连接的客户端不对应,jetty 就会发疯并进入循环并一遍又一遍地抛出以下异常。我期望发生的情况是请求超时,因为它在收集器中找不到任何消息。

Mar 8, 2012 2:39:08 PM APIRequestHandler doPost
INFO: json: {"state": "255", "m": "set", "id": "00:00:00:00:00:06", "rid": "84955228696f11e1aa04c42c033c8bd7", "sid": "XXXXX"}
2012-03-08 14:39:08.526:WARN:oejs.ServletHandler:/
java.lang.IllegalStateException: ASYNCSTARTED,initial
at org.eclipse.jetty.server.AsyncContinuation.suspend(AsyncContinuation.java:365)
at org.eclipse.jetty.server.AsyncContinuation.suspend(AsyncContinuation.java:959)
at APIRequestHandler.doPost(APIRequestHandler.java:72)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:755)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:848)
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:594)
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:485)
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:231)
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1065)
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:412)
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:192)
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:999)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:117)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:111)
at org.eclipse.jetty.server.Server.handle(Server.java:351)
at org.eclipse.jetty.server.AbstractHttpConnection.handleRequest(AbstractHttpConnection.java:454)
at org.eclipse.jetty.server.AbstractHttpConnection.content(AbstractHttpConnection.java:900)
at org.eclipse.jetty.server.AbstractHttpConnection$RequestHandler.content(AbstractHttpConnection.java:954)
at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:857)
at org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:235)
at org.eclipse.jetty.server.AsyncHttpConnection.handle(AsyncHttpConnection.java:76)
at org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:609)
at org.eclipse.jetty.io.nio.SelectChannelEndPoint$1.run(SelectChannelEndPoint.java:45)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:599)
at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:534)
at java.lang.Thread.run(Thread.java:680)

Servlet:

public void doPost(HttpServletRequest req, HttpServletResponse res)
throws java.io.IOException
{
String rid = req.getParameter("rid");
String msg = req.getParameter("json");
String id = req.getParameter("id");

// Send to tcp-ip channel
APIMessage m = new APIMessage();
m.rid = rid;
m.id = id;
m.json = msg + "\r\n";
queue.add(m);
this.selector.wakeup();

Continuation cc = ContinuationSupport.getContinuation(req);

res.setContentType("text/plain");
res.getWriter().println("Request: "+rid+"\tstart:\t"+new Date());
res.getWriter().flush();
int elapsed = 0;
String responseStr = "";
boolean timeoutHappened = true;
while(elapsed<this.timeout) // say 50 millis
{
if(collector.containsKey(rid)){
responseStr = collector.get(rid);
collector.remove(rid);
timeoutHappened = false;
break;
}
cc.setTimeout(10); // sleep 10 millis
cc.suspend();
}

if(!timeoutHappened)
{
logger.info("--->API http request found response in collector!");
logger.info("Respose: "+responseStr);
}
else // timed out
{
logger.info("--->API http request timed out!");
}

res.getWriter().println("Request: "+rid+"\tend:\t"+new Date());
if(cc.isInitial()!=true) {cc.complete();}
}

最佳答案

我首先会看看我们在 jetty 中已有的代理功能。

http://git.eclipse.org/c/jetty/org.eclipse.jetty.project.git/tree/jetty-servlets/src/main/java/org/eclipse/jetty/servlets/ProxyServlet.java

如果这不能解决您想要做的事情,它至少可以帮助您开始。

您可以在该包的测试中使用类轻松运行嵌入的 servlet:

http://git.eclipse.org/c/jetty/org.eclipse.jetty.project.git/tree/jetty-servlets/src/test/java/org/eclipse/jetty/servlets/AsyncProxyServer.java

祝你好运

关于java - Jetty 新手 - 等待响应数据并继续,ASYNCSTARTED 异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9613212/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com