SpringBoot中webSocket实现即时聊天

即时聊天

这个使用了websocket,在springboot下使用很简单。前端是小程序,这个就比较坑,小程序即时聊天上线需要域名并且使用wss协议,就是ws+ssl更加安全。但是要上线这还不够,你必须为企业主体开发者。个人开发者即时聊天属于社交、不在服务类目内,审核会不通过!!!

功能 :我们的小程序是个二手交易小程序,即时聊天对于一个后台服务器只是单核2g的来说有点抗不住。所以在双方都在线的时候没有存储聊天消息,只是在单方不在线时存储了离线消息。而且只能发三条离线消息。仿照了csdn的聊天。

使用:我们是点击进入聊天之后才发起websocket,这就造成了一个问题,就是用户退出到消息列表又重新点进入就会重新发送一个websocket请求。每次请求session都不一样。而且微信限制一个用户只能同时发起5个请求。一开始前端没能退出聊天页面就端开,就错误唉!!。只能后台去断使用sessioin.close()会调用onClose()方法 这个session是你要断的session。不过后来前端可以自己断了就nice了!

效果:

数据库设计:

对于展示消息聊天列表使用了一张表。last_context为对方发送的最后一条消息。只要有一方点击了私信进入聊天页面就会往表中插入两条记录。方便之后删除聊天,毕竟一方删除不能让另一方也看不到信息

对于消息详细离线内容,则使用了另外一张表。

后台代码:

package com.w.wx.controller.WebSocket;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.w.wx.domain.ChatMessage;
import com.w.wx.service.ChatService;
import com.w.wx.utils.ALToHMUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

@Slf4j
@ServerEndpoint("/wx/{fromOpenid}/{toOpenid}")
@Component
public class WebSocketServer {

    public static WebSocketServer webSocketServer;
    @Autowired
    private ChatService chatService;

    @PostConstruct        //此注解的方法在bean加载前执行
    private void init() {
        webSocketServer = this;
        //初始化时将静态化的interFaceInfoMapper进行了实例化
        webSocketServer.chatService = this.chatService;
    }

	 //静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
    private static AtomicInteger onlineNum = new AtomicInteger();

    //concurrent包的线程安全HashMap,用来存放每个客户端对应的WebSocketServer对象。
    private static ConcurrentHashMap<String, Session> sessionPools = new ConcurrentHashMap<>();

    //发送消息
    public void sendMessage(Session session, ChatMessage message) throws IOException {
        if(session != null){
            synchronized (session) {

                String s = JSONObject.toJSONString(message);
                System.out.println("52 发送数据:" + s);
                session.getBasicRemote().sendText(s);
            }
        }
    }
    //给指定用户发送信息
    public void sendInfo(String to_openid, ChatMessage message){
        Session session = sessionPools.get(to_openid);

        if(session == null){
            webSocketServer.chatService.addDeInfo(message);
        }else{
            try {
                sendMessage(session, message);
            }catch (Exception e){
                e.printStackTrace();
            }
        }

    }
    // 群发消息
    public void broadcast(ChatMessage message){
    	for (Session session: sessionPools.values()) {
            try {
                sendMessage(session, message);
            } catch(Exception e){
                e.printStackTrace();
                continue;
            }
        }
    }

    //收到客户端信息后,根据接收人的username把消息推下去或者群发
    // to=-1群发消息
    @OnMessage
    public void onMessage(String message) throws IOException{
        ChatMessage msg=JSON.parseObject(message, ChatMessage.class);
        sessionPools.get(msg.getToOpenid());

        webSocketServer.chatService.addInfo(message);

        if (msg.getToOpenid().equals("-1")) {
            broadcast(msg);
        } else {
            sendInfo(msg.getToOpenid(),msg);
        }

    }

    //建立连接成功调用
    @OnOpen
    public void onOpen(Session session, @PathParam(value = "fromOpenid") String fromOpenid,@PathParam(value = "toOpenid") String toOpenid) throws IOException {

        ArrayList<ChatMessage> list = webSocketServer.chatService.getAllNotRead(fromOpenid,toOpenid);
        if (!list.isEmpty()) {
            Iterator<ChatMessage> it = list.iterator();
            while (it.hasNext()) {
                ChatMessage chatMessage = it.next();
                chatMessage.setContent(ALToHMUtil.toUnicode(chatMessage.getContent()));
                sendMessage(session, chatMessage);
                log.info("115 当前用户接收离线消息" + chatMessage.toString());
            }
        }

        sessionPools.put(fromOpenid, session);

        addOnlineCount();
        System.out.println("125 "+fromOpenid + "加入webSocket!当前人数为" + onlineNum);

    }

    //关闭连接时调用
    @OnClose
    public void onClose(@PathParam(value = "fromOpenid") String fromOpenid) throws IOException {

        Session session = sessionPools.get(fromOpenid);

        session.close();
        sessionPools.remove(fromOpenid);

        subOnlineCount();
        System.out.println(fromOpenid + "断开webSocket连接!当前人数为" + onlineNum);

    }
    //错误时调用
    @OnError
    public void onError(Session session, Throwable throwable){
       // System.out.println("发生错误");
        throwable.printStackTrace();
    }

    public static void addOnlineCount(){
        onlineNum.incrementAndGet();
    }

    public static void subOnlineCount() {
        onlineNum.decrementAndGet();
    }

    public static AtomicInteger getOnlineNumber() {
        return onlineNum;
    }

    public static ConcurrentHashMap<String, Session> getSessionPools() {
        return sessionPools;
    }
}

到此这篇关于SpringBoot中webSocket实现即时聊天的文章就介绍到这了,更多相关SpringBoot中webSocket实现即时聊天内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Springboot+WebSocket实现一对一聊天和公告的示例代码

    1.POM文件导入Springboot整合websocket的依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> <version>2.1.6.RELEASE</version> </dependency> 2.注册WebSocket的

  • SpringBoot+Websocket实现一个简单的网页聊天功能代码

    最近做了一个SpringBoot的项目,被SpringBoot那简介的配置所迷住.刚好项目中,用到了websocket.于是,我就想着,做一个SpringBoot+websocket简单的网页聊天Demo. 效果展示: 当然,项目很简单,没什么代码,一眼就能明白 导入websocket的包. 通过使用SpringBoot导入包的时候,我们可以发现,很多包都是以 spring-boot-starter 开头的,对于我这种强迫症 ,简直是福音 <dependency> <groupId>

  • Springboot基于websocket实现简单在线聊天功能

    添加maven依赖 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM

  • SpringBoot+WebSocket搭建简单的多人聊天系统

    前言 今天闲来无事,就来了解一下WebSocket协议.来简单了解一下吧. WebSocket是什么 首先了解一下WebSocket是什么?WebSocket是一种在单个TCP连接上进行全双工通信的协议.这是一种比较官方的说法,简单点来说就是,在一次TCP连接中,通信的双方可以相互通信.比如A和B在打电话,A说话的时候,B也可以说话来进行信息的交互,这就叫做全双工通信.对应的是单工通信,和半双工通信,单工通信就是只能由A向B通信,比如电脑和打印机.半双工通信是可以AB可以互相通信,但是同一时间只

  • SpringBoot中webSocket实现即时聊天

    即时聊天 这个使用了websocket,在springboot下使用很简单.前端是小程序,这个就比较坑,小程序即时聊天上线需要域名并且使用wss协议,就是ws+ssl更加安全.但是要上线这还不够,你必须为企业主体开发者.个人开发者即时聊天属于社交.不在服务类目内,审核会不通过!!! 功能 :我们的小程序是个二手交易小程序,即时聊天对于一个后台服务器只是单核2g的来说有点抗不住.所以在双方都在线的时候没有存储聊天消息,只是在单方不在线时存储了离线消息.而且只能发三条离线消息.仿照了csdn的聊天.

  • SpringBoot整合websocket实现即时通信聊天

    目录 一.技术介绍 1.1 客户端WebSocket 1.1.1 函数 1.1.2 事件 1.2 服务端WebSocket 二.实战 2.1.服务端 2.1.1引入maven依赖 2.1.2 编写配置类 2.1.3 编写WebSocketService服务类 2.1.4 建立连接 2.1.5 关闭连接 2.1.6 发送消息 2.1.7 监听错误 2.2 客户端 2.2.1 主页面 2.2.1 聊天页面 三.开源地址 四.参考文献 一.技术介绍 线上演示地址:http://chat.breez.w

  • springboot中websocket简单实现

    目录 websocket简单实现 引入依赖包 实现WebSocketHandler 接口重写相关方法. websocket简单实现 websocket是HTML5下一种新的协议,本质上websocket是一个基于tcp的协议.它实现了浏览器与服务器之间的双向通信,能更好的节省服务器资源和宽带并实现实时的通信.websocket的几个优点?1.使用的资源少,因为它的头更小.2.实时性更强:服务端可以通过连接主动向客户端推送消息.3.有状态:开启连接之后可以不用每次都携带状态信息. 下面介绍spri

  • 基于Node.js + WebSocket打造即时聊天程序嗨聊

    前端一直是一块充满惊喜的土地,不仅是那些富有创造性的页面,还有那些惊赞的效果及不断推出的新技术.像node.js这样的后端开拓者直接将前端人员的能力扩大到了后端.瞬间就有了一统天下的感觉,来往穿梭于前后端之间代码敲得飞起,从此由前端晋升为'前后端'. 本文将使用Node.js加web socket协议打造一个网页即时聊天程序,取名为HiChat,中文翻过来就是'嗨聊',听中文名有点像是专为寂寞单身男女打造的~ 其中将会使用到express和socket.io两个包模块,下面会有介绍. 源码 源码

  • 微信小程序websocket实现即时聊天功能

    今天给大家分享一下本人做小程序使用websocket的一点小经验,希望对大家有所帮助. 使用之前肯定首先要了解一下websocket是什么,简单来讲websocket就是客户端与服务器之间专门建立的一条特殊通道,请求只需要请求一次,而且还可以从通道实时获取服务器数据,非常适合应用到实时应用上. 因为这里本人是分享小程序,所以就不去深究websocket的底层和协议了,感兴趣的朋友可以去看下websocket协议 建议大家在做之前先看看微信小程序官方提供的api关于websocket的文档,因为微

  • 使用WebSocket实现即时通讯(一个群聊的聊天室)

    随着互联网的发展,传统的HTTP协议已经很难满足Web应用日益复杂的需求了.近年来,随着HTML5的诞生,WebSocket协议被提出,它实现了浏览器与服务器的全双工通信,扩展了浏览器与服务端的通信功能,使服务端也能主动向客户端发送数据. 传统的HTTP协议是无状态的,每次请求(request)都要由客户端(如浏览器)主动发起,服务端进行处理后返回response结果,而服务端很难主动向客户端发送数据:这种客户端是主动方,服务端是被动方的传统Web模式对于信息变化不频繁的Web应用来说造成的麻烦

  • SpringBoot实现WebSocket即时通讯的示例代码

    目录 1.引入依赖 2.WebSocketConfig 开启WebSocket 3.WebSocketServer 4.测试连接发送和接收消息 5.在线测试地址 6.测试截图 1.引入依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency>

  • SpringBoot+WebSocket实现即时通讯的方法详解

    目录 环境信息 服务端实现 导入依赖 创建配置类 创建一个注解式的端点并在其中通过配套注解声明回调方法 服务端主动发送消息给客户端 客户端实现 Java客户端实现 在前端环境(vue)中使用websocket 环境信息 名称 版本号 Spring Boot 2.4.5 Idea 2021.3.2 服务端实现 导入依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>sp

  • Java中使用websocket实现在线聊天功能

    很早以前为了快速达到效果,使用轮询实现了在线聊天功能,后来无意接触了socket,关于socket我的理解是进程间通信,首先要有服务器跟客户端,服务的启动监听某ip端口定位该进程,客户端开启socket分配ip端口连接服务端ip端口,于是两个进程间便可以通信了.下面简单画个图理解. but,今天还是准备分享websocket的使用,先上效果,再贴代码. 第一步启动socket服务. 然后连接客户端连接服务器,加入聊天室,分别使用googel(白玉京,沈浪),火狐(楚留香),ie(李寻欢)进行测试

随机推荐