Web跨浏览器进程通信(Web跨域)


Posted in Javascript onApril 17, 2013

在之前一篇文章里尝试了跨浏览器的数据共享,最后提到使用LocalConnection还可以实现跨浏览器消息交互的可行性。

花了两个晚上简略的研究了下,LocalConnection的单向通信非常的简单,不过要实现多个终端交互,必须自己实现一套消息机制,见智见仁了。

为了简单演示,本例使用了基于广播的观察者模式:每个终端可以订阅自己感兴趣的主题,也可以向广播发送消息,通知其他感兴趣的终端。

Demo: http://www.etherdream.com/FunnyScript/WebIPC/ (多开几个浏览器页面小窗口,即可测试)

比较遗憾的是最新版的Chrome浏览器仍然无法和其他浏览器进程交互:(

如果没有错误发生,应该就是如下的效果:

Web跨浏览器进程通信(Web跨域)

在任何一个页面上的操作,都会立即同步到其他页面里,只要Observe了感兴趣的主题。

为什么要使用观察者模式呢?因为跨进程的通信是比较耗资源的,所以不感兴趣的消息可以直接不订阅,而不是收到再放弃。

LocalConnection是为单一的通信设计的,虽然使用很简单,但可用的接口少之又少。想直接用它来广播事件,或者消息路由,门都没有。

因此底层的消息发送上没有太多可选余地,只能简单的点对点发送。我们必须创建多个LocalConnection,来实现消息的汇聚和分发。

LocalConnection真正能用的只有两个方法:

connect(name) —— 创建管道(每个LocalConnection只能创建一个管道,每个管道名只能有一个)

send(name, ...) —— 向管道发送数据

如果只有两个终端通信,那么一切都是那么简单。。。

Web跨浏览器进程通信(Web跨域)

只需简单的将消息发送给对方即可。

不过有多个终端情况就大不相同了。由于我们是本地进程间通信,并没有第三方服务器主持,加上LocalConnection只能点对点的发送消息。意味着每次广播都要给其他所有的终端都发送一次,这样复杂度就大大增加了。

为了简化结构,我们模拟一个LocalConnection作为Host,在第一次启动时运行。其余的作为Client,每次广播消息都提交给Host,由它来调度。

Web跨浏览器进程通信(Web跨域)

Host维护着一个回调列表。当Client对某个主题(subject)感兴趣时,可以发送<主题ID,自己的管道名>给Host来订阅。于是Host就把此Client的管道名添加到该主题的回调列表里。以后若有该主题的消息,即可根据回调列表通知订阅的Client。

为了能让Host和Client通信更简单,这里使用channel+ID的命名规则,来创建管道名。

Host的ID为空,于是Client发送数据只需send(channel)即可;

Client的ID从1~100,选一个没用被占用的作为管道名。Host回调时只需send(channel+id)就能通知对应的Client。

然而,这个Host服务仅仅是假象的。我们根本没法在页面之外运行一个第三方服务,一切只能在页面中实现!于是我们把第一次启动的页面作为Host。当这个页面关闭时,我们再通知第二个页面创建Host,以此类推。。。

Web跨浏览器进程通信(Web跨域)

由于没有第三方服务器,每个Client都可以兼职做Host。到这里,你是不是想到了局域网游戏?由于没有服务器,第一个创建的玩家便是主机。当他退出时,主机就交给了第二个玩家。如果他没按正常步骤,强制退出了游戏,那就很有可以造成主机丢失,数据没来得及转移给下个玩家,导致游戏断线结束。

同样,当我们Host所在页面关闭时,会向所有Client发送一条退出消息。至于谁继承王位,不用关心,谁先得知谁做~~ 唯一值得注意的就是:很多浏览器不能正常触发window.unload事件,这意外着Host可能还没来得把回调列表移交给他的继承者就已匆匆离去,于是后人就无法接管了。为了不让这种情况出现,每当新的Host上任,就向所有的Client发送一个请求,让大家把各自关注的主题重新发送一遍(之前关注的都保存着,就为了这个时候用)。因此,即使新上任的Host一无所有,大家也会把现状告诉他,可立即投入工作中。

若是强制关闭了Host所在的页面进程,那么主机丢失后一切都将会挂起。这时所有Client发送的数据都将有去无回,只有等到之后出现数据发送失败,才得知Host已经挂了。这时谁先发现这个错误,谁就接管Host工作吧。

当然,还可以考虑加上心跳机制,即使Host没有挂掉,但其所在进程长时间占用CPU,导致LocalConnection无法响应消息事件,也可以考虑转移Host了。

由于时间限制,本例还有不少BUG,以后再慢慢完善。

想看代码可以浏览:http://code.google.com/p/webipc/source/browse/

事实上纯粹的本地通信意义并不大,只有配合远程服务进行消息的交互,才更有意义。例如用户开了多个微博页面,传统的模型必须为每个页面发起一个长连接,来保持实时的数据接收。如果使用跨浏览器通信,那么只需让Host发起一个连接即可,其余的Client订阅自己想要的主题,最终只需一个连接就可以。

Javascript 相关文章推荐
Cookie 注入是怎样产生的
Apr 08 Javascript
Javascript Select操作大集合
May 26 Javascript
javascript学习笔记(九)javascript中的原型(prototype)及原型链的继承方式
Apr 12 Javascript
JavaScript全排列的六种算法 具体实现
Jun 29 Javascript
判断文件是否正在被使用的JS代码
Dec 21 Javascript
jquery实现效果比较好的table选中行颜色
Mar 25 Javascript
JS循环遍历JSON数据的方法
Jul 08 Javascript
Thinkphp模板没有解析直接原样输出的解决方法
Oct 31 Javascript
JS实现的仿东京商城菜单、仿Win右键菜单及仿淘宝TAB特效合集
Sep 28 Javascript
jQuery Validate设置onkeyup验证的实例代码
Dec 09 Javascript
React Native自定义控件底部抽屉菜单的示例
Feb 08 Javascript
如何用webpack4.0撸单页/多页脚手架 (jquery, react, vue, typescript)
Jun 18 jQuery
js读写(删除)Cookie实例详解
Apr 17 #Javascript
基于dom编程中 动态创建与删除元素的使用
Apr 17 #Javascript
javaScript(JS)替换节点实现思路介绍
Apr 17 #Javascript
用函数模板,写一个简单高效的 JSON 查询器的方法介绍
Apr 17 #Javascript
JS对img进行操作(换图片/切图/轮换/停止)
Apr 17 #Javascript
用显卡加速,轻松把笔记本打造成取暖器的办法!
Apr 17 #Javascript
js跑马灯代码(自写)
Apr 17 #Javascript
You might like
收音机频率指针指示不准确和灵敏度低问题
2021/03/02 无线电
php tp验证表单与自动填充函数代码
2012/02/22 PHP
Yii使用migrate命令执行sql语句的方法
2016/03/15 PHP
php倒计时出现-0情况的解决方法
2016/07/28 PHP
php array_key_exists() 与 isset() 的区别
2016/10/24 PHP
PHP实现时间比较和时间差计算的方法示例
2017/07/24 PHP
javascript jQuery $.post $.ajax用法
2008/07/09 Javascript
获取css样式表内样式的js函数currentStyle(IE),defaultView(FF)
2011/02/14 Javascript
dotopAlert 提示用户需安装播放器的代码
2012/09/17 Javascript
Jqgrid表格随窗口大小改变而改变的简单实例
2013/12/28 Javascript
Javascript学习笔记之 对象篇(一) : 对象的使用和属性
2014/06/24 Javascript
javascript检查浏览器是否支持flash的实现代码
2014/08/14 Javascript
javascript背景时钟实现方法
2015/06/18 Javascript
JS实现单击输入框弹出选择框效果完整实例
2015/12/14 Javascript
微信小程序 视图层(xx.xml)和逻辑层(xx.js)详细介绍
2016/10/13 Javascript
ES6概念 Symbol.keyFor()方法
2016/12/25 Javascript
form表单数据封装成json格式并提交给服务器的实现方法
2017/12/14 Javascript
vue.js分页中单击页码更换页面内容的方法(配合spring springmvc)
2018/02/10 Javascript
详解VUE中常用的几种import(模块、文件)引入方式
2018/07/03 Javascript
JavaScript函数式编程(Functional Programming)高阶函数(Higher order functions)用法分析
2019/05/22 Javascript
python实现进程间通信简单实例
2014/07/23 Python
python字符串对其居中显示的方法
2015/07/11 Python
python让列表倒序输出的实例
2018/06/25 Python
TensorFlow基本的常量、变量和运算操作详解
2020/02/03 Python
HTML5的Video标签有部分MP4无法播放的问题解析(多图)
2017/08/18 HTML / CSS
《藤野先生》教学反思
2014/02/19 职场文书
幼儿教师演讲稿
2014/05/06 职场文书
给学校的建议书范文
2014/05/15 职场文书
市场营销工作计划书
2014/09/15 职场文书
弘扬焦裕禄精神践行三严三实心得体会
2014/10/13 职场文书
2014年科室工作总结
2014/11/20 职场文书
夫妻分居协议书范文
2014/11/26 职场文书
2015年仓库管理员工作总结
2015/04/21 职场文书
2016年会领导致辞稿
2015/07/29 职场文书
python opencv常用图形绘制方法(线段、矩形、圆形、椭圆、文本)
2021/04/12 Python
Pytorch distributed 多卡并行载入模型操作
2021/06/05 Python