承接上篇(解決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、
css、less/scss等資源不要放在static目錄下,建議這些公用的資源放在自建的common目錄下。4、HbuilderX 1.9.0+ 支持在根目錄創建
ext.json、sitemap.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 的問題,有了解的大神希望不吝賜教。
