【问题标题】:Long polling in JQuery + JAVA?JQuery + JAVA中的长轮询?
【发布时间】:2013-09-13 22:45:21
【问题描述】:

我需要在 服务器保留我的请求,直到新数据到来。我使用 Tomcat 6 作为我的网络服务器。这是我的 JQuery 代码,

function sendMessage() {

    var message = $("#message").val();
    $.ajax({
        type: "POST",
        cache: false,
        url: "sendMessage.html",
        data: "message=" + message,
        dataType: "html",

        success: function(response) {

        },
        error: function(e) {
            //alert('Error: ' + e);
        },
    });
}


function startLongPolling(){

    $.ajax({
        type: "POST",
        cache: false,
        url: "LongPoll.html",
        dataType: "html",
        success: function(response) {   
            if(response != null && response !="" && response !="null")
                $("#sucess").html(response);
        },
        error: function(e) {
            //alert('Error: ' + e);
        },

        complete: function(e) {
            startLongPolling();
        },
    });
}

我的 java 代码将是,

@RequestMapping(value = "LongPoll.html", method=RequestMethod.POST )
public @ResponseBody String longLongPolling(HttpSession session) {

    String sessionId = session.getId().toString();
    AgentState agentState = ApplicaionManager.agentDetail.get(sessionId);
    String message = null;

    if(ApplicaionManager.agentDetail.containsKey(sessionId)){

        while(true){

            if(agentState.isStateChange() == true){
                message = agentState.getMessage();
                if(message != null)
                    agentState.setStateChange(false);
                System.out.println("Break for session "+sessionId+" due to Agent State changed");
                break;
            }

            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    System.out.println("While exited for session"+sessionId);
    return message;
}

但每 11 秒 会有一个continous request sent to server。我不知道怎么可能。我已使用 chrome 开发者工具对此进行了检查。

希望我们的堆栈用户能帮助我。

【问题讨论】:

  • 它是否在控制台中打印“Break for session..”?
  • I 状态的任何变化意味着,它会打印“Break for session..”。
  • 请粘贴完整的jquery代码
  • @UVM 。我更新了我的代码。请检查一下。
  • 您的请求可能超时。 jQuery 没有设置默认超时值,但您的浏览器、操作系统或服务器可能有。

标签: java jquery spring google-chrome-devtools long-polling


【解决方案1】:

这是正常/预期的。根据您的浏览器和(尤其是)前端服务器(Apache/NGINX)和网络服务器(Tomcat?)配置,您将拥有:

  • 第一个响应的最长等待时间(连接超时,在您的情况下可能是 10 秒)
  • 完整响应的最长等待时间

这些设置基本上可以防止服务器收到垃圾邮件,这些请求永远不会完成并用完线程池中的线程。

您可以增加这些值,但在创建代码时应始终考虑超时。基本上你想在客户端做:

  • 开长拉
  • 等待回复
  • 如果收到,继续
  • 如果(超时)错误,请转到步骤 1

请注意,此解决方案不可扩展:通常(例如)您需要 200 个线程处理传入请求。这个想法是他们完成得很快。如果线程池耗尽,用户将不得不等待新的连接。但是使用 200 个线程,您可以为超过 2000 个用户提供服务。但如果线程因为长池而被阻塞,则不会。

如果可能,您应该真正研究一下WebSockets,它现在在新版本的 Java 中可用。

编辑 正如 Konrad 下面建议的那样,您可以使用 socket.io 之类的东西,它会自动回退到其他机制。有一个基于 Java 的服务器端可用调用 Atmosphere 的实现,但我还没有尝试过。

【讨论】:

  • 查看socket.io,它是一个很好的用于创建套接字连接的 JavaScript 库。它还为旧版浏览器提供向后兼容性。
  • socket.io 很不错,但服务器端仅限于 NodeJS(自然)。如果你想在基于 Java 的后端使用它,你需要兼容 JEE7 的应用服务器。快速谷歌搜索出现了这个:github.com/Atmosphere/atmosphere for Java-backends and socket.io on frontend。
猜你喜欢
  • 2013-02-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多