前端进阶之旅前端进阶之旅
基础篇
进阶篇
高频篇
精选篇
手写篇
原理篇
面经篇
AI 面试
自检篇
每日一题
  • 综合
    • 综合题型
    • 其他问题
    • 设计模式
    • 思维导图
    • 学习路线
  • 前端基础
    • HTTP
    • 浏览器
    • 计算机基础
  • 进阶学习
    • NPM工作流
    • Docker
    • Canvas
    • Node学习指南
    • 前端综合文章
  • 其他
    • Handbook
    • 职场话题
    • CSS可视化
小程序题库
公众号动态
博客动态
开发者导航
基础篇
进阶篇
高频篇
精选篇
手写篇
原理篇
面经篇
AI 面试
自检篇
每日一题
  • 综合
    • 综合题型
    • 其他问题
    • 设计模式
    • 思维导图
    • 学习路线
  • 前端基础
    • HTTP
    • 浏览器
    • 计算机基础
  • 进阶学习
    • NPM工作流
    • Docker
    • Canvas
    • Node学习指南
    • 前端综合文章
  • 其他
    • Handbook
    • 职场话题
    • CSS可视化
小程序题库
公众号动态
博客动态
开发者导航
  • React专栏

    • React组合式开发实战

      • 前端开发的四个时代
      • 企业管理系统的前世今生
      • 可视化页面搭建工具
      • 实战篇 01:开发前准备
      • 实战篇 02:项目脚手架
      • 实战篇 03:页面布局方案
      • 实战篇 04:权限管理机制
      • 实战篇 05:菜单匹配逻辑
      • 实战篇 06:消息通知设计
      • 实战篇 07:多语言支持
      • 继往开来:可视化页面搭建工具
    • React Hooks与Immutable实战

    • React SSR服务端渲染与同构实践

    • IM聊天系统前端开发实践

    • 微前端开发实战

    • React进阶实践

  • Vue专栏

  • 移动端专栏

  • Node专栏

  • 前端工程化专栏

  • 算法专栏

  • Typescript专栏

  • 其他专栏

完整面试题地址:
作者:程序员poetry
扫码关注作者公众号:「前端进阶之旅」 每天分享技术干货
前端进阶之旅公众号二维码

# 前言

渲染线程讲解完后。这一章节我们来探索一下微信小程序的通讯系统。来看一下渲染线程是如何通讯逻辑线程的。

本章节内容分解:

  • 小程序通讯系统原理

# 通讯系统

先重顾看一下微信小程序的线程架构图。

image.png

可以看到sendData并不是直接指向逻辑层的(也就是Event这两条线)。小程序逻辑层和渲染层的通信会由 Native (微信客户端)做中转,逻辑层发送网络请求也经由 Native 转发。我们先留有这个概念。

# 通讯原理

Native做中转的话需要一个契机,就是WeixinJSBridge,WeixinJSBridge提供了渲染层与Native、Native与逻辑层之间消息通信的机制。机制是机制,那么具体的通讯手段是什么呢?

根据不一样的客户端通讯手段是不一样的,统一的机制为了更好的兼容不同的客户端,具体的通讯手段分为几种。

内置组件中有部分组件是利用到客户端原生提供的能力,既然需要客户端原生提供的能力,那就会涉及到渲染层与客户端的交互通信。这层通信机制在 iOS 和安卓系统的实现方式并不一样,iOS 是利用了 WKWebView 的提供 messageHandlers 特性,而在安卓则是往 WebView 的 window 对象注入一个原生方法,最终会封装成 WeiXinJSBridge 这样一个兼容层。在微信开发者工具中则是使用了websocket进行了封装。

在微信小程序执行过程中,Native层,也就是客户端层分别向渲染层与逻辑层注入WeixinJSBridge以达到线程通讯的目的,前面章节中在分析渲染层结构和逻辑层结构中我们也都看到了其中WeixinJSBridge的<script>标记注入,WeixinJSBridge提供了如下几个方法:

  • invoke - 调用 Native API,以api方式调用开发工具提供的基础能力,并提供对应api执行后的回调。
  • invokeCallbackHandler - Native 传递 invoke 方法回调结果
  • on - 用来收集小程序开发者工具触发的事件回调
  • publish - 渲染层发布消息,用来向逻辑业务层发送消息,也就是说要调用逻辑层的事件方法
  • subscribe - 订阅逻辑层消息
  • subscribeHandler - 视图层和逻辑层消息订阅转发
  • setCustomPublishHandler - 自定义消息转发

上面说到初始化过程中Native层理论上是微信客户端,分别在视图层和业务逻辑层注入了WeixinJSBridge,但是由于运行环境的关系,比如我们现在正用的微信开发者工具来说,它并不是微信客户端,并没有Native。那么他是用什么手段进行线程与线程之间的通讯的呢?是Websocket。并且微信开发者工具在WeixinJSBridge的基础上进行了上面几个方法的重构,以达到调用微信开发者工具(IDE)功能目的。

那么是哪几个方法进行了重写呢,在源码中我们找到答案:

image.png

那我们就来继续探索一下,这几个方法。

首先这几个方法在微信开发者工具应用的文件夹中可以找到,目录为Contents/Resources/app.nw/js/extensions/pageframe/index.js。我们找到打开之后里面的代码依然是压缩的。这里使用 js-beautify工具美化一下这个压缩的代码,以便于我们进行解析。

$ js-beautify index.js -o beautifyIndex.js
@前端进阶之旅: 代码已经复制到剪贴板

这样的话目录中就会多处一个美化后的js文件。建议把目标文件拷贝出来再进行操作。

打开这个“美化”之后的js文件后,发现依然还是很难读懂,哈哈,暂时我也没啥办法,有人认识小程序部门的人看看能不能要一份源码,记得发我一份。

在讲这几个方法之前我们先确认一个事情,就是微信开发者工具的通讯机制真的是websocket吗,我们从源码的角度来看一下。

# Websocket

首先我们找到上面所说的Websocket模块源码

websocket.jpg

可以看到模块内包含了websocket的创建、建立连接,收发数据,并且模块开放了一些方法,比如send、connect、registerCallback、removeCallback。

websocket建立连接了之后就是进行通讯协议约定,就像火车一样,你买的不一样的火车票,同样的火车就会拉你去不一样的地方。因为我们约定了不一样的火车票要去不一样的地方。

# invoke

invoke主要是用来 调用 Native API,在微信开发者工具中以api方式调用开发者工具提供的基础能力。

view层会统一向websocket服务发送command: WEBVIEW_INVOKE的命令,根据参数中的api值来确定调用开发者工具具体的api方法。调用完毕后,websocket服务向view层发送command: WEBVIEW_INVOKE_CALLBACK命令,渲染层根据此标识知道api调用完毕,然后执行对应的回调。

用过websocket的时候一样要约定一些通讯协议,比如PUBLISH_MAP_DATA: { k: v }。所上面的将的command就是这样约定的通讯协议来区分功能。

fe
基础篇
进阶篇
高频篇
精选篇
手写篇
原理篇
面经篇
AI 面试
自检篇
每日一题
  • 综合
    • 综合题型
    • 其他问题
    • 设计模式
    • 思维导图
    • 学习路线
  • 前端基础
    • HTTP
    • 浏览器
    • 计算机基础
  • 进阶学习
    • NPM工作流
    • Docker
    • Canvas
    • Node学习指南
    • 前端综合文章
  • 其他
    • Handbook
    • 职场话题
    • CSS可视化
小程序题库
公众号动态
博客动态
开发者导航
  • React专栏

    • React组合式开发实战

      • 前端开发的四个时代
      • 企业管理系统的前世今生
      • 可视化页面搭建工具
      • 实战篇 01:开发前准备
      • 实战篇 02:项目脚手架
      • 实战篇 03:页面布局方案
      • 实战篇 04:权限管理机制
      • 实战篇 05:菜单匹配逻辑
      • 实战篇 06:消息通知设计
      • 实战篇 07:多语言支持
      • 继往开来:可视化页面搭建工具
    • React Hooks与Immutable实战

    • React SSR服务端渲染与同构实践

    • IM聊天系统前端开发实践

    • 微前端开发实战

    • React进阶实践

  • Vue专栏

  • 移动端专栏

  • Node专栏

  • 前端工程化专栏

  • 算法专栏

  • Typescript专栏

  • 其他专栏