解决uniapp的websocket连接在web和安卓正常,iOS连接不上的问题

  承接上篇(解决sockjs、stomp在uni-app端使用的坑)第3个问题:在安卓app上是可以正常建立链接的,但是在ios app上却不行。虽然不行,但还是需要解决。

  起初查百度,很多人说是nginx配置,或ssl证书问题,但是我试了,iOS还是不生效。那么web连接和安卓连接都没问题,那么说明nginx配置没问题,ssl证书应该也没问题。

  后来到Dcloud问答及微信开放社区里看帖子,发现的确有很多人遇到这个问题,但是都没有给出切实有效的解决方案。

  后来查看插件市场,看到一个插件:plus-websocket,更新记录有:解决 iOS 端无法使用的问题,所以抱着试试的态度试了一下就解决了。

一、解决方案 - plus-websocket

  在 HTML5+ 和 WEB 环境使用小程序风格的 websocket 接口,支持 H5、5+APP、uni-app(不含小程序,小程序环境请直接使用 uni 接口)。

  也可以用于解决 uni-app 环境下不支持 ArrayBuffer 类型数据和不支持多个 websocket 连接的问题以及解决使用 websocket 后导致部分安卓设备白屏的问题。

1、使用方式

(1)NPM

npm i plus-websocket --save

import socket from 'plus-websocket'

(2)直接下载

// 以下路径需根据项目实际情况填写
import socket from '../../js/plus-websocket/index.js'

2、API

  详细用法可参考 uni-app文档,跟uni提供的websocket的使用api一样

  • socket.connectSocket(OBJECT)socket.onSocketOpen(CALLBACK)
    • SocketTask.(CALLBACK)
    • SocketTask.send(OBJECT)
    • SocketTask.close(OBJECT)
    • SocketTask.onOpen(CALLBACK)
    • SocketTask.(CALLBACK)
    • SocketTask.(CALLBACK)
  • socket.onSocketError(CALLBACK)
  • socket.sendSocketMessage(OBJECT)
  • socket.onSocketMessage(CALLBACK)
  • socket.closeSocket(OBJECT)
  • socket.onSocketClose(CALLBACK)

3、注意事项

  当在 uni-app 中使用时也可用当前 API 替换 uni-app 内置的 websocket API

// main.js
import socket from 'plus-websocket'

// #ifdef APP-PLUS
Object.assign(uni, socket)
// #endif

二、遇到问题

  这里遇到一个问题就是:开发版正常,而打包自定义基座之后不正常的问题。怎么解决呢?

1、由于我将自己封装的 uniWebsock.js、引入的 stomp.js 和 plus-websocket.js 都是放在 static 目录下,并且在 uniWebsock.js 里使用到了 import 和 Class类 等 ES6 的写法。

  想到之前看文档时对这方面有描述,但记不清了,那么就回去看文档:uni-app目录结构

1、编译到任意平台时,static 目录下的文件均会被完整打包进去,且不会编译。非 static 目录下的文件(vue、js、css 等)只有被引用到才会被打包编译进去。

2、static 目录下的 js 文件不会被编译,如果里面有 es6 的代码,不经过转换直接运行,在手机设备上会报错。

3、cssless/scss 等资源不要放在 static 目录下,建议这些公用的资源放在自建的 common 目录下。

4、HbuilderX 1.9.0+ 支持在根目录创建 ext.jsonsitemap.json 等小程序需要的文件。

  那么说明我们引入的 js 之类的文件是不能放在 static 目录的,需要自建一个公共目录 js_sdk 去存放。

2、这样改了之后安卓自定义基座可以了,但是 iOS 自定义基座还是不行。就想到之前微信分享、视频播放之类的都增加了模块勾选的,所以想到这个websocket是不是也需要什么模块配置。

  查看 mainfest.json 文件里的APP模块配置,发现有个 iOS UIWebview模块

  点击详情查看是不是这个影响:Appstore审核反馈废弃UIWebview APIs问题的说明

  看了之后好像也没什么影响,后来就去github查看插件的源码,发现其源码是通过创建UIWebview实现的:plus-websocket/src/SocketTask.ts

  所以判断 iOS 是需要添加UIWebview支持的,那么勾选之后需要打包才能生效。勾选之后制作自定义基座就Ok了,使用wss://域名/ws/ 代理 iOS 也可以正常连接了。

  虽然最终是解决了,但是还是没弄清楚为啥,猜测可能是 uniapp 提供的 websocket 内部实现没兼容 iOS 的问题,有了解的大神希望不吝赐教。

原文地址:https://www.cnblogs.com/goloving/p/14744424.html