Instant Messaging (即时通讯) 含代码

代码地址: https://github.com/Xavier-777/Instant-Messaging


简介

使用 Sparkjava 作为后端服务器,开发的一个即时聊天室,可以发送文本信息、图片、音频、视频等信息,可以发送 zip、docx等文件,甚至可以进行语音视频通话等功能。


Sparkjava简介

这里的Sparkjava是一个微型web框架,与大数据的spark是完全两个不同的东西。如果你有了解过 Node.js 那么 sparkjava 对你来说很容易上手,因为两者的编写方式很相似,你可以理解为java版的 Node.js ,但是Node.js 是一个异步非阻塞的框架,而sparkjava是同步阻塞的。(实际上是老师要求使用这个框架的!)


视频通话

这里使用了 agora.io(声网) 的sdk实现,当然你也可以使用其他的sdk


项目功能的业务流程介绍

1. 文本信息发送

websocket 链接创建过程:
在这里插入图片描述

websocket 消息传递
在这里插入图片描述


2. 视频、音频等二进制文件的发送

二进制文件用文件上传的方式进行传输,没有走 websocket 的流程
在这里插入图片描述


3. 在线视频通话

这里使用了声网的sdk实现该功能,具体的参考文档:https://docs.agora.io/cn/Video/landing-page?platform=Web
在我的项目中,需要写自己的 appId 与 appCertificate 才能使用视频通话的功能,建议自己去官网申请一个。更多详情可以去看官方文档


4. 心跳机制

首先了解一下什么是心跳机制。
之所以叫心跳机制是因为:它像心跳一样每隔固定时间向服务器发一次信息,以此来告诉服务器,这个客户端还活着。这个信息没有固定的要求。

那么现在就有两种情况:
1.服务器没有响应,前端无法接收到后端的消息。
2.服务器响应了,但前端没有接收该信息。

针对情况1:最有可能是服务器宕机了,无法响应,websocket断连,释放资源。
情况2:服务器没有宕机,但是该web页面被关闭了,所以接收不到该信息,websocket断连,释放资源。


因此,想要实现心跳检测,服务器必须响应该心跳信息,客户端也要接收该信息
这里给出我的实现方法:
前端:

// 心跳检测包
var heartCheck = {
    
    
    timeout: 30000,        //30秒发一次心跳
    timeoutObj: null,
    serverTimeoutObj: null,
    reset: function(){
    
    
        clearTimeout(this.timeoutObj);
        clearTimeout(this.serverTimeoutObj);
        this.start();
    },
    start: function(){
    
    
        var self = this;
        this.timeoutObj = setTimeout(function(){
    
    
            //这里发送一个心跳,后端收到后,返回一个心跳消息,
            //onmessage拿到返回的心跳就说明连接正常
            ws.send("ping");
            self.serverTimeoutObj = setTimeout(function(){
    
    //如果超过一定时间还没重置,说明后端主动断开了
                ws.close();     //如果onclose会执行reconnect,我们执行ws.close()就行了.如果直接执行reconnect 会触发onclose导致重连两次
            }, self.timeout)
        }, this.timeout)
    }
}


webSocket.onopen = function () {
    
    
    heartCheck.reset();  //心跳检测
};
webSocket.onmessage = function (msg) {
    
    
    var data = JSON.parse(msg.data);
    if (data.heartCheck) {
    
    
        console.log(data); //获取心跳json
    } else {
    
    
        updateChat(data);//解析json,并更新聊天列表
    }
    heartCheck.reset(); //心跳检测
};

console.log(data); 打印出心跳检测的信息,以证明客户端还在。


后端:

@OnWebSocketMessage
public void onMessage(Session user, String message) throws IOException {
    
    
    if (message.equals(heart)) {
    
    
        broadcastHeartCheck();
    } else {
    
    
        // 广播字符串
        broadcastMessage(Main.userUsernameMap.get(user), message);
    }
}

broadcastHeartCheck(); 收到的message是heart后,响应相应的心跳信息,以证明服务器还在。


未实现功能

1. 在线状态确认与离线消息处理

我去了解了一下实现的机制,发现需要用到 redis 缓存数据库,来记录用户的状态。当用户在线时,直接发送信息给该用户;当用户不在线时,将信息存到数据库中,等到用户上线了,再将该信息发给用户,然后将数据库的记录更改为已读状态。更多详细信息见下面的参考资源。


2. 在线录制视频、语音

目前还没有去了解,我猜用声网的sdk可以实现,但是我没有认真看完官方文档所以不敢确认。或者用其他的sdk也行。


总结

尚未实现的功能都是超出我目前的能力范围的,希望有dalao可以帮我实现,或者等我能力提升了,再去慢慢实现这些功能。


参考资料:
离线通讯机制:https://zhuanlan.zhihu.com/p/42982409
布隆过滤器:https://zhuanlan.zhihu.com/p/43263751

猜你喜欢

转载自blog.csdn.net/lendsomething/article/details/115297139
今日推荐