博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
postMessage和sendMessage
阅读量:5234 次
发布时间:2019-06-14

本文共 9191 字,大约阅读时间需要 30 分钟。

参考:http://www.cnblogs.com/giggle/p/5350288.html()

         http://blog.csdn.net/zha_zi/article/details/41677033 

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容器中运行。

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

 

结果:我只是飘过。。。。。 --- 开始处理主线程的任务。。。。。。主线程:请求处理数据------ ---主线程的任务处理完毕........主线程:请求处理数据------处理过程¥¥

Cross-document messaging

Cross-document messaging 简介

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

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

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

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

1   window.addEventListener('message',function(e){ 2                console.log("event------" + e.data); 3    },false); 4      // postMessage 5      $(function($){ 6         function postMessages(){ 7             window.postMessage("12345","/"); 8             console.log("--45678----"); 9         }10         postMessages();11      });12 13 14 结果:异步执行动作15 --45678----16 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

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

1   
1   

 

3. openWindow中使用

1   
1   

WebSockets

WebSockets 简介

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

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

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

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

1 var WebServer = require('ws').Server; 2 var wss = new WebServer({port:3500}); 3 wss.on('connection', function(ws){ 4     console.log('创建连接成功!'); 5     ws.on('message', function(msg){ 6         console.log(msg); 7     }); 8     setInterval(function(){ 9         ws.send(Math.random() * 10000);10     },1000);11 });

 

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

3          var server = { 4             ws : {}, 5             connection : function(){ 6                 this.ws = new WebSocket("ws://test.com:3500/"); 7                 this.recieve(); 8                 this.open(); 9                 this.ws.onerror = function(error, data){10                     console.log("error : " + error);11                     server.ws.close();12                 }13             },14             send : function(_msg){15                 server.ws.send(_msg);16             },17             recieve : function(){18                 server.ws.onmessage = function(event){19                     if(event.data){20                         $("
").text(event.data).appendTo('body');21 }22 } 23 },24 close : function(){25 server.ws = null;26 },27 open : function(){28 server.ws.onopen= function(){
            35 console.log("webSocket已经链接.......");
36                         server.ws.send('webSocket已经创建');
47             }48          };49          // 连接50         server.connection();51         var i = 0;52         var myInterval = setInterval(function(){53             i = i + 1;54             server.send('发送 ' + i + ': ');55             if(server.ws.readyState != 1){56                 clearInterval(myInterval);57             }58         }, 1000);59      });60         61   

 

结果:

1 C:\Users\Administrator\Desktop\test\nodeJs>node websocket 2 创建连接成功! 3 webSocket已经创建 4 发送 1: 5 发送 2: 6 发送 3: 7 发送 4: 8 发送 5: 9 发送 6:10 发送 7:11 发送 8:12 发送 9:13 发送 10:14 发送 11:15 发送 12:16 发送 13:17 发送 14:18 发送 15:19 发送 16:20 发送 17:21 22 页面接收部分:-----23 4848.97773680332624 7762.76257153449425 3343.60296665235526 1073.497007220234327 8700.74766559460128 2556.626196472806429 3065.18321312710530 134.270077263858331 7319.23092354132 3183.510159427986833 6892.6431299344734 1412.41507933304935 6946.47757733811136 4111.86859594082737 5996.17467300129738 4171.96536721360239 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作为服务器端。

1 var http = require('http'); 2 const path = require('path'); 3 path.basename('index.html'); 4 var url = require('url'); 5 var fs = require('fs'); 6 var filehome = "./html"; 7 http.createServer(function(req,res){ 8     console.log(''); 9     // 文件系统10     if(req.url.search(/\.html|\.js/i) > 0){11         filepath = filehome + req.url;12         fs.readFile(filepath, function(error, data){13             if(error){14                 res.writeHeader(404, {"Content-Type":"text/html;charset='utf-8'"});15                 res.write('

404错误

你要找的页面不存在

');16 res.end();17 }else{18 res.writeHeader(200, {"Content-Type":"text/html;charset='utf-8'"});19 res.write(data);20 res.end();21 }22 });23 return;24 }25 26 // 请求处理27 var pathname = url.parse(req.url).pathname;28 res.writeHeader(200, {"Content-Type":"text/event-stream"}); 29 if(pathname.search('/serverEvent') > -1){30 setInterval(function(){31 var date = new Date().getTime();32 var content = "data:" + date + "\n\n";33 res.write(content);34 res.flushHeaders();35 //res.end(); 此处不能关闭,不然会中断Server-Sent EVENT抛出error36 }, 1000); 37 }38 }).listen(3011, '127.0.0.1');39 40 console.log("启动成功,请去http://127.0.0.1:3011 下尝试。。。。");

 

客户端:

1      $(function($){ 2         var source = new EventSource('http://127.0.0.1:3011/serverEvent'); 3         source.onmessage=function(event){ 4             $("
").text(event.data).appendTo('body'); 5 }; 6 source.onerror = function(error, event){ 7 $("
").text('Error is occur.....').appendTo('body'); 8 } 9 10 source.open=function(event){11 $("
").text("连接创建成功。。。。。").appendTo('body');12 };13 });

 

转载于:https://www.cnblogs.com/DennyZhao/p/7573223.html

你可能感兴趣的文章
C++ FFLIB 之FFDB: 使用 Mysql&Sqlite 实现CRUD
查看>>
Spring-hibernate整合
查看>>
c++ map
查看>>
exit和return的区别
查看>>
discuz 常用脚本格式化数据
查看>>
洛谷P2777
查看>>
PHPStorm2017设置字体与设置浏览器访问
查看>>
SQL查询总结 - wanglei
查看>>
安装cocoa pods时出现Operation not permitted - /usr/bin/xcodeproj的问题
查看>>
GIT笔记:将项目发布到码云
查看>>
JavaScript:学习笔记(7)——VAR、LET、CONST三种变量声明的区别
查看>>
JavaScript 鸭子模型
查看>>
SQL Server 如何查询表定义的列和索引信息
查看>>
GCD 之线程死锁
查看>>
NoSQL数据库常见分类
查看>>
一题多解 之 Bat
查看>>
Java 内部类
查看>>
{面试题7: 使用两个队列实现一个栈}
查看>>
【练习】使用事务和锁定语句
查看>>
centos7升级firefox的flash插件
查看>>