小程序|websocket入门案例: 构建微信扫小程序码登录系统

小程序|websocket入门案例: 构建微信扫小程序码登录系统

文章图片

小程序|websocket入门案例: 构建微信扫小程序码登录系统

文章图片

小程序|websocket入门案例: 构建微信扫小程序码登录系统


概览
WebSocket 想必各位前后端开发都不陌生这种基于TCP的全双工通信协议 , 比起 HTTP long-polling(长轮询) 来说控制开销少实时性强 。 它通过 HTTP/1.1 协议的101状态码进行握手 。 所以我们使用 nginx 这类来处理它的时候 , 需要配置协议升级 , 到 HTTP/1.1版本 。
而为了创建Websocket连接 , 我们通过客户端发出请求 , 之后服务器进行回应 , 这个过程通常称为 handshaking 。
案例
微信扫码登录 , 想必各位大家都不陌生 , 这个被广泛应用到了社会各个场景 。
同时还衍生出了 , 微信扫公众号二维码登录 和 微信扫小程序码登录  这些本质上原理也都大差不差 。
本文就借着 微信扫小程序码登录  , 这个场景来简单聊聊 websocket 的应用 。
方案概括
简单概括一下 , 用户访问某个网站 此时 浏览器(ClientA) 和 WS Server 之间建立了一个长链接 Server 给这个长链接颁发了一个 id (记为 idA)。
ClientA 向服务端发送 idA 来请求小程序码 , 服务端接收后 , 调用 wxacode.getUnlimited  把小程序码生成出来 , 此小程序码的 page 参数 为 小程序内的websocket登录页面 (例如 pages/index/wsLogin) 场景值参数 scene 为 idA 。生成后返回给回ClientA 。
接下来 , 用户获取小程序码后 , 使用微信扫码 , 就进入了我们小程序 (ClientB) 中的 pages/index/wsLogin 页面 , 同时通过场景值(scene) , 拿到了 idA 。

用户点击确认登录 , 我们小程序这里 , 就会向服务端发送一个触发事件(可以是ws或者http触发) , 这个事件用大白话描述一下就是:
小程序这里告诉服务端 用户微信信息xxx来验证登录 , 同时登录成功之后 , 我要向 idA 那个 socket 发送一个登录成功的事件 , 反之则发送未注册事件 。
浏览器(ClientA) , 检测到这个服务端推送事件后 , 就能够从服务端获取 token , 登录并实时进行页面跳转了 。
是不是本质上非常简单 ?
当然这些作为一个 demo 来说已经够了 要构建一个高可用的远远不止 。
数据交互图
客户端单项通信(扫码登录场景)
【小程序|websocket入门案例: 构建微信扫小程序码登录系统】
客户端双向通信(聊天室IM场景)

(eg. 这只是最简易的场景 , 真实情况要复杂许多)
代码实现
此 demo 为了方便 ,  ws server 为单例 , 所有的 socket 实例保存在内存中 。
共有三个端 , web  mp  server
另一种思路
在上面这个示例中 , 我们给每个从客户端连接的 ws 请求 颁发了一个 id 然后把它藏入小程序码的参数里 , 这样由于发 id 这个机制默认是无序的 , 我们比较难做缓存 , 万一依赖的第三方服务 宕机 , 或者 运行缓慢 , 势必影响我们自身的服务 。 那么有没有办法 , 减小这样的不确定性因素呢?
笔者曾经做过一个方案:
更改指定一个 socket.to namespace 里的发号规则 , 改为 0-999  然后先预制 参数为 0-999 的小程序码共 1000 张 把他们上传同步到 CDN 去 , 并且在数据库中记录下他们的 id CDN url  这样用户访问 web 端登录页面时 , 发现是这个 namespace 的规则 , 就按照顺序 , 给一个没有被占用的 id 。假设为 10 (之前9位还在保持连接) 。