function ajax(data){
var xhr = new XMLHttpRequest();
xhr.open(‘get‘, ‘/cgi-bin/xxx‘, true);
xhr.onreadystatechange = function(){
if (xhr.readyState == 4) {
if (xhr.status == 200) {
......
}
}
}
xhr.send(data);
}
setTimeout(function(){ajax({"data":"hehe"});}, 2000);//每隔2秒请求一次function ajax(data){ var xhr = new XMLHttpRequest(); xhr.open(‘get‘, ‘/cgi-bin/xxx‘, true); xhr.onreadystatechange = function(){ if (xhr.readyState == 4) { if (xhr.status == 200) { } } } xhr.send(data);}setTimeout(function(){ajax({"data":"hehe"});}, 2000);//每隔2秒请求一次
Ajax轮询与基于Ajax的长轮询原理对比: 图4-2
function longPoll(data, cbk){
var xhr = new XMLHttpRequest();
var url = ‘/cgi-bin/xxx‘;
xhr.onreadystatechange = function(){
if (xhr.readyState == 4) {//XMLHttpRequest 的状态中4: 请求已完成,且响应已就绪
if (xhr.status == 200) { //请求完毕后重新发起新的一次连接
cbk(xhr.responseText);
xhr.open(‘get‘, url, true);
xhr.send(otherData);
}
}
}
xhr.open(‘get‘, url, true);
xhr.send(data);
}x
function longPoll(data, cbk){ var xhr = new XMLHttpRequest(); var url = ‘/cgi-bin/xxx‘; xhr.onreadystatechange = function(){ if (xhr.readyState == 4) {//XMLHttpRequest 的状态中4: 请求已完成,且响应已就绪 if (xhr.status == 200) { //请求完毕后重新发起新的一次连接 cbk(xhr.responseText); xhr.open(‘get‘, url, true); xhr.send(otherData); } } } xhr.open(‘get‘, url, true); xhr.send(data);}web.xml中application的配置的版本是3.0<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0"><web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0"><web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<filter>
<filter-name>Spring OpenEntityManagerInViewFilter</filter-name>
<filter-class>org.springframework.~.OpenEntityManagerInViewFilter</filter-class>
<async-supported>true</async-supported>
</filter>
<filter-mapping>
<filter-name>Spring OpenEntityManagerInViewFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>ASYNC</dispatcher>
</filter-mapping>
</web-app><web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0"> <filter> <filter-name>Spring OpenEntityManagerInViewFilter</filter-name> <filter-class>org.springframework.~.OpenEntityManagerInViewFilter</filter-class> <async-supported>true</async-supported> </filter> <filter-mapping> <filter-name>Spring OpenEntityManagerInViewFilter</filter-name> <url-pattern>/*</url-pattern> <dispatcher>REQUEST</dispatcher> <dispatcher>ASYNC</dispatcher> </filter-mapping></web-app>WebApplicationInitializer,你同样需要像在web.xml中一样,设置”asyncSupported”标签为ASYNC.为了简化这个配置,考虑继承AbstractDispatcherServletInitializer或者AbstractAnnotationConfigDispatcherServletInitializer。它们会自动设置这些选项,使它很容易注册过滤器实例。 asyncContext.addListener(new AsyncListener() { //这里为异步处理提供了一个监听器,使用AsyncListener接口表示。此接口负责管理异步事件
@Override
public void onComplete(AsyncEvent event) throws IOException {
}
//超时处理,注意asyncContext.complete();,表示请求处理完成
@Override
public void onTimeout(AsyncEvent event) throws IOException {
AsyncContext asyncContext = event.getAsyncContext();
asyncContext.complete();
}
@Override
public void onError(AsyncEvent event) throws IOException {
}
@Override
public void onStartAsync(AsyncEvent event) throws IOException {
}
}); asyncContext.addListener(new AsyncListener() { //这里为异步处理提供了一个监听器,使用AsyncListener接口表示。此接口负责管理异步事件 @Override public void onComplete(AsyncEvent event) throws IOException { } //超时处理,注意asyncContext.complete();,表示请求处理完成 @Override public void onTimeout(AsyncEvent event) throws IOException { AsyncContext asyncContext = event.getAsyncContext(); asyncContext.complete(); } @Override public void onError(AsyncEvent event) throws IOException { } @Override public void onStartAsync(AsyncEvent event) throws IOException { } });
DeferredResult的处理顺序与Callable十分相似,由应用程序多线程产生异步结果:
DeferredResult对象,并且把它保存在内在队列当中或者可以访问它的列表中。DispatcherServlet与所有的Filter的Servlet容器线程退出,但Response仍然开放。DeferredResult中sets值.并且Spring MVC分发request给Servlet容器.DispatcherServlet再次被调用并且继续异步的处理产生的结果.Spring MVC提供Java Config与MVC namespace作为选择用来配置处理异步request.WebMvcConfigurer可以通过configureAsyncSupport来进行配置,而xml可以通过子元素来进行配置.
如果你不想依赖Servlet容器(e.g. Tomcat是10)配置的值,允许你配置异步请求默认的timeout值。你可以配置AsyncTaskExecutor用来包含Callable实例作为controller方法的返回值.强烈建议配置这个属性,因为在默认情况下Spring MVC使用SimpleAsyncTaskExecutor。Spring MVC中Java配置与namespace允许你注册CallableProcessingInterceptor与DeferredResultProcessingInterceptor实例.
如果你想覆盖DeferredResult的默认过期时间,你可以选择使用合适的构造器.同样的,对于Callable,你可以通过WebAsyncTask来包装它并且使用相应的构造器来定制化过期时间.WebAsyncTask的构造器同样允许你提供一个AsyncTaskExecutor.
原文地址:spring-framework-reference-4.2.6.RELEASE
function foreverFrame(url,callback){
var iframe = body.appendChild(document.createElement("iframe"));
iframe.style.display="none";
iframe.src=url+"?callback=parent.foreverFrame.callback";
this.callback = callback;
} function foreverFrame(url,callback){ var iframe = body.appendChild(document.createElement("iframe")); iframe.style.display="none"; iframe.src=url+"?callback=parent.foreverFrame.callback"; this.callback = callback; }<script>
parent.foreverFrame.callback(‘hello world!‘);
</script>
<script>
parent.foreverFrame.callback(‘hello Mars!‘);
</script><script>parent.foreverFrame.callback(‘hello world!‘);</script><script>parent.foreverFrame.callback(‘hello Mars!‘);</script>function xhrStreaming(url, callback) {
var xhr = new XMLHttpRequest();
xhr.open(‘post‘, url, true);
//保存上次返回的文档位置
var lastSize;
xhr.onreadystatechange = function() {
var newResponseText = "";
if (xhr.readyState > 2) {
newResponseText = xhr.responseText.slice(lastSize);
lastSize = xhr.responseText.length;
callback(newResponseText);
}
if (xhr.readyState == 4) {
xhrStreaming(url, callback);
}
}
xhr.send(null);
}function xhrStreaming(url, callback) { var xhr = new XMLHttpRequest(); xhr.open(‘post‘, url, true); //保存上次返回的文档位置 var lastSize; xhr.onreadystatechange = function() { var newResponseText = ""; if (xhr.readyState > 2) { newResponseText = xhr.responseText.slice(lastSize); lastSize = xhr.responseText.length; callback(newResponseText); } if (xhr.readyState == 4) { xhrStreaming(url, callback); } } xhr.send(null);}protocol="org.apache.coyote.http11.Http11NioProtocol"protocol="org.apache.coyote.http11.Http11NioProtocol"
var supported = ("WebSocket" in window);
if (supported) alert("WebSockets are supported");var supported = ("WebSocket" in window);if (supported) alert("WebSockets are supported");var connection = new WebSocket(‘ws://localhost:8080‘);
// When the connection is open, send some data to the server connection.onopen = function () { connection.send(‘Ping‘); // Send the message ‘Ping‘ to the server }; // Log errors connection.onerror = function (error) { console.log(‘WebSocket Error ‘ + error); }; // Log messages from the server connection.onmessage = function (e) { console.log(‘Server: ‘ + e.data); };var connection = new WebSocket(‘ws://localhost:8080‘);// When the connection is open, send some data to the server connection.onopen = function () { connection.send(‘Ping‘); // Send the message ‘Ping‘ to the server }; // Log errors connection.onerror = function (error) { console.log(‘WebSocket Error ‘ + error); }; // Log messages from the server connection.onmessage = function (e) { console.log(‘Server: ‘ + e.data); };Connection:Upgrade Sec-WebSocket-Key:eDCPPyPQZq7PiwRcx8SPog== Sec-WebSocket-Version:13 Upgrade:websocketConnection:Upgrade Sec-WebSocket-Key:eDCPPyPQZq7PiwRcx8SPog== Sec-WebSocket-Version:13 Upgrade:websocketHTTP/1.1 101 Switching Protocols
Upgrade:websocket
Connection:upgrade
Sec-WebSocket-Accept:QJsTRym36zHnArQ7FCmSdPhuK78=
// Connection:upgrade 升级被服务器同意
// Upgrade:websocket 指示客户端升级到websocket
// Sec-WebSocket-Accept:参考上面请求的Sec-WebSocket-Key的注释HTTP/1.1 101 Switching ProtocolsUpgrade:websocketConnection:upgradeSec-WebSocket-Accept:QJsTRym36zHnArQ7FCmSdPhuK78=// Connection:upgrade 升级被服务器同意// Upgrade:websocket 指示客户端升级到websocket// Sec-WebSocket-Accept:参考上面请求的Sec-WebSocket-Key的注释TIP 代理、很多现有的HTTP中间设备可能不理解新的WebSocket协议,而这可能导致各种问题,使用时需要注意,可以使借助TLS,通过建立一条端到端的加密信道,可以让WebSocket通信绕过所有中间代理。原文:https://www.cnblogs.com/redcoatjk/p/10846100.html