使用WebSocket实现聊天功能

这篇具有很好参考价值的文章主要介绍了使用WebSocket实现聊天功能。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


前言

使用WebSocket实现一对一的聊天功能与未读消息功能


一、数据库设计

会话表

字段名 字段类型 长度 注释
conversation_id int 11 会话ID
create_time datetime 创建时间
conversation_type int 1 会话类型

消息表

字段名 字段类型 长度 注释
message_id int 11 消息ID
conversation_id int 11 会话ID
sender_id int 11 发送者ID
receiver_id in t 11 接收者ID
content text 消息内容
type int 2 消息类型
information varchar 255 信息
sender_img int 11 发送者头像ID
receiver_img int 11 接收者头像ID
message_status int 1 消息状态(1已读,0未读)
create_time datetime 创建时间

二、实现代码

1.SessionWrap

@Data
public class SessionWrap {

    private String from;	// 连接人id
    private String type;	// 连接类型
    private Session session;
    private Date lastTime;
}

2.websocket

@Component
@ServerEndpoint(value = "/api/websocket/{from}/{type}")
public class WebSocketServer {

    @Autowired
    private RqriMessageService rqriMessageService;

    public static WebSocketServer webSocketServer;

    // 所有的连接会话
    private static CopyOnWriteArraySet<SessionWrap> sessionList = new CopyOnWriteArraySet<>();

    private String from;
    private String type;


    @PostConstruct
    public void init() {
        webSocketServer = this;
        webSocketServer.rqriMessageService = this.rqriMessageService;

    }

    @OnOpen
    public void onOpen(Session session, @PathParam(value = "from") String from, @PathParam(value = "type") String type) {
        this.from = from;
        this.type = type;
        try {
            // 遍历list,如果有会话,更新,如果没有,创建一个新的
            for (SessionWrap item : sessionList) {
                if (item.getFrom().equals(from) && item.getType().equals(type)) {
                    item.setSession(session);
                    item.setLastTime(new Date());
                    log.info("【websocket消息】更新连接,总数为:" + sessionList.size());
                    return;
                }
            }
            SessionWrap sessionWrap = new SessionWrap();
            sessionWrap.setFrom(from);
            sessionWrap.setType(type);
            sessionWrap.setSession(session);
            sessionWrap.setLastTime(new Date());
            sessionList.add(sessionWrap);
            log.info("【websocket消息】有新的连接,总数为:" + sessionList.size());
        } catch (Exception e) {
            log.info("【websocket消息】连接失败!错误信息:" + e.getMessage());
        }
    }

    @OnClose
    public void onClose() {
        try {
            sessionList.removeIf(item -> item.getFrom().equals(from) && item.getType().equals(type));
            log.info("【websocket消息】连接断开,总数为:" + sessionList.size());
        } catch (Exception e) {
            log.info("【websocket消息】连接断开失败!错误信息:" + e.getMessage());
        }
    }

    @OnMessage
    public void onMessage(String message, Session session) {
        try {
            if ("ping".equals(message)) {
                session.getBasicRemote().sendText("ping");	// 心跳检测
            } else {
                // 将消息插入到数据库
                JSONObject r = webSocketServer.rqriMessageService.insertMessage(message);
                // 成功
                if (r.getInteger("code") == 200) {
                    JSONObject data = r.getJSONObject("data");
                    String senderId = data.getString("senderId");      // 发送者
                    String receiverId = data.getString("receiverId");   // 接收者
                    for (SessionWrap item : sessionList) {
                        if (senderId.equals(item.getFrom()) || receiverId.equals(item.getFrom()) ) {
                            item.getSession().getBasicRemote().sendText(r.toJSONString());
                        } 
                    }
                    log.info("【websocket消息】发送消息:" + r.toJSONString());
                }
            }
        } catch (Exception e) {
            log.info("【websocket消息】发送消息失败!错误信息:" + e.getMessage());
        }
    }


    @OnError
    public void onError(Session session, Throwable error) {
        log.error("用户错误,原因:"+error.getMessage());
        error.printStackTrace();
    }

}

3.insertMessage

private final String rqriMessageStr = "rqri_message_unread_";

public JSONObject insertMessage(String message) {
        JSONObject jsonObject = new JSONObject();
        RqriMessage rqriMessage = JSONObject.parseObject(message, RqriMessage.class);
        // 把消息添加到数据库
        int i = rqriMessageMapper.insertSelective(rqriMessage);

        // 将未读信息添加到redis  添加接收者的未读
        String conversationId = String.valueOf(rqriMessage.getConversationId());
        String receiverId = String.valueOf(rqriMessage.getReceiverId());
        
        String key = rqriMessageStr + conversationId + "_" + receiverId;
        if (redisUtils.get(key) == null) {
            redisUtils.set(key, 1, 0); 	// 设置永不过期
        } else {
            redisUtils.incr(key, 1);	// 未读数量添加1
        }

        jsonObject.put("code", 200);
        jsonObject.put("data", rqriMessage);
        // 发送者的id和未读数量,返回给前端渲染到页面
        HashMap<String, Integer> map = new HashMap<>();
        map.put("num", Integer.valueOf(redisUtils.get(key).toString()));
        map.put("id", rqriMessage.getSenderId());
        jsonObject.put("isread", map);

        return jsonObject;
}

4.清除未读

最后在进入聊天页面和退出聊天页面时把未读数量清零。文章来源地址https://www.toymoban.com/news/detail-682316.html

到了这里,关于使用WebSocket实现聊天功能的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • django websocket实现聊天室功能

    注意事项channel版本 django2.x 需要匹配安装 channels 2 django3.x 需要匹配安装 channels 3 Django 3.2.4 channels 3.0.3 Django 3.2.* channels 3.0.2 Django4.2 channles==3.0.5 是因为最新版channels默认不带daphne服务器 直接用命令 python manage.py runsever 默认运行的是wsgi ,修改,删除settings中的wsgi,都不能正确运

    2024年01月22日
    浏览(45)
  • SpringBoot集成WebSocket实现及时通讯聊天功能!!!

    注意:   至此,后端代码就集成完了,集成完之后,记得重启你的Springboot项目 前端Vue 1:新建Vue 页面  路由: 代码:路由根据你项目的实际情况写 在用户登录的时候,需要将你的用户名存储到本地Session 中  效果图:  用户甲:   用户乙:   注:网上学习来源 SpringBoot集

    2024年02月01日
    浏览(43)
  • Ratchet实现PHP WebSocket多人聊天功能的示例

       composer 安装ratchet 使用PDO连接数据库,创建mysql命令如下 使用Redis存储消息列表 这个示例代码中,PHP代码使用Ratchet来创建WebSocket服务器,并实现了简单的聊天功能。HTML代码使用JavaScript来建立WebSocket连接,并处理消息传输和用户输入。要运行此代码,请确保已安装Ratchet并

    2024年02月11日
    浏览(43)
  • Springboot + Websocket的集成实现简单的聊天室功能

    WebSocket是一种网络通信协议,它可以在单个TCP连接上实现双向(全双工)通信。WebSocket使用HTML5标准,并且可以在客户端和服务器之间建立持久连接,这意味着连接在浏览器刷新或关闭后仍然保持打开状态。 WebSocket的主要优点包括: 1. 双向通信:WebSocket支持客户端和服务器之

    2024年03月21日
    浏览(47)
  • 微信小程序WebSocket实现stream流式聊天对话功能

    要在微信小程序实现聊天对话功能,回话是流式应答,这里使用了WebSocket技术。WebSocket大家应该都很熟悉,使用wx.connectSocket就可以了。这里可能需要注意下的是流式应答,后端如何发送,前端如何接收。直接上代码: 可以扫码体验: 后端关键代码: 小程序ts代码: 可以扫码

    2024年04月10日
    浏览(86)
  • uniapp+websocket聊天功能实现(超详细!!附代码,可直接复用)

    最近项目上用到了聊天的功能,下面来分享一下关于websocket,键盘弹出等问题,避免别的朋友踩坑。  接着进入正文了!!!!! 先看看整体的页面布局  system.windowHeight : 页面总高度 totalHeight:顶部导航栏高度 sendHeight:底部输入框高度 (设置样式的时候自己设置的) keybo

    2024年02月08日
    浏览(39)
  • 微信小程序 | 基于小程序+Java+WebSocket实现实时聊天功能

    此文主要实现在小程序内聊天对话功能,使用Java作为后端语言进行支持,界面友好,开发简单。 2.1、注册微信公众平台账号。 2.2、下载安装IntelliJ IDEA(后端语言开发工具),Mysql数据库,微信Web开发者工具。 1.创建maven project 先创建一个名为SpringBootDemo的项目,选择【New Proje

    2024年02月02日
    浏览(57)
  • SpringBoot和Vue2集成WebSocket,实现聊天室功能

    springboot集成websocket实现聊天室的功能。如有不足之处,还望大家斧正。

    2024年01月23日
    浏览(47)
  • thinkphp websocket 开发实时聊天系统的用户群组与订阅功能实现 (一)

    PHP开发实时聊天系统的用户群组与订阅功能实现 在当今社交互联网时代,实时聊天系统已经成为人们日常交流的重要工具。为了提供更好的用户体验,我们需要实现用户群组与订阅功能,使得用户能够方便地创建和加入群组,并且能够订阅感兴趣的内容。 本篇文章将介绍如

    2024年02月07日
    浏览(46)
  • webSocket及使用webSocket实现实时聊天通信

    webSocket在开始的时候依旧使用的是http协议,只不过后面保持tcp持久链接,是一种全双工通信。webSockets和http很像,它的请求url用的是ws、wss,对应http、https 初始化 npm init -y 安装ws依赖 npm i --save ws 写服务器代码 服务器启动 node server.js 配置前端代码,即告诉浏览器这个请求不要

    2023年04月11日
    浏览(41)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包