一飞开源,介绍创意、新奇、有趣、实用的开源应用、系统、软件、硬件及技术,一个探索、发现、分享、使用与互动交流的开源技术社区平台。致力于打造活力开源社区,共建开源新生态!
一、开源项目简介盒子IM盒子IM是一个仿微信实现的网页版聊天软件,目前完全开源。支持私聊、群聊、离线消息、发送语音、图片、文件、emoji表情等功能支持视频聊天(基于webrtc实现,需要ssl证书)后端采用springboot+netty实现,网页端使用vue,移动端使用uniapp服务器支持集群化部署,每个im-server仅处理自身连接用户的消息二、开源协议使用MIT开源协议
三、界面展示界面截图私聊:
群聊:
好友列表:
群聊列表:
微信小程序:
四、功能概述特点盒子IM是一个仿微信实现的网页版聊天软件,目前完全开源且免费支持web端和移动端同时在线以及消息同步后端服务支持集群化部署,具有良好的横向扩展能力消息推送功能已进行SDK封装,可快速接入企业项目合适人群如果您是以下人群之一,那么盒子IM将会非常适合您:
企业中的项目需要开发IM模块,希望快速整合盒子IM的部分功能对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(略)项目结构模块
功能
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只消费属于自己的queueredis记录了每个用户的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 packagejava -jar ./im-platform/target/im-platform.jarjava -jar ./im-server/target/im-server.jar3.启动前端web
cd im-uinpm installnpm run serve访问 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>内容使用了redis进行通信,所以要配置redis地址:
spring: redis: host: 127.0.0.1 port: 6379直接把IMClient通过@Autowire导进来就可以发送消息了,IMClient 只有2个接口:
public IMClient { /** * 发送私聊消息 * * @param message 私有消息 */ public<T> void sendPrivateMessage(IMPrivateMessage<T> message); /** * 发送群聊消息(发送结果通过MessageListener接收) * * @param message 群聊消息 */ public<T> void sendGroupMessage(IMGroupMessage<T> message); }发送私聊消息(群聊也是类似的方式):
@Autowired private IMClient imClient; public void sendMessage(){ IMPrivateMessage<PrivateMessageVO> 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);}监听发送结果: 1.编写消息监听类,实现MessageListener,并加上@IMListener 2.发送消息时指定sendResult为true
@Slf4j@IMListener(type = IMListenerType.ALL)public PrivateMessageListener implements MessageListener { @Override public void process(IMSendResult<PrivateMessageVO> 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()); } }}4.2 前端接入 首先将im-ui/src/api/wssocket.js拷贝到自己的项目。
接入代码如下:
import * as wsApi from './api/wssocket';let wsUrl = 'ws://localhost:8878/im'let token = "您的token";wsApi.init(wsUrl,token);wsApi.connect();wsApi.onOpen(() => { // 连接打开 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) => { console.log("连接关闭");});六、源码地址访问一飞开源:https://code.exmay.com/