参考:http://www.cnblogs.com/giggle/p/5350288.html(浅谈webWorker

http://blog.csdn.net/zha_zi/article/details/41677033 HTML5 中 postMessage sendMessage 用法

Web Workers----工作线程

Html5对多线程的支持。在 HTML5 中提出了工作线程(Web Workers)的概念。用于解决页面之间数据处理的多线程,加快数据处理。如同java中的Thread。

Web Workers 的三大主要特征: 能够长时间运行(响应),理想的启动性能以及理想的内存消耗。

Web Workers 允许开发人员编写能够长时间运行而不被用户所中断的后台程序,去执行事务或者逻辑,并同时保证页面对用户的及时响应。

Web Workers 为 Web 前端网页上的脚本提供了一种能在后台进程中运行的方法。一旦它被创建,Web Workers 就可以通过 postMessage 向任务池发送任务请求,执行完之后再通过 postMessage 返回消息给创建者指定的事件处理程序 ( 通过 onmessage 进行捕获 )。Web Workers 进程能够在不影响用户界面的情况下处理任务,并且,它还可以使用 XMLHttpRequest 来处理 I/O,但通常,后台进程(包括 Web Workers 进程)不能对 DOM 进行操作。如果希望后台程序处理的结果能够改变 DOM,只能通过返回消息给创建者的回调函数进行处理。

主线程-----------------------------------------------------

var worker = new Worker('***.js');

--仅能存放同域的处理数据用,或ajax调用数据用的js,子线程的js不能操作dom节点,因为子线程不能影响主线程对dom的操作。

worker.postMessage(data); 通过postMessage方法来关联主子线程。data为任意值

worker.terminate();     终止workers,一旦终止则不能再使用,需要重新new worker

worker.message(); 接收信息用,放入监控中则一直有效。

worker.error();  对错误的处理

子线程--------------------------------------------------------

子线程中的js可操作范围:

worker.js执行的上下文与主页面html执行时的上下文并不相同,最顶层的对象并不是window,而是WorkerGlobalScope。

因此window的alert方法在此js中不能用。WorkerGlobalScope的属性方法:

1、self

  我们可以使用 WorkerGlobalScope 的 self 属性来或者这个对象本身的引用

2、location

  location 属性返回当线程被创建出来的时候与之关联的 WorkerLocation 对象,它表示用于初始化这个工作线程的脚步资源的绝对 URL,即使页面被多次重定向后,这个 URL 资源位置也不会改变。

3、close

  关闭当前线程,与terminate作用类似

4、importScripts

  我们可以通过importScripts()方法通过url在worker中加载库函数

5、XMLHttpRequest

  有了它,才能发出Ajax请求

6、setTimeout/setInterval以及addEventListener/postMessage

  1.可以加载一个JS进行大量的复杂计算而不挂起主进程,并通过postMessage,onmessage进行通信

  2.可以在worker中通过importScripts(url)加载另外的脚本文件

  3.可以使用 setTimeout(), clearTimeout(), setInterval(), and clearInterval()

  4.可以使用XMLHttpRequest来发送请求

  5.可以访问navigator的部分属性

局限性:

  1.不能跨域加载JS

  2.worker内代码不能访问DOM

  3.各个浏览器对Worker的实现不大一致,例如FF里允许worker中创建新的worker,而Chrome中就不行

示例:

加载报错“Uncaught DOMException: Failed to construct 'Worker': ”   --部分浏览器不允许本地加载外部文件,需要放在web容器中运行。

 $(function($){
if(typeof(window.Worker) != 'undefined'){
var worker = new Worker('worker.js');
worker.postMessage("主线程:请求处理数据------");
worker.onmessage = function(e){ // 注意这里message是小写
console.log("---" + e.data);
}
worker.onerror = function(e){
console.log("---" + e.message);
worker.terminate();
}
worker.postMessage("主线程:请求处理数据------");
}
console.log("我只是飘过。。。。。");
});
 /**
* worker.js 的上下文顶级对象为WorkerGlobalScope,没有document和windows对象。因此dom元素不能操作,windows的部分方法不能使用.注意保存的编码格式
* DennyZhao
* Date:2017/9/22
*/
var self = this;
  self.importScripts('script1.js'); //限定为WorkerGlobalScope对象内容
  self.onmessage = function(event){
//console.log("-----work);//这个不起作用不支持console
9 self.postMessage(" 开始处理主线程的任务。。。。。。" + event.data);
var a = event.data;
a += "处理过程¥¥";
self.postMessage("主线程的任务处理完毕........" + a);
self.close(); }
结果:
我只是飘过。。。。。
--- 开始处理主线程的任务。。。。。。主线程:请求处理数据------
---主线程的任务处理完毕........主线程:请求处理数据------处理过程¥¥

Cross-document messaging

Cross-document messaging 简介

H5推出的信息队列调用,可以解决两个window之间的信息共享,iframe内外信息传递,本地调用远端页面到本地的跨域信息传递,方法调用等问题。

不过仅限于前台web的页面之间调用,还没办法解决跨域的前台和后台的调用,还需用Ajax的jsonP形式进行传递。

postMessage采用异步通信的方式,因此可以做页面的js动作和渲染用。同时不影响别的代码继续执行,提高处理速度。

1.本地自身使用消息队列的postMessage(如果同时执行在同一个window上,会因为渲染和js处理同时进行导致并发出错)

   window.addEventListener('message',function(e){
console.log("event------" + e.data);
},false);
// postMessage
$(function($){
function postMessages(){
window.postMessage("12345","/");
console.log("--45678----");
}
postMessages();
}); 结果:异步执行动作
--45678----
event------12345

2. iframe中的内外交互

在windows/system32/driver/etc/host 下,修改127.0.0.1

127.0.0.1 test.com

127.0.0.1 test2.com

这样就形成跨域请求,如果不跨域时,可不设置。(以上为测试用)

   <script type="text/javascript"> --父窗体
// postMessage
window.addEventListener("message", function(event){
$("div").css("backgroundColor","#" + event.data);
});
$(function($){
//$("#myIframe")[0].contentWindow.postMessage("getMessage", "http://test2.com:8080"); 放此地方报错,iframe的src还未装载
$("button").click(function(){
$("#myIframe")[0].contentWindow.postMessage("getMessage", "http://test2.com:8080"); //注意此处调用子url时需要iframe已经产生渲染完毕。
}); }); </script>
   <script type="text/javascript">  --iFrame
var color= 50;
window.addEventListener("message", function(event){
$('div').css("backgroundColor", "red"); },false);
// postMessage
$(function($){ $('div').click(function(){
color = color + 100000;
$(this).css("backgroundColor", "#" + color);
window.top.postMessage(color, "http://test.com:8080");
}); }); </script>

3. openWindow中使用

   <script type="text/javascript">
// postMessage
window.addEventListener("message", function(event){
$("div").css("backgroundColor","#" + event.data);
});
$(function($){
//$("#myIframe")[0].contentWindow.postMessage("getMessage", "http://test2.com:8080"); 放此地方报错,iframe的src还未装载
$("button").click(function(){
var child = window.open("http://test2.com:8080/webtest/worker/iFrame.html", "_blank");
var my = setInterval(function(){
if(child && !child.closed){
child.postMessage("getMessage", "http://test2.com:8080"); //注意此处调用子url时需要window已经产生
clearInterval(my);
}
}, 200);
}); }); </script>
   <script type="text/javascript">
var color= 50;
window.addEventListener("message", function(event){
$('div').css("backgroundColor", "red"); },false);
// postMessage
$(function($){ $('div').click(function(){
color = color + 100000;
$(this).css("backgroundColor", "#" + color);
window.opener.postMessage(color, "http://test.com:8080");
}); }); </script>

WebSockets

WebSockets 简介

在 Web 应用中,HTTP 协议决定了客户端和服务端连接是短连接,即客户端 Request,服务端 Response,连接断开。要想实现客户端和服务端实时通信,只能通过客户端轮询来实现。服务端推送数据也并不是字面上意思上的直接推,其实还是客户端自己取。WebSockets 是 HTML5 规范新引入的功能,用于解决浏览器与后台服务器双向通讯的问题,使用 WebSockets 技术,后台可以随时向前端推送消息,以保证前后台状态统一。

在 WebSockets 中使用 send 和 onmessage发送和接收信息。

WebSockets 服务器端有 jetty 提供的基于 Java 的实现,有 WebSocket-Node 基于 node.js 的实现。

1.选用nodeJs作为服务器端应用(参见nodejs 创建webSocket)

 var WebServer = require('ws').Server;
var wss = new WebServer({port:3500});
wss.on('connection', function(ws){
console.log('创建连接成功!');
ws.on('message', function(msg){
console.log(msg);
});
setInterval(function(){
ws.send(Math.random() * 10000);
},1000);
});

前台发送信息到后台: 1 <script type="text/javascript"> 2 $(function($){

          var server = {
ws : {},
connection : function(){
this.ws = new WebSocket("ws://test.com:3500/");
this.recieve();
this.open();
this.ws.onerror = function(error, data){
console.log("error : " + error);
server.ws.close();
}
},
send : function(_msg){
server.ws.send(_msg);
},
recieve : function(){
server.ws.onmessage = function(event){
if(event.data){
$("<div>").text(event.data).appendTo('body');
}
}
},
close : function(){
server.ws = null;
},
open : function(){
server.ws.onopen= function(){
           
35 console.log("webSocket已经链接.......");
36                         server.ws.send('webSocket已经创建');
             }
};
// 连接
server.connection();
var i = 0;
var myInterval = setInterval(function(){
i = i + 1;
server.send('发送 ' + i + ': ');
if(server.ws.readyState != 1){
clearInterval(myInterval);
}
}, 1000);
}); </script>

结果:

 C:\Users\Administrator\Desktop\test\nodeJs>node websocket
创建连接成功!
webSocket已经创建
发送 1:
发送 2:
发送 3:
发送 4:
发送 5:
发送 6:
发送 7:
发送 8:
发送 9:
发送 10:
发送 11:
发送 12:
发送 13:
发送 14:
发送 15:
发送 16:
发送 17: 页面接收部分:-----
4848.977736803326
7762.762571534494
3343.602966652355
1073.4970072202343
8700.747665594601
2556.6261964728064
3065.183213127105
134.2700772638583
7319.230923541
3183.5101594279868
6892.64312993447
1412.415079333049
6946.477577338111
4111.868595940827
5996.174673001297
4171.965367213602
1790.7039601051533

结果

Server-Sent Events

HTML5 Server-Sent 事件模型允许您从服务器 push 实时数据到浏览器。与Web-Socket相比,Server-Sent Events 仅可由服务器向客户端单方面推送信息,而不能有客户端向服务端推送请求。好处是不用建立服务端的 WebSocket服务。

利用 Eventsource 对象处理与页面间的接收和发送数据。在客户端,我们使用 HTML5+JavaScript,服务端使用 Java。在现存的 Ajax 模式中,web 页面会持续不断地请求服务器传输新数据,由客户端负责请求数据。而在服务端发送模式下,无需在客户端代码中执行连续的数据请求,而是由服务端 push 推送更新。一旦您在页面中初始化了 Server-Sent 事件,服务端脚本将持续地发送更新。客户端 JavaScript 代码一旦接收到更新就将新的数据写入页面中展示出来。使用基于 Java 的 Servlet 技术实现服务器端。

为方便快捷,我们使用nodejs作为服务器端。

 var http = require('http');
const path = require('path');
path.basename('index.html');
var url = require('url');
var fs = require('fs');
var filehome = "./html";
http.createServer(function(req,res){
console.log('');
// 文件系统
if(req.url.search(/\.html|\.js/i) > 0){
filepath = filehome + req.url;
fs.readFile(filepath, function(error, data){
if(error){
res.writeHeader(404, {"Content-Type":"text/html;charset='utf-8'"});
res.write('<h1>404错误</h1><p>你要找的页面不存在</p>');
res.end();
}else{
res.writeHeader(200, {"Content-Type":"text/html;charset='utf-8'"});
res.write(data);
res.end();
}
});
return;
} // 请求处理
var pathname = url.parse(req.url).pathname;
res.writeHeader(200, {"Content-Type":"text/event-stream"});
if(pathname.search('/serverEvent') > -1){
setInterval(function(){
var date = new Date().getTime();
var content = "data:" + date + "\n\n";
res.write(content);
res.flushHeaders();
//res.end(); 此处不能关闭,不然会中断Server-Sent EVENT抛出error
}, 1000);
}
}).listen(3011, '127.0.0.1'); console.log("启动成功,请去http://127.0.0.1:3011 下尝试。。。。");

客户端:

      $(function($){
var source = new EventSource('http://127.0.0.1:3011/serverEvent');
source.onmessage=function(event){
$("<div>").text(event.data).appendTo('body');
};
source.onerror = function(error, event){
$("<div>").text('Error is occur.....').appendTo('body');
} source.open=function(event){
$("<div>").text("连接创建成功。。。。。").appendTo('body');
};
});

postMessage和sendMessage的更多相关文章

  1. PostMessage与SendMessage各自的问题

     深入解析SendMessage.PostMessage 本文将使用C++语言,在MFC框架的配合下给出PostMessage.SendMessage等的使用方式与使用不当造成的后果(讨论均针对自定义 ...

  2. [C#.net]PostMessage与SendMessage的区别

    用 PostMessage.SendNotifyMessage.SendMessageCallback 等异步函数发送系统消息时,参数里不可以使用指针,因为发送者并不等待消息的处理就返回,接受者还没处 ...

  3. PostMessage与SendMessage的区别(二)

    在做基于窗口的Windows程序的时候,我们避免不了要向窗口发送消息,有两种方式,一种是PostMessage,另外一种是SendMessage.关于这两个宏,我是通过狠狠的看MSDN才搞明白的,那里 ...

  4. MFC发送自定义消息-PostMessage和SendMessage

    PostMessage:把消息投放到线程的消息队列,不能消息被处理就立即返回SendMessage:消息被处理完后才返回 几种发送消息的写法:   ::PostMessage(GetSafeHwnd( ...

  5. PostMessage和SendMessage的区别

    1, PostMessage只把消息放入队列,不管其他程序是否处理都返回,然后继续执行,这是个异步消息投放函数.而SendMessage必须等待其他程序处理消息完了之后才返回,继续执行,这是个同步消息 ...

  6. postmessage and sendmessage

    从msdn上看二者的解释: postmessage : Places (posts) a message in the message queue associated with the thread ...

  7. PostMessage与SendMessage的区别

    PostMessage只负责将消息放到消息队列中,不确定何时及是否处理 SendMessage要等到受到消息处理的返回码(DWord类型)后才继续 PostMessage执行后马上返回 SendMes ...

  8. VC++中PostMessage、SendMessage和PeekMessage之间的区别

    1, PostMessage只把消息放入队列,不管其他程序是否处理都返回,然后继续执行,这是个异步消息投放函数.而SendMessage必须等待其他程序处理消息完了之后才返回,继续执行,这是个同步消息 ...

  9. MFC窗口消息PostMessage和SendMessage

    以前这些消息用得比较少,但是今天碰到了个事儿,我看非用消息不可. 事情是这样的,我在线程中需要刷新对话框上面的内容,但是每每执行到UpdateData时就出现了断言错误. 查了相关资料,发现这个可能是 ...

随机推荐

  1. dbt 包管理

    dbt 可以方便的支持基于git 的包管理 依赖申明 位置 dbt_project.yml 中的repositories 或者使用packages.yaml 格式 dbt_project.yml: r ...

  2. [C++] 一个能够定时自毁的类的实现

    试想一下, 有没有这种需求: 对于每一个新的对象, 我们希望它能够在一定时间后自动销毁, 前提是我们没有在这段时间内给它发出重置信号. 这种需求其实是有的, 比如在电影里, 主角知道了一个反派不希望被 ...

  3. 投行的码工 Dead-end job

    发信人: icestonesy (无忧), 信区: Quant 标  题: 投行的码工怎么样? 发信站: BBS 未名空间站 (Sat May 16 23:25:00 2015, 美东) 最近看到不少 ...

  4. centos7 取消自动锁屏

    CentOS7默认短时间会锁屏,这带来了一定的麻烦,比如看电影时,你不得不时不时的动动鼠标,才能防止锁屏.在网上查了一些资料,也没有找到相关的解决办法,不过最终还是找到了. 1.打开 applicat ...

  5. 【jmeter】jmeter聚合报告之90%Line参数说明

    其实要说明这个参数的含义非常简单,可能你早就知道他的含义,但我对这个参数一直有误解,而且还一直以为是“真理”,原于一次面试,被问到了这个问题,所以引起我这个参数的重新认识. 先说说我错误的认识: 我一 ...

  6. antd在线换肤定制功能

    最近react项目,用的antd框架,然后看见他的antdPro例子里面有个定制功能很帅,老大说做,那就做吧,鼓捣了一晚终于实现了. 先看预览效果吧 css换肤 入行前端的时候经常看鱼哥(张鑫旭)的博 ...

  7. Linux内核深入研究之进程的线性地址空间-传统版

    引言: 了解Linux环境下,进程的地址空间划分,对于我们理解Linux应用程序有很大的帮助,否则会被New与Malloc之类的指针操作弄的晕头转向,本文基于Linux内核讲述了Linux/Unix线 ...

  8. spring扩展点之三:Spring 的监听事件 ApplicationListener 和 ApplicationEvent 用法,在spring启动后做些事情

    <spring扩展点之三:Spring 的监听事件 ApplicationListener 和 ApplicationEvent 用法,在spring启动后做些事情> <服务网关zu ...

  9. GC之五--SystemGC完全解读

    目录: GC之一--GC 的算法分析.垃圾收集器.内存分配策略介绍 GC之二--GC日志分析(jdk1.8)整理中 GC之三--GC 触发Full GC执行的情况及应对策略 gc之四--Minor G ...

  10. R语言学习——输入与输出

    导入数据: grades<-read.table("D:/ProgramData/test1.txt",sep="\t") 求均值:mean() 求方差: ...