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 相关文章推荐
40个新鲜出炉的jQuery 插件和免费教程[上]
Jul 24 Javascript
改进版通过Json对象实现深复制的方法
Oct 24 Javascript
jQuery获取当前对象标签名称的方法
Feb 07 Javascript
JS去除iframe滚动条的方法
Apr 01 Javascript
JS实现在状态栏显示打字效果完整实例
Nov 02 Javascript
Javascript实现单例模式
Jan 24 Javascript
jQuery Easyui 下拉树组件combotree
Dec 16 Javascript
Node.js中Bootstrap-table的两种分页的实现方法
Sep 18 Javascript
Vue框架之goods组件开发详解
Jan 25 Javascript
浅谈webpack4 图片处理汇总
Sep 12 Javascript
其实你可以少写点if else与switch(推荐)
Jan 10 Javascript
jQuery class属性操作addClass()与removeClass()、hasClass()、toggleClass()
Mar 31 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
解析获取优酷视频真实下载地址的PHP源代码
2013/06/26 PHP
PHP根据两点间的经纬度计算距离
2014/10/31 PHP
php+mysql实现无限分类实例详解
2015/01/15 PHP
thinkphp项目部署到Linux服务器上报错“模板不存在”如何解决
2016/04/27 PHP
基于PHP实现的多元线性回归模拟曲线算法
2018/01/30 PHP
Yii2.0框架模型多表关联查询示例
2019/07/18 PHP
php获取是星期几的的一些常用姿势
2019/12/15 PHP
基于PHP实现发微博动态代码实例
2020/12/11 PHP
[原创]提供复制本站内容时出现,该文章转自脚本之家等字样的js代码
2007/03/27 Javascript
屏蔽鼠标右键、Ctrl+n、shift+F10、F5刷新、退格键 的javascript代码
2007/04/01 Javascript
深入理解JavaScript系列(10) JavaScript核心(晋级高手必读篇)
2012/01/15 Javascript
由点击页面其它地方隐藏div所想到的jQuery的delegate
2013/08/29 Javascript
通过js获取div的background-image属性
2013/10/15 Javascript
浅谈js数组和splice的用法
2016/12/04 Javascript
javascript中的深复制详解及实例分析
2016/12/29 Javascript
JS触摸与手势事件详解
2017/05/09 Javascript
深入理解vue.js中的v-if和v-show
2017/06/22 Javascript
微信小程序canvas实现刮刮乐效果
2018/07/09 Javascript
JavaScript前端开发时数值运算的小技巧
2020/07/28 Javascript
详解如何使用React Hooks请求数据并渲染
2020/10/18 Javascript
微信小程序实现可拖动悬浮图标(包括按钮角标的实现)
2020/12/29 Javascript
python 3利用Dlib 19.7实现摄像头人脸检测特征点标定
2018/02/26 Python
Python实现读写INI配置文件的方法示例
2018/06/09 Python
pygame游戏之旅 载入小车图片、更新窗口
2018/11/20 Python
在Python中关于使用os模块遍历目录的实现方法
2019/01/03 Python
python3实现从kafka获取数据,并解析为json格式,写入到mysql中
2019/12/23 Python
给ubuntu18安装python3.7的详细教程
2020/06/08 Python
使用 CSS3 中@media 实现网页自适应的示例代码
2020/03/24 HTML / CSS
韩都衣舍天猫官方旗舰店:天猫女装销售总冠军
2017/10/10 全球购物
美国尼曼百货官网:Neiman Marcus
2019/09/05 全球购物
军人违纪检讨书
2014/02/04 职场文书
工商管理本科生求职信
2014/07/13 职场文书
义务教育学校标准化建设汇报材料
2014/08/16 职场文书
励志演讲稿600字
2014/08/21 职场文书
2016优秀员工先进事迹材料
2016/02/25 职场文书
CSS完成视差滚动效果
2021/04/27 HTML / CSS