SpringBoot实战之整合WebSocket之群聊

SpringBoot实战之整合WebSocket

前言

Springboot版本:2.3.5.RELEASE
开发工具:idea2019.1
maven版本:3.5.4版本

一、WebSocket简介

WebSocket protocol是HTML5一种新的协议。它实现了浏览器与服务器全双工通信。一开始的握手需要借助HTTP请求完成。

二、WebSocket原理

网站上的即时通讯是很常见的,比如网页的QQ,微信等。按照以往的技术能力通常是采用轮询等技术解决。HTTP协议是非持久化的,单向的网络协议,在建立连接后只允许浏览器向服务器发出请求后,服务器才能返回相应的数据。当需要即时通讯时,通过轮询在特定的时间间隔(如1秒),由浏览器向服务器发送Request请求,然后将最新的数据返回给浏览器。
缺点:会导致过多不必要的请求,浪费流量和服务器资源,每一次请求、应答,都浪费了一定流量在相同的头部信息上,
而在WebSocket中,只需要服务器和浏览器通过HTTP协议进行一个握手的动作,然后单独建立一条TCP的通信通道进行数据的传送。
WebSocket同HTTP一样也是应用层的协议,但是它是一种双向通信协议,是建立在TCP之上的。广泛被用来做即时通讯,以替代轮询。

图型理解大概这样,连接成功后,会持久保持连接,双向传递信息,直到客户端断开连接。
在这里插入图片描述

三、WebSocket特点

WebSocket协议的URL有两种模式,分别为ws和wss,对应http协议中的http和https。
特点如下:

  • WebSocket使用时需要先建立连接,是一种有状态的协议,在之后的通信过程中可以省略部分状态信息(例如身份认证等);
  • WebSocket连接端口在80(ws)和443(wws)上创建,与http端口相同,基本上防火墙都不会阻止WebSocket连接;
  • 心跳消息(ping和pong)将被反复发送,进而保持WebSocket连接一致出于活跃中台。(送方->接收方:ping 接收方->发送方:pong)
  • WebSocket连接关闭时将发送一个特殊的关闭消息;
  • WebSocket支持跨域,可以便面Ajax的限制;
  • WebSocket协议支持扩展,用户可以扩展协议,实现部分自定义的子协议。

四、WebSocket应用场景

  • 在线股票网站
  • 即时聊天
  • 多人在线游戏
  • 应用集群通信
  • 系统性能监控

五、SpringBoot整合WebSocket实战

1、创建项目,添加依赖

<?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/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.5.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.yangxf</groupId>
    <artifactId>demoWebSocket</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>demoWebSocket</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <!--websocket依赖包-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-websocket</artifactId>
        </dependency>
        <!--websocket前段依赖包-->
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>webjars-locator-core</artifactId>
        </dependency>
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>sockjs-client</artifactId>
            <version>1.1.2</version>
        </dependency>
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>stomp-websocket</artifactId>
            <version>2.3.3</version>
        </dependency>
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>jquery</artifactId>
            <version>3.3.1</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

2、添加配置类

package com.yangxf.demoWebSocket.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;

/**
 * 〈一句话功能简述〉<br> 
 * 〈WebSocket的配置类〉
 *
 * @author linwd
 * @create 2021/4/5
 * @since 1.0.0
 */
@Configuration
@EnableWebSocketMessageBroker//开启WebSocket的消息代理
public class WebSocketConfig  implements WebSocketMessageBrokerConfigurer {
    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry) {
        /**
         * 设置消息代理的前缀
         * 即如果消息前缀是/topic,就会将消息转给消息代理,再有消息代理广播给当前连接的客户端;
         */
        registry.enableSimpleBroker("/topic");
        /**
         * 表示配置一个或多个前缀,通过这些前缀过滤出需要被注解处理的消息
         */
        registry.setApplicationDestinationPrefixes("/app");
    }
    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        /**
         * 定义一个前缀为“/chat”的endPoint
         */
        registry.addEndpoint("/chat").withSockJS();
    }

}

3、添加控制器以及封装对象

/**
 * FileName: HelloController
 * Author:   linwd
 * Date:     2021/4/5 12:07
 * Description: 测试控制器
 * History:
 * <author>          <time>          <version>          <desc>
 * 作者姓名           修改时间           版本号              描述
 */
package com.yangxf.demoWebSocket;

import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.web.bind.annotation.RestController;

/**
 * 〈一句话功能简述〉<br>
 * 〈测试控制器〉
 *
 * @author linwd
 * @create 2021/4/5
 * @since 1.0.0
 */
@RestController
public class HelloController {

    @MessageMapping("/hello")
    @SendTo("/topic/greetings")
    public Message greetings(Message message) throws Exception {
        return message;
    }
}



public class Message {
    private String name;
    private String context;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getContext() {
        return context;
    }

    public void setContext(String context) {
        this.context = context;
    }

    public Message() {
    }
}


4、添加前台html以及js

resource目录下添加static文件夹,文件夹下创建html以及js

  • 添加html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>群聊</title>
    <script src="/webjars/jquery/jquery.min.js"></script>
    <script src="/webjars/sockjs-client/sockjs.min.js"></script>
    <script src="/webjars/stomp-websocket/stomp.min.js"></script>
    <script src="/app.js"></script>
</head>
<body>
<div>
    <label for="name">请输入用户名:</label>
    <input type="text" id="name" placeholder="用户名">
</div>
<div>
    <button id="connect" type="button">连接</button>
    <button id="disconnect" type="button" disabled="disabled">断开连接</button>
</div>
<div id="chat" style="display: none;">
</div>
<div>
    <label for="context">请输入聊天内容:</label>
    <input type="text" id="context" placeholder="聊天内容">
</div>
<button id="send" type="button">发送</button>
<div id="conversation" style="display: none;">
    群聊进行中...
</div>
<div id="greetings" >
</div>

</body>
</html>

  • 添加js
var stompClient=null;
function sendConnected(connected) {
    $("#connect").prop("disabled",connected);
    $("#disconnect").prop("disabled",!connected);
    if(connected){
        $("#conversation").show();
        $("#chat").show();
    }else{
        $("#conversation").hide();
        $("#chat").hide();
    }
    $("#greetings").html("");
}

/**
 * 连接事件
 */
function connect() {
    if(!$("#name").val()){
        return;
    }

    var socket=new SockJS("/chat");
    stompClient=Stomp.over(socket);
    stompClient.connect({},function (frame) {
        sendConnected(true);
        stompClient.subscribe("/topic/greetings",function (greeting) {
            showGreeting(JSON.parse(greeting.body));
        });
    });
}

function disconnect() {
    if(stompClient!=null){
        stompClient.disconnect();
    }
    sendConnected(false);
}

function sendName() {
    stompClient.send("/app/hello",{},JSON.stringify({'name':$("#name").val(),'context':$("#context").val()}));
}

function showGreeting(message) {
    $("#greetings").append("<div>"+message.name+":"+message.context+"</div>");
}

$(function () {
    $("#connect").click(function() {connect();});
    $("#disconnect").click(function() {disconnect();});
    $("#send").click(function() {sendName();});

});

5、测试验证

可以看出简单的qq聊天
登录成功后,可以跟别人聊天,然后退出qq,就断开连接。

在这里插入图片描述

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
要在Spring Boot整合WebFlux并实现WebSocket服务器,可以按照以下步骤进行操作: 1. 创建一个Spring Boot项目:使用Spring Initializr或手动创建一个基于Spring Boot的项目。 2. 添加依赖:在项目的pom.xml(Maven)或build.gradle(Gradle)文件中添加以下依赖项: ```xml <!-- Spring Boot WebFlux --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-webflux</artifactId> </dependency> <!-- Spring Boot WebSocket --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency> ``` 3. 创建WebSocket处理器:创建一个WebSocket处理器类,实现`WebSocketHandler`接口。该处理器将处理WebSocket连接的打开、关闭以及消息传递等操作。 ```java import org.springframework.web.reactive.socket.WebSocketHandler; import org.springframework.web.reactive.socket.WebSocketMessage; import org.springframework.web.reactive.socket.WebSocketSession; import reactor.core.publisher.Mono; public class MyWebSocketHandler implements WebSocketHandler { @Override public Mono<Void> handle(WebSocketSession session) { // 处理WebSocket连接的逻辑 return session.send( session.receive() .map(WebSocketMessage::getPayloadAsText) .map(session::textMessage) ); } } ``` 4. 配置WebSocket路由:创建一个配置类,配置WebSocket的路由和处理器。 ```java import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.reactive.config.EnableWebFlux; import org.springframework.web.reactive.config.WebFluxConfigurer; import org.springframework.web.reactive.handler.SimpleUrlHandlerMapping; import org.springframework.web.reactive.socket.server.support.WebSocketHandlerAdapter; import java.util.HashMap; import java.util.Map; @Configuration @EnableWebFlux public class WebSocketConfig implements WebFluxConfigurer { @Bean public WebSocketHandlerAdapter handlerAdapter() { return new WebSocketHandlerAdapter(); } @Bean public SimpleUrlHandlerMapping handlerMapping() { Map<String, WebSocketHandler> map = new HashMap<>(); map.put("/websocket", new MyWebSocketHandler()); SimpleUrlHandlerMapping mapping = new SimpleUrlHandlerMapping(); mapping.setOrder(1); mapping.setUrlMap(map); return mapping; } } ``` 5. 启动应用程序:启动Spring Boot应用程序,WebSocket服务器将在`/websocket`路径下监听连接。 现在,你已经成功地在Spring Boot整合了WebFlux并实现了一个简单的WebSocket服务器。你可以使用前端代码(如JavaScript)来连接并测试WebSocket服务器。希望对你有所帮助!如果有任何问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lwd2307997664

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值