仿微信的聊天工具,网页版多端聊天软件 具有良好的横向扩展能力
一个仿微信的聊天工具。后端采用springboot+netty实现,web端使用vue,移动端使用uniapp,支持私聊、群聊、离线消息、发送图片、文件、语音、emoji表情、视频聊天等功能。
一、项目简介一个仿微信实现的网页版聊天软件,目前完全开源。 支持私聊、群聊、离线消息、发送语音、图片、文件、emoji表情等功能 支持视频聊天(基于webrtc实现,需要ssl证书) 后端采用springboot+netty实现,网页端使用vue,移动端使用uniapp 服务器支持集群化部署,每个im-server仅处理自身连接用户的消息
二、功能概述特点合适人群如果您是以下人群之一,那么盒子IM将会非常适合您: 企业中的项目需要开发IM模块,希望快速整合盒子IM的部分功能 对IM系统比较感兴趣,想学习如何独立编写一个优雅且高性能的IM系统 在校生或者刚参加工作的小伙伴,通过学习优质的开源项目提升自己的编程实战能力
三、技术选型 前置技能掌握以下技能: 后端:Springboot、Mybatis-plus、Netty、Mysql、Redis 前端:Vue、Uniapp 地环境搭建技术选型
后端框架:Springboot、Netty、Mybatis-plus、Swagger、Jwt 技术组件:Mysql、Redis、Minio、Coturn、Nginx 前端技术:Vue、Eelement-ui、Uniapp、Webrtc 基础环境安装安装GIT、JDK1.8、IDEA、Maven、HbuilderX(略)
本项目结构[td]模块 | 功能 | im-platform | 与页面进行交互,处理业务请求 | im-server | 推送聊天消息 | im-client | 消息推送sdk | im-common | 公共包 | im-ui | web页面 | im-uniapp | app页面 | 消息推送方案
- 当消息的发送者和接收者连的不是同一个server时,消息是无法直接推送的,所以我们需要设计出能够支持跨节点推送的方案
- 利用了redis的list数据实现消息推送,其中key为im:unread{serverid},每个key的数据可以看做一个queue,每个im-server根据自身的id只消费属于自己的queue
- redis记录了每个用户的websocket连接的是哪个im-server,当用户发送消息时,im-platform将根据所连接的im-server的id,决定将消息推向哪个queue
本地快速部署1.安装运行环境 - 安装node:v14.16.0
- 安装jdk:1.8
- 安装maven:3.6.3
- 安装mysql:5.7,密码分别为root/root,运行sql脚本(脚本在im-platfrom的resources/db目录)
- 安装redis:5.0
- 安装minio,命令端口使用9001,并创建一个名为"box-im"的bucket,并设置访问权限为公开
2.启动后端服务 - mvn clean package
- java -jar ./im-platform/target/im-platform.jar
- java -jar ./im-server/target/im-server.jar
[color=rgb(51, 102, 153) !important]复制代码
3.启动前端web - cd im-ui
- npm install
- npm run serve
[color=rgb(51, 102, 153) !important]复制代码
访问 http://localhost:8080 4.启动uniapp-h5 将im-uniapp目录导入HBuilderX,点击菜单"运行"->"开发环境-h5" 访问 http://localhost:5173 快速接入消息推送的请求代码已经封装在im-client包中,对于需要接入im-server的小伙伴,可以按照下面的教程快速的将IM功能集成到自己的项目中。 注意服务器端和前端都需要接入,服务器端发送消息,前端接收消息。 4.1 服务器端接入 引入pom文件 - <dependency>
- <groupId>com.bx</groupId>
- <artifactId>im-client</artifactId>
- <version>2.0.0</version>
- </dependency>
[color=rgb(51, 102, 153) !important]复制代码
内容使用了redis进行通信,所以要配置redis地址: - spring:
- redis:
- host: 127.0.0.1
- port: 6379
[color=rgb(51, 102, 153) !important]复制代码
直接把IMClient通过@Autowire导进来就可以发送消息了,IMClient 只有2个接口: - public class IMClient {
- /**
- * 发送私聊消息
- *
- * @param message 私有消息
- */
- public<T> void sendPrivateMessage(IMPrivateMessage<T> message);
- /**
- * 发送群聊消息(发送结果通过MessageListener接收)
- *
- * @param message 群聊消息
- */
- public<T> void sendGroupMessage(IMGroupMessage<T> message);
- }
[color=rgb(51, 102, 153) !important]复制代码
发送私聊消息(群聊也是类似的方式): - @Autowired
- private IMClient imClient;
- public void sendMessage(){
- IMPrivateMessage<rivateMessageVO> sendMessage = new IMPrivateMessage<>();
- // 发送方的id和终端类型
- sendMessage.setSender(new IMUserInfo(1L, IMTerminalType.APP.code()));
- // 对方的id
- sendMessage.setRecvId(2L);
- // 推送给对方所有终端
- sendMessage.setRecvTerminals(IMTerminalType.codes());
- // 同时推送给自己的其他类型终端
- sendMessage.setSendToSelf(true);
- // 需要回推发送结果,将在IMListener接收发送结果
- sendMessage.setSendResult(true);
- // 推送的内容
- sendMessage.setData(msgInfo);
- // 推送消息
- imClient.sendPrivateMessage(sendMessage);
- }
[color=rgb(51, 102, 153) !important]复制代码
监听发送结果: 1.编写消息监听类,实现MessageListener,并加上@IMListener 2.发送消息时指定sendResult为true - @Slf4j
- @IMListener(type = IMListenerType.ALL)
- public class PrivateMessageListener implements MessageListener {
- @Override
- public void process(IMSendResult<rivateMessageVO> result){
- PrivateMessageVO messageInfo = result.getData();
- if(result.getCode().equals(IMSendCode.SUCCESS.code())){
- log.info("消息发送成功,消息id:{},发送者:{},接收者:{},终端:{}",messageInfo.getId(),result.getSender().getId(),result.getReceiver().getId(),result.getReceiver().getTerminal());
- }
- }
- }
[color=rgb(51, 102, 153) !important]复制代码
4.2 前端接入 首先将im-ui/src/api/wssocket.js拷贝到自己的项目。 接入代码如下: - import * as wsApi from './api/wssocket';
- let wsUrl = 'ws://localhost:8878/im'
- let token = "您的token";
- wsApi.connect(wsUrl,token);
- wsApi.onConnect(() => {
- // 连接打开
- console.log("连接成功");
- });
- wsApi.onMessage((cmd,msgInfo) => {
- if (cmd == 2) {
- // 异地登录,强制下线
- console.log("您已在其他地方登陆,将被强制下线");
- } else if (cmd == 3) {
- // 私聊消息
- console.log(msgInfo);
- } else if (cmd == 4) {
- // 群聊消息
- console.log(msgInfo);
- }
- })
- wsApi.onClose((e) => {
- if (e.code != 3000) {
- console.log("意外断开,进行重连");
- wsApi.reconnect(wsUrl,token);
- }else{
- console.log("主动断开");
- }
- });
[color=rgb(51, 102, 153) !important]复制代码
私聊:
群聊:
好友列表:
群聊列表:
微信小程序:
以下内容需要积分高于 2 才可浏览
链接:https://pan.baidu.com/s/1dgOS7PVI42jeWZYd3uKi6g
提取码下载:
|