开源的H5即时聊天系统 spring-boot + netty + protobuf + vue ~

前言

一篇文章引发的思考?

一次读公号推文, 发现一篇文章写得特好, 勾起了好奇心

《群聊比单聊,为什么复杂这么多?》, @沈大大.

GitHub 地址

him-vue 前往 him-netty 前往

心路历程

  • 第一阶段, 刚看完文章时, 特别兴奋, 开始着手, 花了一个月把聊天界面基本弄, 然后着手于后端, 经过些简单的调研, 决定用 netty 搭建一个, 后面发现里面的复杂逻辑, 再加上心中的火似乎已经熄灭, 最后...
  • 第二阶段, 最近刷公文时又刷到这篇类似的文章, 于是决定不能退缩, 所以有了接下来的事

踩坑指南

    1. iOS版本手机QQ中清空不了 Cookie 的bug (Android 版本的QQ没试), 其它浏览器均正常
    1. 手机微信中打开后点击输入文字后, 不管点不点击发送按钮都会出现短暂的不能点击的现象(任何按钮都不能点击), 后来发现是因为在微信里面, 输入法把 输入框顶上去了, 然后输入法隐藏后输入框还在上面!!!! 点击查看详情
      。找到一个解决输入框的方法: @blur="chatTextBlur" 监听失去焦点的事件(vue 写法), 然后在事件里面执行 window.scroll(0, 0);
    1. 因为设置了定位,overflow: scroll 原生滚动,iOS下会不流畅,解决办法:换成 -webkit-overflow-scrolling: touch;

功能列表

  • [x] 单聊
  • [x] 群聊
  • [x] protobuf 编解码
  • [x] 客户端心跳
  • [x] 客户端断开重连
  • [x] 异地登录, 通知下线
  • [x] 移动端/PC端适配
  • [x] 离线消息 (消息通过 ack 机制, 实现可达性)
  • [x] 第三方QQ登录
  • [x] 自带 emoji 表情
  • [x] 文本消息
  • [ ] 声音提示
  • [ ] 图片消息
  • [ ] 音频消息
  • [ ] 视屏消息
  • [ ] 分布式部署
  • [ ] PHP 版本的 (Workerman 版本)

环境要求

git

这个版本管理肯定需要安装的

node

node 版本最新的即可

jdk

JDK 8

maven

3.6.1

vue

构建工具用 vue 目前使用的 2.x 版本

java 安装

spring boot

2.1.2

下载

git clone https://github.com/lmxdawn/him-netty.git

cd him-netty

SQL的导入

创建数据库,名称: him, 把 根目录下 scripts 里面的 him.sql 导入进去

打包

mvn -Dmaven.test.skip=true clean package

java -jar him-api/target/him-api-0.0.1-SNAPSHOT.jar

如果要加环境配置 --spring.profiles.active=pro 即可, 默认是 dev 环境。
特别要注意:配置文件里面有跨域配置,这个一定要注意

vue 安装

下载

git clone https://github.com/lmxdawn/him-vue.git
cd him-vue

安装

npm install

编译

npm run serve 本地测试版 | npm run build 编译命令

him-vue 前往 和 him-netty 前往 都启动后访问 http://localhost:8080

注意 默认使用 QQ登录, 这个需要去申请QQ互联, 如果不想去申请, 则可以直接设置 Cookie, 两个值 UID 和 SID, 这两个值可以通过接口 /api/user/login/byPwd 获取, 具体请看java 代码

加好友演示

加群演示

QQ 互联相关配置

java 代码

him-api/src/main/resources/ 这里的配置文件里面, qq.auth.appidqq.auth.appkey 配置上即可

vue 代码

详细配置 根目录下的
.env.development
.env.production
.env.stage 这三个文件是配置, 分别代表 本地测试,生产环境,线上测试环境

名称 描述
VUE_APP_API_BASE API接口地址
VUE_APP_WEBSOCKET_URL websocket地址
VUE_APP_USER_QR_CODE_URL 生成用户的二维码地址(用来加好友的)
VUE_APP_GROUP_QR_CODE_URL 生成群二维码的地址(用来加群的)
VUE_APP_ROUTER_BASE 如果用了 NGINX 做代理, 并且有二级路径, 则需要配置此项

跨域问题

NGINX 做了端口的代理后, header 头 设置了跨域, 但是还是获取不了, 不知道为啥, 欢迎大神来指导

最后我的解决办法, 全部用一个域名, 然后 NGINX 做路径的转换,下面贴一下我的配置

# 前端路径, 注意这里配置了二级目录后, 需要 vue 的路由里面也需要配置
# 我是写在配置文件里面的 VUE_APP_ROUTER_BASE 这个配置项来控制的
location /h5 {
   try_files $uri $uri/ /h5/index.html;
}
# API 路径
location /api
{
  proxy_pass http://127.0.0.1:9000/api;
  proxy_http_version 1.1;
  proxy_set_header Upgrade $http_upgrade;
  proxy_set_header Connection "Upgrade";
  proxy_set_header X-Real-IP $remote_addr;
}
# ws 路径
location /ws
{
  proxy_pass http://127.0.0.1:9001;
  proxy_http_version 1.1;
  proxy_set_header Upgrade $http_upgrade;
  proxy_set_header Connection "Upgrade";
  proxy_set_header X-Real-IP $remote_addr;
}

Him 组件说明

参数 说明 类型 可选值 默认值
isShow 是否显示界面 boolean true
width 宽度 string 100%
height 高度 string 100%
top 定位的顶部位置 string
left 定位的左边位置 string
bottom 定位的底部位置 string
right 定位的右边位置 string
apiBaseUrl api 接口的地址 string
webSocketUrl websocket 的连接地址 string
userQRCodeUrl 用户二维码的生成地址 string
groupQRCodeUrl 群二维码的生成地址 string
isAutoInit 是否自动初始化(如果为 false 需要执行) boolean true
webSocketReconnectMaxCount 尝试重新连接的最大次数 number 5

图床说明

把图片放入 git 版本控制里, 上传到 GitHub 上, 然后 在 GitHub 里打开这个图片 把里面的 blob 改为 raw

例如: https://github.com/lmxdawn/him-vue/blob/master/pic/WechatIMG10.jpeg 改为 https://github.com/lmxdawn/him-vue/raw/master/pic/WechatIMG10.jpeg

我这里直接用的 七牛云的, 因为怕 GitHub 的访问太慢

protobuf 杂谈

说明: 目前所有文件都生成好了,不需要在生成,下面简单说明下

java 中使用

下载好 him-netty 后在 protocol 目录下

生成 java 类需要安装 安装 protoc 下载地址:https://github.com/protocolbuffers/protobuf/releases

目前下载的 v3.7.1,解压到任意目录 ,然后把这个目录添加到环境变量 Path 中

然后 windows 版本执行 proto.bat 即可,Linux/Max 运行 sh proto.sh

vue 中使用

目前我是安装好了 protobufjs 了,proto 文件放在 /src/proto 目录。
运行命令 pbjs -t json-module -w commonjs -o src/proto/proto.js src/proto/*.proto 即可
由于我添加到了 package.json 中,直接运行 npm run protojs 也可以

页面中引入

上面的执行完成后,会在 src/proto 目录下生成 proto.js 文件,由于 webpack 新版本的原因直接引入该文件会报错
Cannot assign to read only property'exports'of object'
需要修改最后一行代码为export default $root;

import protoRoot from "@/proto/proto"
const WSBaseReqProto = protoRoot.lookup("protocol.WSBaseReqProto");
const WSBaseResProto = protoRoot.lookup("protocol.WSBaseResProto");
// 编码
function (payload) {
    // 加入登录验证
    payload.uid = parseInt(this.getUid());
    payload.sid = this.getSid();
    console.log("发送的信息:");
    let errMsg = WSBaseReqProto.verify(payload);
    console.log("buff 解析错误信息:", errMsg);
    // Create a new message
    const wsData = WSBaseReqProto.create(payload); // or use .fromObject if conversion is necessary
    // Encode a message to an Uint8Array (browser) or Buffer (node)
    return WSBaseReqProto.encode(wsData).finish();
}
// 解码
function (data, cb) {
    let reader = new FileReader();
    reader.readAsArrayBuffer(data);
    reader.onload = () => {
        const buf = new Uint8Array(reader.result);
        const response = WSBaseResProto.decode(buf);
        // 成功回调
        cb(response);
    };
}

扩展阅读

Vue-cli3.0 + Element UI + ThinkPHP5.1 + RBAC权限 + 响应式的后台管理系统

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,542评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,596评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,021评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,682评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,792评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,985评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,107评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,845评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,299评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,612评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,747评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,441评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,072评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,828评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,069评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,545评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,658评论 2 350

推荐阅读更多精彩内容

  • feisky云计算、虚拟化与Linux技术笔记posts - 1014, comments - 298, trac...
    不排版阅读 3,833评论 0 5
  • 第一部分 HTML&CSS整理答案 1. 什么是HTML5? 答:HTML5是最新的HTML标准。 注意:讲述HT...
    kismetajun阅读 27,450评论 1 45
  • 今天中午我们在下面跳跳绳,跳绳是双飞也是学校规定的,跳双飞可不是通的那一种跳一个的普通跳。跳双飞是脚下跳...
    李诗雅1212阅读 258评论 0 0
  • 文 / 懵晓懂 对宇宙的奥秘人类不再仅限于星球的探索,而是把目光伸向了维度空间。或许这个世界正如佛经所说,一切皆空...
    懵晓懂阅读 357评论 0 1
  • 相识相知相离,是乎就那么的遥远又那么近,也许再也没有也许吧!她和他认识是因为一本书,一本他们两个都喜欢的书...
    远方WZY阅读 208评论 0 4