用WebSocket实现一个简易的群聊功能,so easy

简介: 本文主要来讲解如何使用WebSocket来实现一个简易的群聊功能。

大家好,我是三友~~

本文主要来讲解如何使用WebSocket来实现一个简易的群聊功能。

公众号:三友的java日记

引入maven依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <version>2.2.5.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-websocket</artifactId>
    <version>2.2.5.RELEASE</version>
</dependency>

搭建项目

项目的目录结构

image.png

接下来,我们来分析每个类的作用。

WebSocketApplication

@SpringBootApplication
public class WebSocketApplication {
   
   
    public static void main(String[] args) {
   
   
        SpringApplication.run(WebSocketApplication.class, args);
    }
}

这个类就是一个简单的启动引导类的功能。

WebSocketServer:群聊核心类

@Component
@ServerEndpoint(value = "/chat/{username}", configurator = SpringBasedConfigurator.class)
public class WebSocketServer {
   
   
    private final Map<Session, String> userSessionMap = new ConcurrentHashMap<>();

    @OnOpen
    public void onOpen(Session session, @PathParam("username") String username) {
   
   
        userSessionMap.put(session, username);
        multicastMessage(session, "欢迎" + username + "加入群聊!");
    }

    @OnMessage
    public void onMessage(Session session, String message) {
   
   
        String username = userSessionMap.get(session);
        multicastMessage(session, username + ": " + message);
    }

    @OnClose
    public void onClose(Session session) {
   
   
        String username = userSessionMap.remove(session);
        multicastMessage(session, username + "退出群聊。");
    }

    private void multicastMessage(Session session, String message) {
   
   
        for (Session userSession : userSessionMap.keySet()) {
   
   
            if (userSession == session) {
   
   
                //是自己,忽略
                continue;
            }
            try {
   
   
                userSession.getBasicRemote().sendText(message);
            } catch (IOException e) {
   
   
                e.printStackTrace();
            }
        }
    }
}

@ServerEndpoint:作用是用来表明当前类是一个节点类,当连接成功之后,用户的操作都会回调这个类对应的对象的方法,对象怎么创建的是根据configurator 属性对应的类来实现的,默认是每个连接对应的对象都是通过反射构建的,但是对于本群聊功能来说,是通过SpringBasedConfigurator对象来获取,这个类的作用接下来会剖析。

@OnOpen:当客户端与服务端建立连接的时候,会回调 @OnOpen 注解标记的方法

@PathParam:可以看成跟spring mvc中的@PathVariable注解作用一样,就是取出连接路径中的占位符对应的值

@OnMessage:当客户端发送消息给服务端的时候,会回调OnMessage 注解标记的方法

@OnClose:当客户端断开连接的时候,会回调@OnClose注解标记的方法。

Session:是代表当前客户端与服务端建立的一个会话,通过这个对象,服务端可以主动给客户端发送消息。

WebSocketServer这个类的主要作用是保存每个客户端与服务端建立的连接,一旦有客户端跟服务端建立连接、发送消息、断开连接,都会发送消息给其他客户端,从而实现群聊的功能。

SpringBasedConfigurator

@Component
public class SpringBasedConfigurator extends ServerEndpointConfig.Configurator implements ApplicationContextAware {
   
   

    private static ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
   
   
        SpringBasedConfigurator.applicationContext = applicationContext;
    }

    @Override
    public <T> T getEndpointInstance(Class<T> clazz) throws InstantiationException {
   
   
        return applicationContext.getBean(clazz);
    }

}

这个类是继承了WebSocket包提供的api ServerEndpointConfig.Configurator ,重写了 getEndpointInstance 方法,主要是因为WebSocket是通过调用getEndpointInstance方法来获取每个连接对应调用的对象, 而getEndpointInstance方法默认是通过直接通过反射构造的,而不是从spring容器获取连接对象,导致类中的像@Resource 这类注解无法生效,所以重写了getEndpointInstance方法,让每个连接对应调用的对象都是从spring容器中获取

WebSocketConfiguration:配置类

@Configuration
public class WebSocketConfiguration {
   
   

    /**
     * 这个类的主要注册每个加了{@link javax.websocket.server.ServerEndpoint}的 spring bean节点,这算是spring整合websocket的一个体现
     * 具体是怎么实现注册的,可以看看 {@link ServerEndpointExporter#afterSingletonsInstantiated()}方法的实现
     *
     * @return
     */
    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
   
   
        return new ServerEndpointExporter();
    }

}

暴露每个加@ServerEndpoint注解的spring bean,算是spring跟WebSocket整合的一处体现。

测试

好了,说完这些类的功能,那么开启测试吧。WebSocket客户端,我们使用https://www.idcd.com/tool/socket网站来模拟。

通过启动引导类来启动项目之后,我们输入 ws://localhost:8080/chat/sanyou, 建立一个连接,模拟一个客户端。

image.png

输入连接地址,点击连接,就会显示连接成功,username这里我们填sanyou,填什么都无所谓,相当于一个名字。

我们再建立一个连接,模拟另一个客户端。

image.png

第一个客户端就会显示这条信息。

image.png

接下来,就可以在发送栏往服务端发送消息,服务端会转给其他的客户端,实现群聊的功能,效果如下。

image.png

image.png

如果还想加入群聊,另外建立连接就行了,这样,一个简易的群聊功能就完成了。

以上就是本篇文章的全部内容,代码我已经上传到https://github.com/sanyou3/sanyou-parent.git 仓库上了,有更详细的注释,如有需要欢迎自行clone,同时如果你有什么不懂或者想要交流的地方,欢迎关注微信公众号来联系我,我们下篇文章再见。

PS:如果觉得这篇文章对你有帮助,欢迎大家关注公众号三友的java日记、分享、点赞、在看,感谢支持。

往期热门文章推荐

如何去阅读源码,我总结了18条心法

如何写出漂亮代码,我总结了45个小技巧

三万字盘点Spring/Boot的那些常用扩展点

三万字盘点Spring 9大核心基础功能

万字+20张图剖析Spring启动时12个核心步骤

1.5万字+30张图盘点索引常见的11个知识点

两万字盘点那些被玩烂了的设计模式

搜索关注公众号 三友的java日记 ,及时干货不错过,公众号致力于通过画图加上通俗易懂的语言讲解技术,让技术更加容易学习,回复 面试 即可获得一套面试真题。

相关文章
|
9月前
使用uniapp实现websocket聊天功能
使用uniapp实现websocket聊天功能
|
4月前
|
前端开发 JavaScript UED
探索Python Django中的WebSocket集成:为前后端分离应用添加实时通信功能
通过在Django项目中集成Channels和WebSocket,我们能够为前后端分离的应用添加实时通信功能,实现诸如在线聊天、实时数据更新等交互式场景。这不仅增强了应用的功能性,也提升了用户体验。随着实时Web应用的日益普及,掌握Django Channels和WebSocket的集成将为开发者开启新的可能性,推动Web应用的发展迈向更高层次的实时性和交互性。
124 1
|
14天前
|
弹性计算 JSON 自然语言处理
语音交互产品通过WebSocket协议对外提供实时语音流语音转写功能
阿里云智能语音交互产品通过WebSocket协议提供实时语音转写功能,支持长语音。音频流以Binary Frame上传,指令和事件为Text Frame。支持单声道、16 bit采样位数的PCM、WAV等格式,采样率8000Hz/16000Hz。可设置返回中间结果、添加标点、中文数字转阿拉伯数字,并支持多语言识别。服务端通过临时Token鉴权,提供外网和上海ECS内网访问URL。交互流程包括StartTranscription、StopTranscription指令及多种事件反馈。
|
6月前
|
人工智能 Go
Golang 搭建 WebSocket 应用(二) - 基本群聊 demo
Golang 搭建 WebSocket 应用(二) - 基本群聊 demo
58 1
|
6月前
|
Linux C++ Docker
【Azure 应用服务】App Service for Linux 中实现 WebSocket 功能 (Python SocketIO)
【Azure 应用服务】App Service for Linux 中实现 WebSocket 功能 (Python SocketIO)
|
7月前
|
前端开发 JavaScript API
探索Python Django中的WebSocket集成:为前后端分离应用添加实时通信功能
【7月更文挑战第17天】现代Web开发趋势中,前后端分离配合WebSocket满足实时通信需求。Django Channels扩展了Django,支持WebSocket连接和异步功能。通过安装Channels、配置设置、定义路由和消费者,能在Django中实现WebSocket交互。前端使用WebSocket API连接后端,实现双向数据流,如在线聊天功能。集成Channels提升Web应用的实时性和用户体验,适应实时交互场景的需求。**
250 6
|
6月前
|
JavaScript 前端开发 网络协议
WebSocket在Java Spring Boot+Vue框架中实现消息推送功能
在现代Web应用中,实时消息提醒是一项非常重要的功能,能够极大地提升用户体验。WebSocket作为一种在单个TCP连接上进行全双工通信的协议,为实现实时消息提醒提供了高效且低延迟的解决方案。本文将详细介绍如何在Java Spring Boot后端和Vue前端框架中利用WebSocket实现消息提醒功能。
283 0
|
9月前
|
前端开发
t-io websocket的聊天功能学习记录(二)
t-io websocket的聊天功能学习记录(二)
131 0
|
9月前
t-io websocket的聊天功能学习记录(一)
t-io websocket的聊天功能学习记录(一)
144 0
|
移动开发 监控 网络协议
基于Socket通讯(C#)和WebSocket协议(net)编写的两种聊天功能(文末附源码下载地址)
基于Socket通讯(C#)和WebSocket协议(net)编写的两种聊天功能(文末附源码下载地址)