前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >基于websocket实现im聊天

基于websocket实现im聊天

原创
作者头像
查拉图斯特拉说
修改2023-11-14 14:53:25
7398
修改2023-11-14 14:53:25
举报
文章被收录于专栏:后端架构

前言

文字聊天应该是很多人每天常用的功能,这篇文章就来分析一下聊天是怎么创建的,他的底层逻辑是什么,以及如何实现他的底层逻辑。

设计实现

消息的发送过程就像这张图一样,经过websocket进行一个消息的转发,一对一是这样,在群里里面发消息也是这个逻辑,一个消息发送给多个人。本质是也是一对一聊天,只是逻辑的干预是你觉得他就是一对多群聊。

用户缓存的核心代码,缓存用户连接。SessionCache封装了用户的信息和客户端连接的引用。

代码语言:javascript
复制
/**
 * 保存sessionId与用户的map
 */
Map<String, SessionCache> sessionCacheMap = new ConcurrentHashMap<>();

当用户登录的时候建立websocket长连接并且把连接信息存入到本地缓存,当有用户给他发消息的时候进行一个消息转发。

代码语言:javascript
复制
public void wsOpen(WebSocketSession session) throws IOException {
    CacheToken cache = validateTokenAndReturnCache(session, tokenCache);
    if (cache == null) return;
    log.info("websocket id:{} 建立连接,用户token:{} 连接成功,放入在线用户缓存", session.getId(), cache.getToken());
    javsessionCacheMap.put(session.getId(), new SessionCache(cache.getToken(), session));
}

当用户下线之后的代码,从本地清除缓存,如果有用户给他发消息就存入到缓存。

代码语言:javascript
复制
/**
 * 关闭连接清除缓存
* @param sessionId
* @return
 */
public void wsClose(String sessionId) {
	SessionCache sessionCache = sessionCacheMap.remove( sessionId );
}

发送消息的代码,当消息过来获取缓存中的WebSocketSession进行一个字节流的逻辑写入。

代码语言:javascript
复制
/**
 * 发送消息的方法
* @param session
* @param payload
* @return
 */
public boolean sendData(WebSocketSession session, String payload){
	if (session == null || !session.isOpen()) {
return false;
}
	try {
		if (session.isOpen()) {
			session.sendMessage(new TextMessage(payload));
			return true;
		} else {
		// 连接关闭,丢弃消息
		// String token = (String) session.getAttributes().get("token");
 		// log.debug( "websocket id:{} 已经关闭, token:{}, 丢弃消息。", session.getId(), token);
 		// log.debug("websocket关闭丢弃消息:{}", payload);
			return false;
		}
	} catch (IOException e) {
		if (e instanceof IOException || e instanceof SocketTimeoutException) {
			log.info("发送消息报错:session.isOpen():{} ERROR: {}", session != null ? session.isOpen() : null,
			e.getMessage());
		} else {
			log.error("发送消息报错:session.isOpen():{}", session != null ? session.isOpen() : null, e);
		}
		return false;
	}
}

消息体

常见的消息分为文字消息,图片消息还有语音消息。这里暂且不说视频流。也就是我们常用的视频聊天。首先从最基本的文字,图片和语音来说,到后台这边都是使用的JSON格式。文字就不用说了,图片的话是经过一个第三方的存储文件服务器转换成的一个链接。然后用户端进行一个渲染。然后才会看到常用的一些图片。然后语音消息其实也是一段文凭。音频其实也是一个文件。到文件服务器之后也是一个文件的链接,然后用户端进去。格式进行一个转换。最后呈现给用户的就是一段语音。

这里要说的有一个点,就是一个敏感字的处理。其实敏感字的检索这就涉及到一些算法的操作。我们可能需要查看某一段文字当中是不是有一些敏感字?在常见的操作当然是使用字符检索一下,也可以使用一些专门的检索算法,当然逻辑上每一个系统里面会有一张专门用来配置的敏感字目录,存在敏感字。进行拒绝或者打码操作。

总结

这里解释了最简单的语音聊天的一个。实现当你用户量变得很大的时候,可能已经满足不了需求。需要用到Netty进行一个性能的提升。这是后话大道至简,其实越复杂的东西是靠着简单的功能一点点往上面叠加而产生的,一对一的聊天,本质上就是数据的传递。

引用

https://www.baeldung.com/java-websockets

点赞关注评论一键三连,欢迎关注公众号【i查拉图斯特拉如是说】每周分享技术干货、开源项目、实战经验、国外优质文章翻译等,您的关注将是我的更新动力!

我正在参与2023腾讯技术创作特训营第三期有奖征文,组队打卡瓜分大奖!

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
    • 设计实现
      • 消息体
      • 总结
        • 引用
        相关产品与服务
        即时通信 IM
        即时通信 IM(Instant Messaging)基于腾讯二十余年的 IM 技术积累,支持 Android、iOS、Mac、Windows、Web、H5、小程序平台且跨终端互通,低代码 UI 组件助您30分钟集成单聊、群聊、好友与资料、消息漫游、群组管理、会话管理、直播弹幕、内容审核和推送等能力。适用于直播互动、电商带货、客服咨询、社交沟通、企业办公、互动游戏、医疗健康等场景。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档