我想换身衣服,给我些css...
给我些png图片 & font文件,我想多些点缀
来吧,JavaScript!快来检测的V8引擎的性能...
要更新点数据,我发了Ajax请求,快点回复...
面对这些请求,服务器都会很「土豪」的说:
只要我有,我都會滿足...
import flash.errors.*;
import flash.events.*;
import flash.net.Socket;
class CustomSocket extends Socket {
private var response:String;
public function CustomSocket(host:String = null, port:uint = 0) {
super();
configureListeners();
if (host && port) {
super.connect(host, port);
}
}
private function configureListeners():void {
addEventListener(Event.CLOSE, closeHandler);
addEventListener(Event.CONNECT, connectHandler);
addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
addEventListener(SecurityErrorEvent.SECURITY_ERROR,
securityErrorHandler);
addEventListener(ProgressEvent.SOCKET_DATA, socketDataHandler);
}
...
}
与脱离浏览器的客户端Socket编程完全相同
So,这些都不是最好的实现「服务器推送」方式
最简单的两种方式:
// 频繁向服务器发Ajax请求,查询是否有更新
setInterval(function(){
$.ajax({ url: '/ajax', success: function(data){
// Do stuff with message
} });
}, 100);
// 服务器接收请求后立马反馈结果
public function postAjax() {
if (isUpdate($JOSN_DATA)) {
echo $JOSN_DATA;
} else {
echo '{"msg": "no update..."}';
}
}
http://10.64.12.173:8099/(树莓派,每分钟查询一次)
// 向服务器端发送Ajax请求,得到服务器的反馈后立马重新请求
// 递归实现
function load(){
$.ajax({ url: '/ajax', success: function(){
// do something with the data
}, complete: load, timeout: 20000 });
}
// 服务器接收请求后不会立马反馈结果,满足要求后才反馈
public function postAjax() {
while(isUpdate($JOSN_DATA)) {
echo $JOSN_DATA;
} // 不满足`isUpdate($JOSN_DATA)`,死循环等待
}
这样,不必要的Ajax请求少了许多...
但服务器负担依旧很重...
Comet is a web application model in which a long-held HTTP request allows a web server to push data to a browser, without the browser explicitly requesting it.
来自wikipedia的解释:
两个特点:
实现思路
// 实现HTTP流的方式
public static function postHTTPStream() {
while(true) {
// 更新数据
$nowData = update();
// 打印数据
echo $nowData;
flush();
sleep(100);
}
}
采用流实现的服务器端的形式
function createStreamingClient(url, progress, finished) {
var xhr = new XMLHttpRequest(),
received = 0;
xhr.open("post", url, true);
xhr.onreadystatechange = function() {
var result;
console.log(xhr.readyState);
if (xhr.readyState == 3) {
result = xhr.responseText.substring(received);
received += result.length;
progress(result);
} else if (xhr.readyState == 4) {
finished(xhr.responseText);
}
};
xhr.send(null);
return xhr;
}
通过在 HTML 页面里嵌入一个隐蔵iframe,然后将这个隐蔵iframe的 SRC 属性设为对一个长连接的请求,服务器端就能源源不断地往客户端输入数据。
iframe 服务器端并不返回直接显示在页面的数据,而是返回对客户端 Javascript 函数的调用,如:
<script type="text/javascript">js_func(“data from server ”)</script>”
服务器端将返回的数据作为客户端 JavaScript 函数的参数传递;客户端浏览器的 Javascript 引擎在收到服务器返回的 JavaScript 调用时就会去执行代码。
使用iframe标签实现HTTP流:
来自Google的处理方式:
使用一个称为"htmlfile"的 ActiveX 解决了在 IE 中的加载显示问题。
相关链接:What else is burried down in the depth’s of Google’s amazing JavaScript?
中断判断:服务器怎么知道浏览器还在请求中?
添加一个最大等待时间判断:
服务器在接收到请求后,阻塞而不立刻返回。如果有新的事件,或者达到超时时间,再响应这个请求;避免服务器的无限等待。
典型产品
让服务器和浏览器实现双向通信
// 插件WebSocket链接
var ws = new WebSocket("ws://url", "websocket");
ws.onopen = function() {
console.log('open');
};
// 接收服务器端的数据
ws.onmessage = function(evt) {
console.log(evt.data);
};
// 向服务器发送客户端数据
ws.send('client data');
// 关闭链接
ws.onclose = function() {
console.log('close');
};
缺陷:
优点:
基于客户端Socket编程
谢谢!