From f92fca9fb18b7deecbca8318609490dfe76b3888 Mon Sep 17 00:00:00 2001 From: konenet Date: Sat, 27 Nov 2021 09:14:55 +0800 Subject: [PATCH] feat: video chat, register and join group --- README.md | 67 +++- package-lock.json | 175 ++++++++++ package.json | 2 + public/screenshot/go-chat-panel.jpeg | Bin 0 -> 164682 bytes src/chat/Login.jsx | 89 +++++- src/chat/Panel.jsx | 461 ++++++++++++++++++--------- src/chat/common/param/Params.jsx | 7 +- src/chat/component/UserInfo.jsx | 159 +++++++++ src/chat/proto/message.proto | 3 +- src/chat/proto/proto.js | 7 +- src/chat/redux/module/index.jsx | 9 + src/chat/redux/module/userInfo.jsx | 25 ++ src/index.js | 8 +- yarn.lock | 77 ++++- 14 files changed, 914 insertions(+), 175 deletions(-) create mode 100644 public/screenshot/go-chat-panel.jpeg create mode 100644 src/chat/component/UserInfo.jsx create mode 100644 src/chat/redux/module/index.jsx create mode 100644 src/chat/redux/module/userInfo.jsx diff --git a/README.md b/README.md index 0a57b59..9ee9941 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,64 @@ -该仓库是go-chat的前端界面。 -后端是使用go开发的,基于WebSocket的聊天程序。 -后端仓库地址: -https://github.com/kone-net/go-chat +## go-chat +使用Go基于WebSocket的通讯聊天软件。 +### 功能列表: +* 登录注册 +* 修改头像 +* 群聊天 +* 群好友列表 +* 单人聊天 +* 添加好友 +* 添加群组 +* 文本消息 +* 剪切板图片 +* 图片消息 +* 文件发送 +* 语音消息 +* 视频消息 +* 屏幕共享(基于图片) +* 视频通话(基于webrtc的p2p视频通话) + +## 后端 +[代码仓库](https://github.com/kone-net/go-chat) +go中协程是非常轻量级的。在每个client接入的时候,为每一个client开启一个协程,能够在单机实现更大的并发。同时go的channel,可以非常完美的解耦client接入和消息的转发等操作。 + +通过go-chat,可以掌握channel的和Select的配合使用,ORM框架的使用,web框架Gin的使用,配置管理,日志操作,还包括proto buffer协议的使用,等一些列项目中常用的技术。 + + +### 后端技术和框架 +* web框架Gin +* 长连接WebSocket +* 日志框架Uber的zap +* 配置管理viper +* ORM框架gorm +* 通讯协议Google的proto buffer +* makefile 的编写 +* 数据库MySQL +* 图片文件二进制操作 + +## 前端 +基于react,UI和基本组件是使用ant design。可以很方便搭建前端界面。 + +界面选择单页框架可以更加方便写聊天界面,比如像消息提醒,可以在一个界面接受到消息进行提醒,不会因为换页面或者查看其他内容影响消息接受。 +[前端代码仓库](https://github.com/kone-net/go-chat-web): +https://github.com/kone-net/go-chat-web + + +### 前端技术和框架 +* React +* Redux状态管理 +* AntDesign +* proto buffer的使用 +* WebSocket +* 剪切板的文件读取和操作 +* 聊天框发送文字显示底部 +* FileReader对文件操作 +* ArrayBuffer,Blob,Uint8Array之间的转换 +* 获取摄像头视频(mediaDevices) +* 获取麦克风音频(Recorder) +* 获取屏幕共享(mediaDevices) +* WebRTC的p2p视频通话 + + +### 截图 +![go-chat-panel](/public/screenshot/go-chat-panel.jpeg) diff --git a/package-lock.json b/package-lock.json index ce0c6e4..bee9ef8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,8 +17,10 @@ "react": "^17.0.2", "react-dom": "^17.0.2", "react-infinite-scroll-component": "^6.1.0", + "react-redux": "^7.2.6", "react-router-dom": "^5.3.0", "react-scripts": "4.0.3", + "redux-thunk": "^2.4.0", "socket.io-client": "^4.3.2", "web-vitals": "^1.0.1" } @@ -3095,6 +3097,15 @@ "@types/node": "*" } }, + "node_modules/@types/hoist-non-react-statics": { + "version": "3.3.1", + "resolved": "https://registry.npmmirror.com/@types/hoist-non-react-statics/download/@types/hoist-non-react-statics-3.3.1.tgz?cache=0&sync_timestamp=1637265727153&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2F%40types%2Fhoist-non-react-statics%2Fdownload%2F%40types%2Fhoist-non-react-statics-3.3.1.tgz", + "integrity": "sha1-ESSq/lEYy1kZd66xzqrtEHDrA58=", + "dependencies": { + "@types/react": "*", + "hoist-non-react-statics": "^3.3.0" + } + }, "node_modules/@types/html-minifier-terser": { "version": "5.1.2", "resolved": "https://registry.nlark.com/@types/html-minifier-terser/download/@types/html-minifier-terser-5.1.2.tgz?cache=0&sync_timestamp=1631043806613&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40types%2Fhtml-minifier-terser%2Fdownload%2F%40types%2Fhtml-minifier-terser-5.1.2.tgz", @@ -3273,12 +3284,39 @@ "integrity": "sha1-4TAwSNU4lWPhMPW92J03qZrLdes=", "license": "MIT" }, + "node_modules/@types/prop-types": { + "version": "15.7.4", + "resolved": "https://registry.npmmirror.com/@types/prop-types/download/@types/prop-types-15.7.4.tgz", + "integrity": "sha1-/PcgXCXf95Xuea8eMNosl5CAjxE=" + }, "node_modules/@types/q": { "version": "1.5.5", "resolved": "https://registry.nlark.com/@types/q/download/@types/q-1.5.5.tgz", "integrity": "sha1-daKo59irSyMEFFBdkjNdHctTpt8=", "license": "MIT" }, + "node_modules/@types/react": { + "version": "17.0.36", + "resolved": "https://registry.npmmirror.com/@types/react/download/@types/react-17.0.36.tgz?cache=0&sync_timestamp=1637514386557&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2F%40types%2Freact%2Fdownload%2F%40types%2Freact-17.0.36.tgz", + "integrity": "sha512-CUFUp01OdfbpN/76v4koqgcpcRGT3sYOq3U3N6q0ZVGcyeP40NUdVU+EWe3hs34RNaTefiYyBzOpxBBidCc5zw==", + "dependencies": { + "@types/prop-types": "*", + "@types/scheduler": "*", + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-redux": { + "version": "7.1.20", + "resolved": "https://registry.npmmirror.com/@types/react-redux/download/@types/react-redux-7.1.20.tgz", + "integrity": "sha1-QvDmGrq7Yh4SxmyW3alMWEI7198=", + "license": "MIT", + "dependencies": { + "@types/hoist-non-react-statics": "^3.3.0", + "@types/react": "*", + "hoist-non-react-statics": "^3.3.0", + "redux": "^4.0.0" + } + }, "node_modules/@types/resolve": { "version": "0.0.8", "resolved": "https://registry.nlark.com/@types/resolve/download/@types/resolve-0.0.8.tgz?cache=0&sync_timestamp=1629709391127&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40types%2Fresolve%2Fdownload%2F%40types%2Fresolve-0.0.8.tgz", @@ -3288,6 +3326,11 @@ "@types/node": "*" } }, + "node_modules/@types/scheduler": { + "version": "0.16.2", + "resolved": "https://registry.npmmirror.com/@types/scheduler/download/@types/scheduler-0.16.2.tgz?cache=0&sync_timestamp=1637270013832&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2F%40types%2Fscheduler%2Fdownload%2F%40types%2Fscheduler-0.16.2.tgz", + "integrity": "sha1-GmL4lSVyPd4kuhsBsJK/XfitTTk=" + }, "node_modules/@types/source-list-map": { "version": "0.1.2", "resolved": "https://registry.nlark.com/@types/source-list-map/download/@types/source-list-map-0.1.2.tgz", @@ -7544,6 +7587,11 @@ "integrity": "sha1-nxJ29bK0Y/IRTT8sdSUK+MGjb0o=", "license": "MIT" }, + "node_modules/csstype": { + "version": "3.0.10", + "resolved": "https://registry.npmmirror.com/csstype/download/csstype-3.0.10.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Fcsstype%2Fdownload%2Fcsstype-3.0.10.tgz", + "integrity": "sha512-2u44ZG2OcNUO9HDp/Jl8C07x6pU/eTR3ncV91SiK3dhG9TWvRVsCoJw14Ckx5DgWkzGA3waZWO3d7pgqpUI/XA==" + }, "node_modules/cyclist": { "version": "1.0.1", "resolved": "https://registry.npm.taobao.org/cyclist/download/cyclist-1.0.1.tgz", @@ -16966,6 +17014,36 @@ "integrity": "sha1-eJcppNw23imZ3BVt1sHZwYzqVqQ=", "license": "MIT" }, + "node_modules/react-redux": { + "version": "7.2.6", + "resolved": "https://registry.npmmirror.com/react-redux/download/react-redux-7.2.6.tgz?cache=0&sync_timestamp=1637424929776&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Freact-redux%2Fdownload%2Freact-redux-7.2.6.tgz", + "integrity": "sha1-SWM6JP5VK1+cr1j+uKE4k23f6ao=", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.15.4", + "@types/react-redux": "^7.1.20", + "hoist-non-react-statics": "^3.3.2", + "loose-envify": "^1.4.0", + "prop-types": "^15.7.2", + "react-is": "^17.0.2" + }, + "peerDependencies": { + "react": "^16.8.3 || ^17" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + }, + "react-native": { + "optional": true + } + } + }, + "node_modules/react-redux/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmmirror.com/react-is/download/react-is-17.0.2.tgz?cache=0&sync_timestamp=1637338596901&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Freact-is%2Fdownload%2Freact-is-17.0.2.tgz", + "integrity": "sha1-5pHUqOnHiTZWVVOas3J2Kw77VPA=" + }, "node_modules/react-refresh": { "version": "0.8.3", "resolved": "https://registry.npmmirror.com/react-refresh/download/react-refresh-0.8.3.tgz", @@ -17583,6 +17661,24 @@ "node": ">=8" } }, + "node_modules/redux": { + "version": "4.1.2", + "resolved": "https://registry.npmmirror.com/redux/download/redux-4.1.2.tgz", + "integrity": "sha1-FA81Qm2Zu0cpr3YK/PeeqqxAcQQ=", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.9.2" + } + }, + "node_modules/redux-thunk": { + "version": "2.4.0", + "resolved": "https://registry.npmmirror.com/redux-thunk/download/redux-thunk-2.4.0.tgz?cache=0&sync_timestamp=1635214108732&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Fredux-thunk%2Fdownload%2Fredux-thunk-2.4.0.tgz", + "integrity": "sha1-rInh1rm9ue5JzmmmkHG+QbvYLWc=", + "license": "MIT", + "peerDependencies": { + "redux": "^4" + } + }, "node_modules/regenerate": { "version": "1.4.2", "resolved": "https://registry.nlark.com/regenerate/download/regenerate-1.4.2.tgz", @@ -24082,6 +24178,15 @@ "@types/node": "*" } }, + "@types/hoist-non-react-statics": { + "version": "3.3.1", + "resolved": "https://registry.npmmirror.com/@types/hoist-non-react-statics/download/@types/hoist-non-react-statics-3.3.1.tgz?cache=0&sync_timestamp=1637265727153&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2F%40types%2Fhoist-non-react-statics%2Fdownload%2F%40types%2Fhoist-non-react-statics-3.3.1.tgz", + "integrity": "sha1-ESSq/lEYy1kZd66xzqrtEHDrA58=", + "requires": { + "@types/react": "*", + "hoist-non-react-statics": "^3.3.0" + } + }, "@types/html-minifier-terser": { "version": "5.1.2", "resolved": "https://registry.nlark.com/@types/html-minifier-terser/download/@types/html-minifier-terser-5.1.2.tgz?cache=0&sync_timestamp=1631043806613&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40types%2Fhtml-minifier-terser%2Fdownload%2F%40types%2Fhtml-minifier-terser-5.1.2.tgz", @@ -24221,11 +24326,37 @@ "resolved": "https://registry.npmmirror.com/@types/prettier/download/@types/prettier-2.4.1.tgz", "integrity": "sha1-4TAwSNU4lWPhMPW92J03qZrLdes=" }, + "@types/prop-types": { + "version": "15.7.4", + "resolved": "https://registry.npmmirror.com/@types/prop-types/download/@types/prop-types-15.7.4.tgz", + "integrity": "sha1-/PcgXCXf95Xuea8eMNosl5CAjxE=" + }, "@types/q": { "version": "1.5.5", "resolved": "https://registry.nlark.com/@types/q/download/@types/q-1.5.5.tgz", "integrity": "sha1-daKo59irSyMEFFBdkjNdHctTpt8=" }, + "@types/react": { + "version": "17.0.36", + "resolved": "https://registry.npmmirror.com/@types/react/download/@types/react-17.0.36.tgz?cache=0&sync_timestamp=1637514386557&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2F%40types%2Freact%2Fdownload%2F%40types%2Freact-17.0.36.tgz", + "integrity": "sha512-CUFUp01OdfbpN/76v4koqgcpcRGT3sYOq3U3N6q0ZVGcyeP40NUdVU+EWe3hs34RNaTefiYyBzOpxBBidCc5zw==", + "requires": { + "@types/prop-types": "*", + "@types/scheduler": "*", + "csstype": "^3.0.2" + } + }, + "@types/react-redux": { + "version": "7.1.20", + "resolved": "https://registry.npmmirror.com/@types/react-redux/download/@types/react-redux-7.1.20.tgz", + "integrity": "sha1-QvDmGrq7Yh4SxmyW3alMWEI7198=", + "requires": { + "@types/hoist-non-react-statics": "^3.3.0", + "@types/react": "*", + "hoist-non-react-statics": "^3.3.0", + "redux": "^4.0.0" + } + }, "@types/resolve": { "version": "0.0.8", "resolved": "https://registry.nlark.com/@types/resolve/download/@types/resolve-0.0.8.tgz?cache=0&sync_timestamp=1629709391127&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40types%2Fresolve%2Fdownload%2F%40types%2Fresolve-0.0.8.tgz", @@ -24234,6 +24365,11 @@ "@types/node": "*" } }, + "@types/scheduler": { + "version": "0.16.2", + "resolved": "https://registry.npmmirror.com/@types/scheduler/download/@types/scheduler-0.16.2.tgz?cache=0&sync_timestamp=1637270013832&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2F%40types%2Fscheduler%2Fdownload%2F%40types%2Fscheduler-0.16.2.tgz", + "integrity": "sha1-GmL4lSVyPd4kuhsBsJK/XfitTTk=" + }, "@types/source-list-map": { "version": "0.1.2", "resolved": "https://registry.nlark.com/@types/source-list-map/download/@types/source-list-map-0.1.2.tgz", @@ -27329,6 +27465,11 @@ } } }, + "csstype": { + "version": "3.0.10", + "resolved": "https://registry.npmmirror.com/csstype/download/csstype-3.0.10.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Fcsstype%2Fdownload%2Fcsstype-3.0.10.tgz", + "integrity": "sha512-2u44ZG2OcNUO9HDp/Jl8C07x6pU/eTR3ncV91SiK3dhG9TWvRVsCoJw14Ckx5DgWkzGA3waZWO3d7pgqpUI/XA==" + }, "cyclist": { "version": "1.0.1", "resolved": "https://registry.npm.taobao.org/cyclist/download/cyclist-1.0.1.tgz", @@ -33947,6 +34088,26 @@ "resolved": "https://registry.npmmirror.com/react-is/download/react-is-16.13.1.tgz?cache=0&sync_timestamp=1634573849595&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Freact-is%2Fdownload%2Freact-is-16.13.1.tgz", "integrity": "sha1-eJcppNw23imZ3BVt1sHZwYzqVqQ=" }, + "react-redux": { + "version": "7.2.6", + "resolved": "https://registry.npmmirror.com/react-redux/download/react-redux-7.2.6.tgz?cache=0&sync_timestamp=1637424929776&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Freact-redux%2Fdownload%2Freact-redux-7.2.6.tgz", + "integrity": "sha1-SWM6JP5VK1+cr1j+uKE4k23f6ao=", + "requires": { + "@babel/runtime": "^7.15.4", + "@types/react-redux": "^7.1.20", + "hoist-non-react-statics": "^3.3.2", + "loose-envify": "^1.4.0", + "prop-types": "^15.7.2", + "react-is": "^17.0.2" + }, + "dependencies": { + "react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmmirror.com/react-is/download/react-is-17.0.2.tgz?cache=0&sync_timestamp=1637338596901&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Freact-is%2Fdownload%2Freact-is-17.0.2.tgz", + "integrity": "sha1-5pHUqOnHiTZWVVOas3J2Kw77VPA=" + } + } + }, "react-refresh": { "version": "0.8.3", "resolved": "https://registry.npmmirror.com/react-refresh/download/react-refresh-0.8.3.tgz", @@ -34392,6 +34553,20 @@ "strip-indent": "^3.0.0" } }, + "redux": { + "version": "4.1.2", + "resolved": "https://registry.npmmirror.com/redux/download/redux-4.1.2.tgz", + "integrity": "sha1-FA81Qm2Zu0cpr3YK/PeeqqxAcQQ=", + "requires": { + "@babel/runtime": "^7.9.2" + } + }, + "redux-thunk": { + "version": "2.4.0", + "resolved": "https://registry.npmmirror.com/redux-thunk/download/redux-thunk-2.4.0.tgz?cache=0&sync_timestamp=1635214108732&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Fredux-thunk%2Fdownload%2Fredux-thunk-2.4.0.tgz", + "integrity": "sha1-rInh1rm9ue5JzmmmkHG+QbvYLWc=", + "requires": {} + }, "regenerate": { "version": "1.4.2", "resolved": "https://registry.nlark.com/regenerate/download/regenerate-1.4.2.tgz", diff --git a/package.json b/package.json index dac76a2..48910a0 100644 --- a/package.json +++ b/package.json @@ -13,8 +13,10 @@ "react": "^17.0.2", "react-dom": "^17.0.2", "react-infinite-scroll-component": "^6.1.0", + "react-redux": "^7.2.6", "react-router-dom": "^5.3.0", "react-scripts": "4.0.3", + "redux-thunk": "^2.4.0", "socket.io-client": "^4.3.2", "web-vitals": "^1.0.1" }, diff --git a/public/screenshot/go-chat-panel.jpeg b/public/screenshot/go-chat-panel.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..8948d2da372953d61fe83fa63a697e53d1c04519 GIT binary patch literal 164682 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 U(qY-qPI$@egui(;1bEH=0aFcvYXATM literal 0 HcmV?d00001 diff --git a/src/chat/Login.jsx b/src/chat/Login.jsx index 7fa6b23..7b5cc4f 100755 --- a/src/chat/Login.jsx +++ b/src/chat/Login.jsx @@ -3,6 +3,7 @@ import { Button, Form, Input, + Drawer, message } from 'antd'; import { axiosPostBody } from './util/Request'; @@ -12,6 +13,7 @@ class Login extends React.Component { constructor(props) { super(props) this.state = { + registerDrawerVisible: false } } @@ -37,6 +39,32 @@ class Login extends React.Component { console.log('Failed:', errorInfo); }; + showRegister = () => { + this.setState({ + registerDrawerVisible: true + }) + } + + registerDrawerOnClose = () => { + this.setState({ + registerDrawerVisible: false + }) + } + + onRegister = (values) => { + let data = { + ...values + } + + axiosPostBody(Params.REGISTER_URL, data) + .then(_response => { + message.success("注册成功!"); + this.setState({ + registerDrawerVisible: false + }) + }); + } + render() { return ( @@ -51,7 +79,7 @@ class Login extends React.Component { style={{ marginTop: 150 }} > @@ -59,7 +87,7 @@ class Login extends React.Component { @@ -68,10 +96,65 @@ class Login extends React.Component { + + + + + +
+ + + + + + + + + + + + + + + + + + + + +
+
); } diff --git a/src/chat/Panel.jsx b/src/chat/Panel.jsx index 44b0e7c..ef5f8e7 100755 --- a/src/chat/Panel.jsx +++ b/src/chat/Panel.jsx @@ -7,7 +7,7 @@ import { Drawer, Tag, Popover, - Tooltip + Tooltip, } from 'antd'; import { UserOutlined, @@ -21,17 +21,22 @@ import { PhoneOutlined, VideoCameraOutlined, UngroupOutlined, - DesktopOutlined + DesktopOutlined, + FileOutlined } from '@ant-design/icons'; import InfiniteScroll from 'react-infinite-scroll-component'; import moment from 'moment'; import { axiosGet, axiosPostBody } from './util/Request'; import * as Params from './common/param/Params' +import UserInfo from './component/UserInfo' import protobuf from './proto/proto' import Recorder from 'js-audio-recorder'; +import { connect } from 'react-redux' +import { actions } from './redux/module/userInfo' -var socket = null +var socket = null; +var peer = null; const { TextArea } = Input; @@ -105,7 +110,6 @@ var heartCheck = { } } - class Panel extends React.Component { constructor(props) { super(props) @@ -137,12 +141,13 @@ class Panel extends React.Component { }, share: { height: 540, - width: 960 + width: 750 }, currentScreen: { height: 0, width: 0 - } + }, + rtcType: 'answer', } } @@ -194,34 +199,54 @@ class Panel extends React.Component { const messagePB = message.create(data) socket.send(message.encode(messagePB).finish()) - // 将ArrayBuffer转换为base64进行展示 - const str = String.fromCharCode(...new Uint8Array(imgData)); - let base64String = `data:image/jpeg;base64,${window.btoa(str)}`; - - this.setState({ - comments: [ - ...this.state.comments, - { - author: localStorage.username, - avatar: this.state.user.avatar, - content:

, - datetime: moment().fromNow(), - }, - ], - }) + this.appendImgToPanel(imgData) }) }, false) } + /** + * 本地上传后,将图片追加到聊天框 + * @param {Arraybuffer类型图片}} imgData + */ + appendImgToPanel(imgData) { + // 将ArrayBuffer转换为base64进行展示 + var binary = ''; + var bytes = new Uint8Array(imgData); + var len = bytes.byteLength; + for (var i = 0; i < len; i++) { + binary += String.fromCharCode(bytes[i]); + } + let base64String = `data:image/jpeg;base64,${window.btoa(binary)}`; + + this.setState({ + comments: [ + ...this.state.comments, + { + author: localStorage.username, + avatar: this.state.user.avatar, + content:

, + datetime: moment().fromNow(), + }, + ], + }, () => { + setTimeout(this.scrollToBottom(), 3000) + }) + } + /** * 获取用户详情 */ fetchUserDetails = () => { axiosGet(Params.USER_URL + this.state.fromUser) .then(response => { + let user = { + ...response.data, + avatar: Params.HOST + "/file/" + response.data.avatar + } + this.props.setUser(user) this.setState({ - user: response.data, + user: user, }) }); } @@ -230,39 +255,15 @@ class Panel extends React.Component { * websocket连接 */ connection = () => { + console.log("to connect...") + peer = new RTCPeerConnection(); var image = document.getElementById('receiver'); - - let arr = [] - var video = document.getElementById('preview1') - let i = 0 - - // let flag = false - // let sourceBuffer - // let mediaSource = new MediaSource() - // var video = document.getElementById('preview1') - // video.src = URL.createObjectURL(mediaSource) - // mediaSource.addEventListener('sourceopen', sourceOpen); - - // function sourceOpen(e) { - // console.log("sourceOpen", "mediaSource ready state: ", mediaSource.readyState) - // // var mime = 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"' - // var mime = 'video/webm; codecs="opus, vp9"'; - // // 新建一个 sourceBuffer - // sourceBuffer = mediaSource.addSourceBuffer(mime); - - // sourceBuffer.addEventListener('updateend', function (_) { - // console.log(mediaSource.readyState); // ended - // // sourceBuffer.appendBuffer(arr) - // }); - // } - - - console.log("to connection") socket = new WebSocket("ws://" + Params.IP_PORT + "/socket.io?user=" + this.props.match.params.user) socket.onopen = () => { heartCheck.start() console.log("connected") + this.webrtcConnection() } socket.onmessage = (message) => { heartCheck.start() @@ -277,6 +278,7 @@ class Panel extends React.Component { return; } + // 视频图像 if (messagePB.contentType === 8) { let currentScreen = { width: this.state.video.width, @@ -289,6 +291,7 @@ class Panel extends React.Component { return; } + // 屏幕共享 if (messagePB.contentType === 9) { let currentScreen = { width: this.state.share.width, @@ -301,28 +304,9 @@ class Panel extends React.Component { return; } - // 接受语音电话或者视频电话 - if (messagePB.contentType === 6 || messagePB.contentType === 7) { - i++ - console.log(i) - // arr.push(messagePB.file) - - if (i % 5 === 0) { - // let fileReader = new FileReader(); - let recordedBlob = new Blob(arr, { type: "video/webm" }); //video/x-matroska;codecs=avc1,opus video/webm - // fileReader.readAsDataURL(recordedBlob) - // fileReader.onload = (e) => { - // console.log(e.target.result) - // video.src = e.target.result; - // this.setState({ - // url: e.target.result - // }) - // } - console.log(recordedBlob) - video.src = URL.createObjectURL(recordedBlob); - } - // sourceBuffer.appendBuffer(messagePB.file.buffer) - + // 接受语音电话或者视频电话 webrtc + if (messagePB.type === "webrtc") { + this.dealWebRtcMessage(messagePB); return; } @@ -331,18 +315,20 @@ class Panel extends React.Component { avatar = messagePB.avatar } + // 文件内容,录制的视频,语音内容 + let content = this.getContentByType(messagePB.contentType, messagePB.url, messagePB.content) this.setState({ comments: [ ...this.state.comments, { author: messagePB.fromUsername, avatar: avatar, - content:

{(messagePB.contentType === 2 || messagePB.contentType === 3) ? : messagePB.content}

, + content:

{content}

, datetime: moment().fromNow(), }, ], }, () => { - this.scrollToBottom() + setTimeout(this.scrollToBottom(), 3000) }) }) } @@ -360,6 +346,98 @@ class Panel extends React.Component { } } + /** + * webrtc 绑定事件 + */ + webrtcConnection = () => { + /** + * 对等方收到ice信息后,通过调用 addIceCandidate 将接收的候选者信息传递给浏览器的ICE代理。 + * @param {候选人信息} e + */ + peer.onicecandidate = (e) => { + if (e.candidate) { + // rtcType参数默认是对端值为answer,如果是发起端,会将值设置为offer + let candidate = { + type: this.state.rtcType + '_ice', + iceCandidate: e.candidate + } + + let data = { + fromUsername: localStorage.username, + from: this.state.fromUser, + to: this.state.toUser, + messageType: this.state.messageType, + content: JSON.stringify(candidate), + type: "webrtc", + } + let message = protobuf.lookup("protocol.Message") + const messagePB = message.create(data) + socket.send(message.encode(messagePB).finish()) + } + + }; + + /** + * 当连接成功后,从里面获取语音视频流 + * @param {包含语音视频流} e + */ + peer.ontrack = (e) => { + if (e && e.streams) { + let remoteVideo = document.getElementById("remoteVideo"); + remoteVideo.srcObject = e.streams[0]; + } + }; + } + + /** + * 处理webrtc消息,包括获取请求方的offer,回应answer等 + * @param {消息内容}} messagePB + */ + dealWebRtcMessage = (messagePB) => { + const { type, sdp, iceCandidate } = JSON.parse(messagePB.content); + + if (type === "answer") { + const offerSdp = new RTCSessionDescription({ type, sdp }); + peer.setRemoteDescription(offerSdp) + } else if (type === "answer_ice") { + peer.addIceCandidate(iceCandidate) + } else if (type === "offer_ice") { + peer.addIceCandidate(iceCandidate) + } else if (type === "offer") { + let preview = document.getElementById("preview1"); + navigator.mediaDevices + .getUserMedia({ + audio: true, + video: true, + }).then((stream) => { + preview.srcObject = stream; + stream.getTracks().forEach(track => { + peer.addTrack(track, stream); + }); + + // 一定注意:需要将该动作,放在这里面,即流获取成功后,再进行answer创建。不然不能获取到流,从而不能播放视频。 + const offerSdp = new RTCSessionDescription({ type, sdp }); + peer.setRemoteDescription(offerSdp) + .then(() => { + peer.createAnswer().then(answer => { + peer.setLocalDescription(answer) + let data = { + fromUsername: localStorage.username, + from: this.state.fromUser, + to: this.state.toUser, + messageType: this.state.messageType, + content: JSON.stringify(answer), + type: "webrtc", + } + let message = protobuf.lookup("protocol.Message") + const messagePB = message.create(data) + socket.send(message.encode(messagePB).finish()) + }) + }); + }); + } + } + /** * 断开连接后重新连接 */ @@ -397,7 +475,7 @@ class Panel extends React.Component { username: users[index].username, uuid: users[index].uuid, messageType: 1, - avatar: users[index].avatar, + avatar: Params.HOST + "/file/" + users[index].avatar, } data.push(d) } @@ -534,16 +612,22 @@ class Panel extends React.Component { return } - axiosGet(Params.USER_URL + value) + let data = { + name: value + } + axiosGet(Params.USER_NAME_URL, data) .then(response => { - console.log(response) - if (response.data.username === 0) { - message.error("无此用户") + let data = response.data + if (data.user.username === "" && data.group.name === "") { + message.error("未查找到群或者用户") return } let queryUser = { - username: response.data.username, - nickname: response.data.nickname, + username: data.user.username, + nickname: data.user.nickname, + + groupUuid: data.group.uuid, + groupName: data.group.name, } this.setState({ hasUser: true, @@ -573,6 +657,18 @@ class Panel extends React.Component { }); }; + joinGroup = () => { + // /group/join/:userUid/:groupUuid + axiosPostBody(Params.GROUP_JOIN_URL + this.state.fromUser + "/" + this.state.queryUser.groupUuid) + .then(_response => { + message.success("添加成功") + this.fetchUserList() + this.setState({ + hasUser: false + }); + }); + } + handleCancel = () => { this.setState({ hasUser: false @@ -601,21 +697,11 @@ class Panel extends React.Component { } for (var i = 0; i < data.length; i++) { let contentType = data[i].contentType - let content = data[i].content; - - if (contentType === 2) { - - } else if (contentType === 3) { - content = - } else if (contentType === 4) { - content =