bridge.js 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. /**
  2. * 跨窗口消息传递
  3. * @module $ui/utils/bridge
  4. */
  5. import Messager from './messager'
  6. import Utils from '@/utils/util'
  7. /**
  8. * 向目标发送信息
  9. * @param {object} options 参数对象
  10. * @param {string} options.bridge 目标的桥页面url地址
  11. * @param {string} options.channel 消息频道名称
  12. * @param {*} [options.data] 消息内容
  13. * @param {string} [options.origin] 自身的桥地址,目标可以通过桥联系到自己
  14. */
  15. export function fire({ bridge, channel, data, origin }) {
  16. return new Messager({
  17. bridge: bridge,
  18. origin: origin,
  19. ready(instance) {
  20. instance.fire(channel, data)
  21. setTimeout(() => {
  22. instance.destroy()
  23. }, 0)
  24. }
  25. })
  26. }
  27. /**
  28. * 接收目标发送过来的信息
  29. * @param channel 消息频道名称
  30. * @param handler 消息处理函数
  31. * @param opts Messager参数
  32. * @return {Messager}
  33. */
  34. export function on(channel, handler, opts = {}) {
  35. const instance = new Messager(opts)
  36. instance.on(channel, handler)
  37. return instance
  38. }
  39. /**
  40. * 接收目标发送过来的信息, 只接收一次
  41. * @param channel 消息频道名称
  42. * @param handler 消息处理函数
  43. * @return {Messager}
  44. */
  45. export function once(channel, handler) {
  46. const instance = on(channel, (data) => {
  47. handler(data)
  48. instance.destroy()
  49. })
  50. return instance
  51. }
  52. /**
  53. * 调用消息服务
  54. * @param {string} name 服务名称
  55. * @param {string} bridge 服务提供方的桥页面地址
  56. * @param {*} data 发送的数据
  57. * @param {string} origin 自己的桥页面地址
  58. * @param {function} callback 回调函数,服务提供方响应的数据通过回调返回
  59. *
  60. * @example
  61. *
  62. * // 请求服务
  63. service({
  64. name: 'MyService',
  65. bridge: 'http://localhost:8001/app1/assets/bridge/index.html',
  66. origin: 'http://localhost:8000/assets/bridge/index.html',
  67. data: {
  68. id: '123'
  69. },
  70. callback(res) {
  71. console.log('服务响应信息', res)
  72. }
  73. })
  74. */
  75. export function service({ name, bridge, data, origin, callback }) {
  76. const _uid = Utils.guid()
  77. const postMessage = {
  78. uid: _uid,
  79. data: data
  80. }
  81. // 如果有回调,以uid为事件名称的通道接收回调数据
  82. if (callback) {
  83. const callbackId = name + _uid
  84. once(callbackId, message => {
  85. // uid匹配才触发回调
  86. if (message.uid === _uid) {
  87. callback(message.data)
  88. }
  89. })
  90. }
  91. fire({ bridge, data: postMessage, origin, channel: name })
  92. }
  93. /**
  94. * 创建服务提供者
  95. * @param {string} name 服务名称
  96. * @param {string} origin 自己的桥页面地址
  97. * @param {function} handler 服务消息句柄函数,当服务被调用时触发,参数:data(调用服务传过来的数据),callback响应函数,通过回调响应给调用者
  98. * @return {Messager}
  99. *
  100. * @example
  101. *
  102. * // 创建一个服务提供者
  103. * const messager = provider({
  104. name: 'MyService',
  105. origin: 'http://localhost:8000/assets/bridge/index.html',
  106. handler: function (data, callback) {
  107. const response = '响应内容'
  108. callback(response)
  109. }
  110. })
  111. // 销毁
  112. messager.destroy()
  113. */
  114. export function provider({ name, origin, handler }) {
  115. return on(name, (message, bridge) => {
  116. const callbackId = name + message.uid
  117. const callback = (data) => {
  118. fire({
  119. bridge,
  120. data: { uid: message.uid, data: data },
  121. origin,
  122. channel: callbackId
  123. })
  124. }
  125. handler(message.data, callback)
  126. })
  127. }