news 2026/9/20 4:51:21

uni-app 的 uni-websocket UTS 插件:跨端 WebSocket 连接管理从接口到源码全解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
uni-app 的 uni-websocket UTS 插件:跨端 WebSocket 连接管理从接口到源码全解析
  • 示例工程
  • 前端
  • 移动开发
  • 跨平台

【免费下载链接】uni-app

A cross-platform framework using Vue.js

项目地址:https://gitcode.com/gh_mirrors/un/uni-app
点击查看免费下载

导读

uni-websocket是 uni-app / uni-app x 生态中一个以 UTS 插件形态交付的 WebSocket 连接管理模块,通过同一套uni.connectSocketuni.sendSocketMessageuni.closeSocket等 API 屏蔽了 Android(Kotlin)、iOS(Swift)、HarmonyOS(ArkTS)三端底层实现的差异。本文以仓库中的 模块 readme 为骨架,结合 接口声明 与各平台实现源码,完整讲解 UTS 语言与 UTS 插件的基本机制、模块提供的全部 WebSocket API 与参数语义、三端底层实现原理、错误码体系,并给出可直接落地的连接、收发、关闭与监听完整代码示例,帮助读者既会用 API,也看得懂其底层是如何做到"一套代码多端运行"的。


一、模块概览:一个"UTS 插件"形态的 WebSocket 连接管理模块

按仓库内 readme 的定义,uni-websocket模块的职责一句话概括为:实现 WebSocket 连接管理功能。它不是一个普通的 JS 组件,而是一个典型的UTS 插件——即使用 UTS 语言编写的 uni_modules 插件,其核心目的是允许 uni-app / uni-app x 开发者使用 UTS 语法来调用扩展 API(封装原生系统的 API 或三方 SDK)。

从 package.json 可以确认该插件的元信息:

  • id/displayNameuni-websocket,版本1.0.0
  • engines.HBuilderX:要求^3.6.8及以上版本;
  • dcloudext.type"uts",即这是一个 UTS 类型插件;
  • dcloudext.sale:regular 与 sourcecode 价格均为0.00,即免费开源插件;
  • uni_modules.platforms:在客户端侧覆盖 Vue(vue2/vue3)、App(app-android / app-ios)、H5 与各大小程序平台,属于全平台型插件。

值得关注的是uni_modules["uni-ext-api"]一节,它向 uni-app 框架声明了本插件注入到uni.命名空间下的 7 个扩展 API,并且对 App 三端(kotlin / swift / arkts)均标记为true

| 声明 API | App-Android (kotlin) | App-iOS (swift) | App-Harmony (arkts) | | -- | -- | -- | -- | |connectSocket| true | true | true | |sendSocketMessage| true | true | true | |closeSocket| true | true | true | |onSocketOpen| true | true | true | |onSocketMessage| true | true | true | |onSocketClose| true | true | true | |onSocketError| true | true | true |

也就是说,插件一旦被工程引入,开发者即可在 App 三端直接调用这些uni.xxx全局 API,无需关心底层是 OkHttp 还是 Starscream。


二、地基:UTS 语言是什么、为什么能跨端

要理解uni-websocket为什么能做到"一份源码跑三端原生",必须先理解其编写语言 UTS。readme 中给出了权威说明,这里结合仓库实践展开:

UTS(uni type script)是一门跨平台的、高性能的、强类型的现代编程语言。它可以被编译为不同平台的编程语言:

| 目标平台 | 编译产物语言 | | -- | -- | | Android | Kotlin | | iOS | Swift | | HarmonyOS(鸿蒙) | ArkTS | | Web / 小程序 | JavaScript |

UTS 采用了与 TypeScript 基本一致的语法规范,并支持绝大部分 ES6 API;但为了跨端,UTS 做了一些约束和特定平台的增补。过去在 JS 引擎下运行支持的语法,大部分在 UTS 的处理下也可以平滑地在 Kotlin 和 Swift 中使用;但有些能力无法抹平,此时需要使用条件编译

与 uni-app 的条件编译类似,UTS 也支持条件编译——写在条件编译块里的代码,可以调用平台特有的扩展语法。在uni-websocket源码中就可以看到这种写法的实际应用,例如 unierror.uts 中:

export class ConnectSocketFailImpl extends UniError implements ConnectSocketFail { // #ifdef APP-ANDROID override errCode: ConnectSocketErrorCode // #endif constructor(errCode : ConnectSocketErrorCode) { super(); this.errSubject = UniWebsocketErrorSubject; this.errCode = errCode; this.errMsg = ConnectUniErrors[errCode] ?? "" } }

// #ifdef APP-ANDROID// #endif之间的override声明只会在 Android 平台参与编译,iOS / HarmonyOS 编译时会被剔除,这正是 UTS 条件编译抹平平台差异的直观例证。

仓库内还提供了 uts 与 ts 的差异文档、UTS 语言官方文档 等资料,需要系统学习 UTS 的读者可继续查阅。


三、UTS 插件机制:utssdk 目录如何按平台组织代码

readme 明确指出:UTS 插件的实现代码主要位于utssdk目录下,并按平台进行分离和组织。原文档中的目录说明表是理解该插件目录结构的钥匙,完整继承如下:

| 目录/文件 | 目标平台 | 实现语言 | 作用描述 | | -- | -- | -- | -- | |utssdk/app-android| Android | UTS, Kotlin, Java | 存放 UTS 插件在 Android 平台上的具体实现源码 | |utssdk/app-ios| iOS | UTS, Swift | 存放 UTS 插件在 iOS 平台上的具体实现源码 | |utssdk/app-harmony| HarmonyOS (鸿蒙) | UTS, ArkTS | 存放 UTS 插件在 HarmonyOS 平台上的具体实现源码 | |utssdk/*.uts| 多平台共用 | UTS | 存放使用 UTS 语言编写的、可供所有平台共用的实现源码 |

对照仓库中uni-websocket插件的实际文件树,这张表完全成立:

src/uni_modules/uni-websocket/ ├── package.json # 插件元信息与 uni-ext-api 声明 ├── readme.md # 模块说明文档 ├── changelog.md # 更新日志 └── utssdk/ ├── interface.uts # 公共:全部 API 与类型的声明 ├── interface.type.uts # 公共:SocketDataOptions(string | ArrayBuffer) ├── protocol.uts # 公共:参数协议校验 ├── unierror.uts # 公共:UniError 错误对象与错误码映射 ├── app-android/ │ ├── index.uts # Android 平台导出实现 │ ├── config.json # Android 原生依赖配置 │ └── websocket/ │ ├── WebSocketManager.uts │ └── WebsockerClient.uts ├── app-ios/ │ ├── index.uts # iOS 平台导出实现 │ ├── config.json │ └── frameworks/ # Starscream.xcframework、websocket.xcframework │ └── websocket/ # iOS 侧 WebSocketManager.uts / WebsockerClient.uts └── app-harmony/ └── index.uts # HarmonyOS 平台导出实现

这里可以总结出 UTS 插件的三条约定,读者开发自己的 UTS 插件时可复用:

  1. 公共逻辑下沉到utssdk/*.uts:类型声明、协议校验、错误定义等跨平台共享内容放在 utssdk 根目录,三端共用;
  2. 平台实现按目录隔离app-androidapp-iosapp-harmony三个子目录分别放置各自平台的实现,互不干扰;
  3. 每平台入口是index.uts:平台目录下的index.uts负责对外导出该平台的 API 实现,uni-app 编译器按目标平台自动选择对应目录。

3.1 平台原生依赖的声明方式

原生依赖放在各平台目录下的config.json中,例如 app-android/config.json:

{ "dependencies": [ "com.squareup.okhttp3:okhttp:3.12.12" ], "minSdkVersion": "19" }

这说明 Android 平台实现基于 OkHttp 3.12.12,并声明了最低支持的minSdkVersion为 19(Android 4.4+)。而 iOS 平台则通过frameworks/目录内置了Starscream(一款纯 Swift 实现的 WebSocket 客户端库)的 xcframework,分别提供真机(ios-arm64)与模拟器(ios-arm64_x86_64-simulator)两个分片——这是 UTS 插件"混编原生语言/三方 SDK"的标准做法,相关规范可参考仓库内的 uts 插件原生语言混编开发文档。


四、WebSocket API 全貌:7 个全局 API + SocketTask 对象

uni-websocket的全部接口形态定义在公共文件 interface.uts 中。它声明了两类能力:

  • 全局 APIuni.前缀调用,共 7 个);
  • SocketTask 对象uni.connectSocket的返回值,提供 6 个方法)。

4.1 全局 API 一览

| API | 签名 | 说明 | | -- | -- | -- | |uni.connectSocket(options)|(options: ConnectSocketOptions) => SocketTask| 创建 WebSocket 连接,返回 SocketTask | |uni.onSocketOpen(callback)|(result: OnSocketOpenCallbackResult) => void| 监听连接打开事件(已废弃,用 SocketTask 的 onOpen 替换) | |uni.onSocketMessage(callback)|(result: OnSocketMessageCallbackResult) => void| 监听收到服务器消息(已废弃,用 onMessage 替换) | |uni.sendSocketMessage(options)|(options: SendSocketMessageOptions) => void| 通过连接发送数据(已废弃,用 SocketTask 的 send 替换) | |uni.onSocketError(callback)|(result: OnSocketErrorCallbackResult) => void| 监听连接错误(已废弃,用 onError 替换) | |uni.closeSocket(options)|(options: CloseSocketOptions) => void| 关闭连接(已废弃,用 SocketTask 的 close 替换) | |uni.onSocketClose(callback)|(result: OnSocketCloseCallbackResult) => void| 监听连接关闭(已废弃,用 onClose 替换) |

接口注释中明确标注:除connectSocket外的 6 个全局 API 均已废弃(@deprecated),官方推荐的新用法是"先uni.connectSocket拿到SocketTask,再通过 task 的onOpen / onMessage / send / close / onError / onClose管理本次连接"。旧式全局 API 仍可用,但会作用于最近一次创建的连接(见下文源码分析)。

4.2ConnectSocketOptions参数详解

connectSocket的入参类型定义在 interface.uts,各字段语义如下:

| 参数 | 类型 | 必填 | 默认值 | 说明 | | -- | -- | -- | -- | -- | |url|string| 是 | - | 开发者服务器接口地址 | |header|UTSJSONObject \| null| 否 |null| HTTP 请求 Header,header 中不能设置 Referer| |protocols|string[] \| null| 否 |null| 子协议数组(WebSocket Subprotocol) | |success|(result: ConnectSocketSuccess) => void \| null| 否 |null| 调用成功的回调 | |fail|(result: ConnectSocketFail) => void \| null| 否 |null| 调用失败的回调 | |complete|(result: any) => void \| null| 否 |null| 调用结束(成功、失败都会执行)的回调 |

对应的参数协议校验在 protocol.uts 中实现:

export const ConnectSocketApiProtocol = new Map<string, ProtocolOptions>([ [ 'url', { type: 'string', required: true } ], [ 'header', { type: 'object', required: false } ], [ 'protocols',{ type: 'string[]',required: false } ], ]); export const ConnectSocketApiOptions: ApiOptions<ConnectSocketOptions> = { formatArgs: new Map<string, Function>([ [ 'url', function (url: string, params: ConnectSocketOptions) { if (url == null) { throw new Error('url is required') } } ] ]), }

即:url为必填字符串,缺失时直接抛出'url is required'header必须是对象;protocols必须是字符串数组。

4.3SendSocketMessageOptions参数详解

export type SendSocketMessageOptions = { data: any, // 需要发送的内容,app 平台从 4.61 版本开始支持 ArrayBuffer success?: ((result: GeneralCallbackResult) => void) | null, fail?: ((result: SendSocketMessageFail) => void) | null, complete?: ((result: any) => void) | null };

data的类型在 interface.type.uts 中定义为SocketDataOptions

export type SocketDataOptions = String | ArrayBuffer;

即支持发送字符串ArrayBuffer(二进制)两种数据;其中 app 平台从 4.61 版本开始支持ArrayBuffer(该版本信息同时标注于 interface.uts 的注释中)。

4.4CloseSocketOptions参数详解

export type CloseSocketOptions = { code?: number | null, // 关闭连接的状态号,默认 1000(表示正常连接关闭) reason?: string | null, // 可读的关闭原因,必须是不长于 123 字节的 UTF-8 文本(不是字符) success?: ..., fail?: ..., complete?: ... };

需要注意两个约束:

  • code未指定时默认取值1000(正常关闭);
  • reason最多 123 字节的 UTF-8 文本,且以字节数而非字符数计量,中文等多字节字符要特别留意。

4.5 SocketTask 对象

connectSocket返回的SocketTask(定义于 interface.uts)是对单条连接的操作句柄,提供:

| 方法 | 说明 | | -- | -- | |send(options: SendSocketMessageOptions)| 通过该连接发送数据 | |close(options: CloseSocketOptions)| 关闭该连接 | |onOpen(callback)| 监听该连接打开事件,回调参数含header(连接成功的 HTTP 响应 Header) | |onClose(callback)| 监听该连接关闭,回调参数含code(关闭状态号)与reason(关闭原因) | |onError(callback)| 监听该连接错误,回调参数含errMsg| |onMessage(callback)| 监听该连接收到服务器消息,回调参数含data(app 4.61 起可为 ArrayBuffer) |

监听回调的类型细节(如OnSocketOpenCallbackResult.headerOnSocketCloseCallbackResult.code/reasonOnSocketMessageCallbackResult.data)均可在上述文件对应位置找到完整注释,这里不再赘述。


五、三端源码实现:单例管理 + 平台客户端

5.1 Android:WebSocketManager 单例 + OkHttp 客户端

Android 平台的入口 app-android/index.uts 非常薄,7 个 API 全部委托给WebSocketManager单例:

export const connectSocket : ConnectSocket = (options : ConnectSocketOptions) : SocketTask => { return WebSocketManager.getInstance().connectSocket(options); } export const sendSocketMessage : SendSocketMessage = (options : SendSocketMessageOptions) : void => { return WebSocketManager.getInstance().sendSocketMessage(options); } // ... onSocketOpen / onSocketMessage / onSocketClose / onSocketError 同理

WebSocketManager.uts 内部是一个经典的单例管理器,核心数据结构有两组:

  • socketTasks: SocketTask[]:保存所有连接任务。源码注释明确说明:"当 uni. 开头调用的时候,只作用于 0 元素;这个 task 数组,当 error 或者 close 的时候,会删除"——这就是"旧式全局 API 作用于最近一次连接"的源码级依据(L112-L113);
  • taskMap: Map<WebsockerClient, SocketTask>:维护底层客户端对象与任务对象的绑定关系,用于回调事件反查对应 task。

connectSocket的调用链为(L137-L151):

  1. 创建WebsockerClient(封装 OkHttp 的 WebSocket);
  2. 包装为SimpleSocketTask并注册进socketTaskstaskMap
  3. 立即回调successerrMsg: "connectSocket:ok")与complete
  4. 调用webscoketClient.connect()发起真实连接;
  5. 返回 task 给调用方。

SimpleSocketTask(L4-L97) 实现了SocketTask接口,内部维护 open / close / error / message 四类回调数组,并提供dispatchXxx方法供底层客户端事件统一派发;send/close在底层客户端为空时(连接已失效)会构造错误结果并依次回调failcomplete

事件回调(onOpen/onMessage/onClose/onError)的统一处理逻辑为(以onClose为例,L239-L261):

  1. 通过taskMap反查 task;
  2. 若该 task 是socketTasks[0]且全局回调已注册,则同时触发全局onSocketClose
  3. 将 task 从socketTasks中移除,并从taskMap中删除绑定;
  4. 向 task 自身的onClose回调派发{ code, reason }

从源码结构可以推断:该设计既兼容了旧的全局uni.onSocketXxx监听方式,也保证了基于 SocketTask 的多连接场景下各连接事件互不串扰。

5.2 iOS:基于 Starscream 的同一套 Manager 结构

iOS 平台目录utssdk/app-ios下同样存在WebSocketManager.uts/WebsockerClient.uts以及入口index.uts,并内置了Starscream.xcframework与封装好的websocket.xcframework(分别提供真机与模拟器架构的二进制分片)。可以推断 iOS 实现沿用了与 Android 相同的 Manager + Client 架构,仅将底层网络库替换为 Starscream。UTS 在此平台会被编译为 Swift,Starscream 正是以 Swift 编写的主流 WebSocket 客户端库,这也与 readme 中"iOS 平台编译为 Swift"的描述一致。

5.3 HarmonyOS:独立入口 index.uts

utssdk/app-harmony目录下有独立的index.uts入口,UTS 在此平台编译为 ArkTS,说明鸿蒙侧拥有独立的 WebSocket 实现路径,无需依赖 Android / iOS 的网络栈。鸿蒙平台 UTS 插件开发注意事项可参考仓库内的 uts 插件 HarmonyOS 平台开发注意事项。


六、错误码体系:Connect 与 Send 的 4 个错误码

公共文件 unierror.uts 集中定义了错误主题与错误码映射:

连接类错误(ConnectSocketErrorCode):

| 错误码 | 说明 | 错误消息(errMsg) | | -- | -- | -- | |600009| URL 格式不合法 |invalid URL|

发送类错误(SendSocketMessageErrorCode):

| 错误码 | 说明 | 错误消息(errMsg) | | -- | -- | -- | |10001| 发送数据超限,发送队列不能超过 16M 大小 |The queue memory exceeds 16 MiB and the connection will be closed| |10002| websocket 未连接 |webSocket is not connected| |602001| websocket 系统错误 |websocket system error|

对应的失败对象ConnectSocketFailImpl/SendSocketMessageFailImpl均继承自UniError,构造函数中会设置errSubject = 'uni-websocket'errCodeerrMsg(L39-L61)。其中errMsg的英文文案The queue memory exceeds 16 MiB...提示了一个重要的工程事实:单连接发送队列上限为 16 MiB,超限会直接关闭连接,因此高频推送场景务必控制发送速率与单条消息体积。

另外,在 WebSocketManager.uts 中,closeSocket在未建立连接时返回的错误消息为closeSocket:fail WebSocket is not connected(L173-L175),send在未连接时则构造errCode = 10002的失败对象(L50),两者可在业务侧作为"是否已连接"的兜底判断。


七、实战:完整可运行的 WebSocket 使用示例

7.1 推荐用法:基于 SocketTask

这是官方推荐的新式用法(接口注释中的 @example 即为此形态,见 interface.uts):

// 1. 创建连接 const task = uni.connectSocket({ url: "ws://192.168.12.106:8080/ws", complete: (e) => { console.log("socket :", e); } }); // 2. 监听连接打开 task.onOpen((res) => { console.log('WebSocket连接已打开!', res.header); }); // 3. 监听服务器消息(app 4.61 起 res.data 可为 string 或 ArrayBuffer) task.onMessage((res) => { console.log('收到服务器内容:' + res.data); }); // 4. 监听错误与关闭 task.onError((res) => { console.log('WebSocket错误:', res.errMsg); }); task.onClose((res) => { console.log('WebSocket 已关闭!code=' + res.code + ' reason=' + res.reason); }); // 5. 发送数据(需在连接打开之后) task.send({ data: "halo" }); // 发送二进制数据(app 4.61+) task.send({ data: arrayBuffer }); // 6. 关闭连接(code 默认 1000 正常关闭) task.close({ code: 1000, reason: "bye" });

7.2 兼容用法:全局 API(已废弃)

接口注释中保留了旧式全局 API 的完整示例形态(interface.uts):

uni.onSocketOpen(function (res) { console.log('WebSocket连接已打开!'); }); uni.onSocketError(function (res) { console.log('WebSocket连接打开失败,请检查!'); }); uni.sendSocketMessage({ data: msg }); uni.onSocketMessage(function (res) { console.log('收到服务器内容:' + res.data); }); uni.closeSocket(); uni.onSocketClose(function (res) { console.log('WebSocket 已关闭!'); });

注意:全局 API 只作用于最近一次创建的连接(源码见 WebSocketManager.uts 中始终取socketTasks[0]的逻辑),因此多连接场景请务必使用 SocketTask 形态,避免事件串线。

7.3 工程接入与版本前提

  • uni-websocket作为 uni_modules 插件引入工程后,uni.connectSocket等 API 即可在 App 三端使用;H5 / 小程序端则由 uni-app 框架自身能力提供,无需本插件(package.json 中uni-ext-api仅声明 app 平台 kotlin / swift / arkts 为 true)。
  • 版本前提:HBuilderX^3.6.8;App 端ArrayBuffer收发需 uni-app x 4.61 及以上;鸿蒙侧 uniVer 4.23 / unixVer 4.61 起可用(版本标注见 interface.uts 中各 API 的 @uniPlatform 注释)。
  • Android 端最低支持 Android 4.4(minSdkVersion 19)。

八、使用注意事项与最佳实践

综合接口注释与源码,总结以下工程要点:

  1. 优先使用 SocketTask 而非全局 API:6 个uni.onSocketXxx/uni.sendSocketMessage/uni.closeSocket均已标记废弃,且只作用于最近连接;SocketTask 形态支持多连接隔离。
  2. 发送时机:发送数据必须在连接打开(onOpen回调触发)之后进行;未连接时send会以errCode 10002(webSocket is not connected)回调fail
  3. 发送队列上限 16 MiB:超过 16 MiB 会触发10001错误并关闭连接,需控制消息大小与频率。
  4. header 限制header中不能设置Referer
  5. 关闭参数约束code默认 1000;reason为不超过123 字节的 UTF-8 文本。
  6. URL 校验url必填,格式不合法时返回错误码600009(invalid URL)。
  7. 连接生命周期:连接 error 或 close 后,任务会从管理器的socketTasks数组中移除(见 WebSocketManager.uts),如需重连需重新调用connectSocket;可结合onClose/onError实现指数退避的重连策略。
  8. 二进制支持:收发ArrayBuffer(二进制帧)需要 app 4.61+,做即时通讯的图片 / 音频上行场景可直接使用。

九、延伸阅读

  • 模块本体:uni-websocket readme、package.json
  • 接口与类型:interface.uts、interface.type.uts
  • 参数协议与错误:protocol.uts、unierror.uts
  • Android 实现:app-android/index.uts、WebSocketManager.uts
  • 官方 API 文档:WebSocket 全局 API 文档、WebSocket API 文档
  • UTS 相关:UTS 语言介绍、uts 和 ts 的差异、uts 插件开发文档、uts 插件原生语言混编开发文档、uts 插件 Android 平台开发注意事项、uts 插件 iOS 平台开发注意事项、uts 插件 HarmonyOS 平台开发注意事项
  • 示例工程
  • 前端
  • 移动开发
  • 跨平台

【免费下载链接】uni-app

A cross-platform framework using Vue.js

项目地址:https://gitcode.com/gh_mirrors/un/uni-app
点击查看免费下载
上一篇:PyCryptoBot风险管理完全指南:止损、追踪止损与资金保护策略
下一篇:告别混乱标签:Kaniko构建镜像的环境与版本标识最佳实践

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/20 4:51:15

用文本编辑器剪视频要多久?AutoCut 自动字幕生成与智能剪辑上手

用文本编辑器剪视频要多久&#xff1f;AutoCut 自动字幕生成与智能剪辑上手 【免费下载链接】autocut 用文本编辑器剪视频 项目地址: https://gitcode.com/GitHub_Trending/au/autocut AutoCut 先给你的视频自动生成字幕&#xff0c;你只需在文本文件里勾选想保留的句子…

作者头像 李华
网站建设 2026/9/20 4:46:05

AI文献匹配技术如何提升论文写作效率

1. 论文写作新工具&#xff1a;AI文献匹配技术的突破最近在学术圈里&#xff0c;一批新型AI写作辅助工具正在悄然改变研究人员的日常工作方式。这些工具最引人注目的功能&#xff0c;是能够自动生成符合学术规范的论文内容&#xff0c;并精准匹配真实可查的参考文献。作为一名长…

作者头像 李华
网站建设 2026/9/20 4:42:10

WPF MVVM视图切换最佳实践与性能优化

1. WPF MVVM视图切换的核心挑战在WPF企业级应用开发中&#xff0c;视图切换是最基础却最容易踩坑的功能点。传统事件驱动模式下&#xff0c;我们习惯在按钮点击事件里直接操作Frame或ContentControl的内容&#xff0c;但这种做法在MVVM架构中会破坏分层原则。我曾接手过一个遗留…

作者头像 李华
网站建设 2026/9/20 4:39:44

LibreChat自托管部署指南:多模型对话聚合与隐私管理

1. 为什么我最终把主力对话工具换成了LibreChat第一次听说LibreChat是在一个技术群里&#xff0c;有人丢了个截图&#xff0c;界面长得跟主流对话产品几乎一模一样&#xff0c;但左上角多了个模型切换下拉框&#xff0c;底下还挂着一排插件图标。当时我的第一反应是"又一个…

作者头像 李华