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

前言

一篇文章引发的思考?

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

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

心路历程
  • 第一阶段, 刚看完文章时, 特别兴奋, 开始着手, 花了一个月把聊天界面基本弄, 然后着手于后端, 经过些简单的调研, 决定用 netty 搭建一个, 后面发现里面的复杂逻辑, 再加上心中的火似乎已经熄灭, 最后...
  • 第二阶段, 最近刷公文时又刷到这篇类似的文章, 于是决定不能退缩, 所以有了接下来的事
踩坑指南
    1. iOS版本手机QQ中清空不了 Cookie 的bug (Android 版本的QQ没试), 其它浏览器均正常
    1. 手机微信中打开后点击输入文字后, 不管点不点击发送按钮都会出现短暂的不能点击的现象(任何按钮都不能点击), 后来发现是因为在微信里面, 输入法把 输入框顶上去了, 然后输入法隐藏后输入框还在上面!!!! 点击查看详情

    。找到一个解决输入框的方法: @blur="chatTextBlur" 监听失去焦点的事件(vue 写法), 然后在事件里面执行 window.scroll(0, 0);

    1. 因为设置了定位,overflow: scroll原生滚动,iOS下会不流畅,解决办法:换成 -webkit-overflow-scrolling: touch;
功能列表
  • 单聊
  • 群聊
  • protobuf 编解码
  • 客户端心跳
  • 客户端断开重连
  • 异地登录, 通知下线
  • 移动端/PC端适配
  • 离线消息 (消息通过 ack 机制, 实现可达性)
  • 第三方QQ登录
  • 自带 emoji 表情
  • 文本消息
  • 声音提示
  • 图片消息
  • 音频消息
  • 视屏消息
  • 分布式部署
  • 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.gitcd 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_BASEAPI接口地址
VUE_APP_WEBSOCKET_URLwebsocket地址
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是否显示界面booleantrue
width宽度string100%
height高度string100%
top定位的顶部位置string
left定位的左边位置string
bottom定位的底部位置string
right定位的右边位置string
apiBaseUrlapi 接口的地址string
webSocketUrlwebsocket 的连接地址string
userQRCodeUrl用户二维码的生成地址string
groupQRCodeUrl群二维码的生成地址string
isAutoInit是否自动初始化(如果为 false 需要执行)booleantrue
webSocketReconnectMaxCount尝试重新连接的最大次数number5
图床说明

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

例如: https://github.com/lmxdawn/hi...改为 https://github.com/lmxdawn/hi...

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

protobuf 杂谈

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

java 中使用

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

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

目前下载的 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);
    };
}
GitHub 地址

him-vue 前往

him-netty 前往

扩展阅读

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

原文链接:segmentfault.com

上一篇:gulp-wrap-exports
下一篇:string-interpolate

相关推荐

官方社区

扫码加入 JavaScript 社区