{"id":18928051,"url":"https://github.com/lmxdawn/him-vue","last_synced_at":"2025-05-07T10:43:24.166Z","repository":{"id":35838525,"uuid":"164049084","full_name":"lmxdawn/him-vue","owner":"lmxdawn","description":"开源的H5即时聊天系统 spring-boot + netty + protobuf + vue ~","archived":false,"fork":false,"pushed_at":"2022-12-31T15:30:13.000Z","size":4862,"stargazers_count":193,"open_issues_count":14,"forks_count":59,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-03-31T09:11:14.280Z","etag":null,"topics":["im","netty","protobuf","spring-boot","vue","vue-im","websocket"],"latest_commit_sha":null,"homepage":"http://him-netty.await.fun/h5","language":"Vue","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/lmxdawn.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-01-04T02:46:30.000Z","updated_at":"2025-03-27T07:42:48.000Z","dependencies_parsed_at":"2023-01-16T07:23:38.712Z","dependency_job_id":null,"html_url":"https://github.com/lmxdawn/him-vue","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lmxdawn%2Fhim-vue","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lmxdawn%2Fhim-vue/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lmxdawn%2Fhim-vue/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lmxdawn%2Fhim-vue/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lmxdawn","download_url":"https://codeload.github.com/lmxdawn/him-vue/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252862302,"owners_count":21815834,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["im","netty","protobuf","spring-boot","vue","vue-im","websocket"],"created_at":"2024-11-08T11:22:32.822Z","updated_at":"2025-05-07T10:43:24.140Z","avatar_url":"https://github.com/lmxdawn.png","language":"Vue","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n\u003cdiv align=\"center\"\u003e\n    \u003cp align=\"center\"\u003e\n\n\n   [![him-vue](https://github.com/lmxdawn/him-vue/raw/master/pic/him.jpg)](http://him-netty.await.fun/h5)\n\n\n   \u003c/p\u003e\n   \u003cp align=\"center\"\u003e\n\n   [![him-vue](https://img.shields.io/badge/him-him--vue-1.svg)](https://github.com/lmxdawn/him-vue)\n   [![him-netty](https://img.shields.io/badge/him-him--netty-1.svg)](https://github.com/lmxdawn/him-netty)\n   [![QQ群](https://img.shields.io/badge/QQ%E7%BE%A4-210277856-orange.svg)](https://shang.qq.com/wpa/qunwpa?idkey=d4965fc7101936dcdea5eb1d05e2eaeb3128f20796028ee937ab516652083c6c)\n   [![](https://badge.juejin.im/entry/5cd6be3ae51d456e5b66ae3d/likes.svg?style=flat-square)](https://juejin.im/post/5cd6be3ae51d456e5b66ae3d)\n\n   \u003c/p\u003e\n\n   \u003cp align=\"center\"\u003e\n\n   [![vue](https://img.shields.io/badge/vue-2.x-1.svg)](https://github.com/vuejs/vue)\n   [![netty](https://img.shields.io/badge/netty-4.1.25.Final-1.svg)](https://github.com/netty/netty)\n   [![spring-boot](https://img.shields.io/badge/spring--boot-2.1.2.RELEASE-1.svg)](https://github.com/spring-projects/spring-boot)\n\n   \u003c/p\u003e\n\u003c/div\u003e\n\n# him-vue\n\n\u003e 使用前先阅读开源协议: [中文版](https://github.com/lmxdawn/him-vue/LICENSE_CN) , [English version](https://github.com/lmxdawn/him-vue/LICENSE) , 协议出处 [Anti-996-License-1.0](https://github.com/kattgu7/Anti-996-License)\n\n\u003e 前端：vue  [前往](https://github.com/lmxdawn/him-vue) ，服务端 netty [前往](https://github.com/lmxdawn/him-netty)\n\n# 踩坑指南\n\n\u003e * 1. iOS版本手机QQ中清空不了 Cookie 的bug (Android 版本的QQ没试), 其它浏览器均正常\n\n\u003e * 2. 手机微信中打开后点击输入文字后, 不管点不点击发送按钮都会出现短暂的不能点击的现象(任何按钮都不能点击), 后来发现是因为在微信里面, 输入法把 输入框顶上去了, 然后输入法隐藏后输入框还在上面!!!! [点击查看详情](https://developers.weixin.qq.com/community/develop/doc/00040a43cd4290dedbc7e7f1851400)\n  。找到一个解决输入框的方法:  @blur=\"chatTextBlur\" 监听失去焦点的事件(vue 写法), 然后在事件里面执行 `window.scroll(0, 0);`\n\n\u003e * 3. 因为设置了定位，`overflow: scroll` 原生滚动，iOS下会不流畅，解决办法：换成 `-webkit-overflow-scrolling: touch;`\n\n# 功能列表\n* [x] 单聊\n* [x] 群聊\n* [x] protobuf 编解码\n* [x] 客户端心跳\n* [x] 客户端断开重连\n* [x] 异地登录, 通知下线\n* [x] 移动端/PC端适配\n* [x] 离线消息 (消息通过 ack 机制, 实现可达性)\n* [x] 第三方QQ登录\n* [x] 自带 emoji 表情\n* [x] 文本消息\n* [ ] 声音提示\n* [ ] 图片消息\n* [ ] 音频消息\n* [ ] 视屏消息\n* [ ] 分布式部署\n* [ ] PHP 版本的 (Workerman 版本)\n\n# 环境要求 \n\n## git\n\u003e 这个版本管理肯定需要安装的\n\n## node \n\u003e node 版本最新的即可\n\n## vue\n\n\u003e 构建工具用 vue 目前使用的 2.x 版本\n\n## 下载\n\n\u003e git clone https://github.com/lmxdawn/him-vue.git\n\u003e cd him-vue\n\n## 安装\n\n\u003e npm install\n\n## 编译\n\u003e npm run serve 本地测试版\n\n\u003e him-vue [前往](https://github.com/lmxdawn/him-vue) 和 him-netty [前往](https://github.com/lmxdawn/him-netty) 都启动后访问 http://localhost:8080\n\n\u003e npm run build 编译命令\n\n注意默认使用 QQ登录, 这个需要去申请QQ互联, 如果不想去申请, 则可以直接设置 Cookie, 两个值 UID 和 SID, 这两个值可以通过接口 /api/user/login/byPwd 获取, 具体请看java 代码\n\n# 加好友演示\n\n[![him-vue](https://github.com/lmxdawn/him-vue/raw/master/pic/user-show-how.gif)](http://him-netty.await.fun/h5)\n\n# 加群演示\n\n[![him-vue](https://github.com/lmxdawn/him-vue/raw/master/pic/group-show-how.gif)](http://him-netty.await.fun/h5)\n\n\n# QQ 互联相关配置\n\n### java 代码\n\u003e him-api/src/main/resources/ 这里的配置文件里面, `qq.auth.appid` 和 `qq.auth.appkey` 配置上即可\n\n### vue 代码\n\u003e 详细配置 根目录下的\n`.env.development`\n`.env.production`\n`.env.stage` 这三个文件是配置, 分别代表 本地测试,生产环境,线上测试环境\n\n|名称|描述|\n| --- | --- |\n| VUE_APP_API_BASE | API接口地址 |\n| VUE_APP_WEBSOCKET_URL | websocket地址 |\n| VUE_APP_USER_QR_CODE_URL | 生成用户的二维码地址(用来加好友的) |\n| VUE_APP_GROUP_QR_CODE_URL | 生成群二维码的地址(用来加群的) |\n| VUE_APP_ROUTER_BASE | 如果用了 NGINX 做代理, 并且有二级路径, 则需要配置此项 |\n\n# 跨域问题\n\n\u003e NGINX 做了端口的代理后, header 头 设置了跨域, 但是还是获取不了, 不知道为啥, 欢迎大神来指导\n\n\u003e 最后我的解决办法, 全部用一个域名, 然后 NGINX 做路径的转换,下面贴一下我的配置\n\n```\n# 前端路径, 注意这里配置了二级目录后, 需要 vue 的路由里面也需要配置\n# 我是写在配置文件里面的 VUE_APP_ROUTER_BASE 这个配置项来控制的\nlocation /h5 {\n   try_files $uri $uri/ /h5/index.html;\n}\n# API 路径\nlocation /api\n{\n  proxy_pass http://127.0.0.1:9000/api;\n  proxy_http_version 1.1;\n  proxy_set_header Upgrade $http_upgrade;\n  proxy_set_header Connection \"Upgrade\";\n  proxy_set_header X-Real-IP $remote_addr;\n}\n# ws 路径\nlocation /ws\n{\n  proxy_pass http://127.0.0.1:9001;\n  proxy_http_version 1.1;\n  proxy_set_header Upgrade $http_upgrade;\n  proxy_set_header Connection \"Upgrade\";\n  proxy_set_header X-Real-IP $remote_addr;\n}\n```\n\n# Him 组件说明\n|   参数  | 说明    |  类型  |  可选值   | 默认值   |\n| --- | --- |--- | --- |--- |\n|  isShow   |   是否显示界面  | boolean |  —   |  true  | \n|  width |   宽度| string |  —   |  100%  | \n|  height|   高度  | string |  —   |  100%  | \n|  top |   定位的顶部位置 | string |  —   |   —| \n|  left|   定位的左边位置 | string |  —   |   — | \n|  bottom|   定位的底部位置 | string |  —   |   — | \n|  right|   定位的右边位置 | string |  —   |   — | \n|  apiBaseUrl|   api 接口的地址| string |  —   |  —   | \n|  webSocketUrl|   websocket 的连接地址 | string |  —   |  —   | \n|  userQRCodeUrl |   用户二维码的生成地址 | string |  —   |  —   | \n|  groupQRCodeUrl|   群二维码的生成地址 | string |  —   |  —   |\n|  isAutoInit |   是否自动初始化（如果为 false 需要执行） | boolean |  —   |  true  | \n|  webSocketReconnectMaxCount |   尝试重新连接的最大次数 |number|  —   |  5 | \n\n# 图床说明\n\n\u003e 把图片放入 git 版本控制里, 上传到 GitHub 上, 然后 在 GitHub 里打开这个图片 把里面的 blob 改为 raw\n\n\u003e 例如: https://github.com/lmxdawn/him-vue/blob/master/pic/WechatIMG10.jpeg 改为 https://github.com/lmxdawn/him-vue/raw/master/pic/WechatIMG10.jpeg\n\n\u003e 我这里直接用的 七牛云的, 因为怕 GitHub 的访问太慢\n\n# protobuf 杂谈\n \n\u003e 说明： 目前所有文件都生成好了，不需要在生成，下面简单说明下\n\n## vue 中使用\n\n\u003e 目前我是安装好了 protobufjs 了，proto 文件放在 /src/proto 目录。\n\u003e 运行命令 pbjs -t json-module -w commonjs -o src/proto/proto.js  src/proto/*.proto 即可\n\u003e 由于我添加到了 package.json 中，直接运行 npm run protojs 也可以\n\n## 页面中引入\n\n\u003e 上面的执行完成后，会在 src/proto 目录下生成 proto.js 文件，**由于 webpack 新版本的原因直接引入该文件会报错**\n\u003e [](https://github.com/protobufjs/protobuf.js/issues/1216)[Cannot assign to read only property'exports'of object' ](https://github.com/protobufjs/protobuf.js/issues/1216 \"Cannot assign to read only property'exports'of object' \")\n\u003e **需要修改最后一行代码为**：`export default $root;`\n\n```\nimport protoRoot from \"@/proto/proto\"\nconst WSBaseReqProto = protoRoot.lookup(\"protocol.WSBaseReqProto\");\nconst WSBaseResProto = protoRoot.lookup(\"protocol.WSBaseResProto\");\n// 编码\nfunction (payload) {\n    // 加入登录验证\n    payload.uid = parseInt(this.getUid());\n    payload.sid = this.getSid();\n    console.log(\"发送的信息：\");\n    let errMsg = WSBaseReqProto.verify(payload);\n    console.log(\"buff 解析错误信息：\", errMsg);\n    // Create a new message\n    const wsData = WSBaseReqProto.create(payload); // or use .fromObject if conversion is necessary\n    // Encode a message to an Uint8Array (browser) or Buffer (node)\n    return WSBaseReqProto.encode(wsData).finish();\n}\n// 解码\nfunction (data, cb) {\n    let reader = new FileReader();\n    reader.readAsArrayBuffer(data);\n    reader.onload = () =\u003e {\n        const buf = new Uint8Array(reader.result);\n        const response = WSBaseResProto.decode(buf);\n        // 成功回调\n        cb(response);\n    };\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flmxdawn%2Fhim-vue","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flmxdawn%2Fhim-vue","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flmxdawn%2Fhim-vue/lists"}