Spring Boot WebSocket 笔记

本文仓库地址:chat01

一、网页技术发展过程

一开始的网页是静态的html页面,不能进行交互,随后javascript出现,在一定程度上实现了页面的简单交互。不过javascript不能和服务端交互,随后ajax的出现解决了与服务端交互的问题,ajax存在的不足——所有的请求都是由客户端发起的,服务端进行响应,若服务端有最新的消息,则难以发送到客户端去,不过我们一直存在这种实时通讯的需求。
在没有WebSocket之前的解决方案:
一、轮询:客户端每隔一定时间去服务端查询有没有数据
存在的问题:
会有大量的无效请求,服务端的资源被大大浪费掉了
二、长连接:去服务端查询的时候如果服务端没有数据就不响应,等有数据了再响应。
存在的问题:
①:浏览器如果在服务端响应之前有新的请求发送,就只能新建一个并发请求(或者把旧的请求断掉,重新发请求)。因为前一个请求被服务端持有,没有被释放,请求收不回来。
②:无论是tcp还是http都有连接超时说法,服务端与客户端之间连接需要定时关闭再连接。
三、Applet和Flash:都能够解决消息推送问题,不过需要浏览器支持javafalsh,同时这两种技术都存在安全问题(目前被废弃)。

WebSocket
利用HTTP1.1版本的升级特性Connection: upgrade,正常发送HTTP请求,请求头里面没有这个东西。
当浏览器发送WebSocket请求前需要建立WebSocket连接,首先发送一个HTTP请求,在这个HTTP请求头里面带上Connection: upgrade告诉服务器要进行请求协议升级,服务端会检查是否支持客户端需要升级的协议,若支持会返回给客户端一个101状态码,表示转换请求协议,从而实现HTTP请求向WebSocket请求的转换。
优势:
一、由于是用HTTP请求建立连接的,默认端口也是80和443,默认情况下不会被防火前拦截,不需要我们进行额外配置
二、使用HTTP协议进行握手,可以自然地集成到网络浏览器的HTTP服务器中
三、通信数据轻量,性能开销小,同行效率高
四、支持跨域

实际应用场所:聊天、多人在线游戏、股票网站、高清视频…

二、WebSocket群聊Demo

一、新建Spring Boot项目,引入依赖:
在这里插入图片描述
二、利用webjars在Maven中引入前端库(也可以使用导入js的方式)
可以Maven仓库中搜索,导入pom坐标,这些前端库将以jar包的形式出现在咱们的项目里边,实际上用webjars本质上也是用jar包里边的js文件,只不过用导入Maven依赖的方式方便统一管理,此处附上依赖:

<!--        前端依赖-->
        <!-- https://mvnrepository.com/artifact/org.webjars/sockjs-client -->
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>sockjs-client</artifactId>
            <version>1.1.2</version>
        </dependency>
<!--        stomp可操作协议 兼容性更好-->
        <!-- https://mvnrepository.com/artifact/org.webjars/stomp-websocket -->
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>stomp-websocket</artifactId>
            <version>2.3.3</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.webjars/jquery -->
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>jquery</artifactId>
            <version>3.5.1</version>
        </dependency>
        <!--定位器-->
        <!-- https://mvnrepository.com/artifact/org.webjars/webjars-locator-core -->
        <dependency>
            <groupId>org.webjars</groupId>
            <artifactId>webjars-locator-core</artifactId>
        <!--            <version>0.48</version>-->
        </dependency>

三、application.yml文件中配置服务端口:

server:
  port: 7723

四、创建配置类WebSocketConfig配置WebSocket:

@Configuration
@EnableWebSocketMessageBroker //开启WebSocket消息代理
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {

    //注册端点用
    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        //定义了一个前缀为chat的endpoint,提供了对SockJS的支持
        registry.addEndpoint("/chat").setAllowedOrigins("http://localhost:7723").withSockJS();
    }

    //配置消息代理
    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry) {
        //消息代理前缀为topic
        registry.enableSimpleBroker("/topic","/queue");
    }
}

五、创建信息实体类:

@Data
public class Message {
    private String name;
    private String content;
}

六、创建聊天控制类

@Controller
public class GreetingController {
    //发消息用
    @Autowired
    SimpMessagingTemplate simpMessagingTemplate;
    //客户端消息往@MessageMapping地址上发
    //前端页面根据@SendTo定义监听地址 (广播地址)
    @MessageMapping("/hello")
    @SendTo("/topic/greetings")
    public Message greeting(Message message) {
        System.out.println("message ="+message);
        return message;
    }
}

七、在static目录下创建chat.html页面:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="/webjars/jquery/3.5.1/jquery.js"></script>
    <script src="/webjars/sockjs-client/1.1.2/sockjs.min.js"></script>
    <script src="/webjars/stomp-websocket/stomp.min.js"></script>
</head>
<body>

<div>
<label for="username">请输入用户名:</label>
    <input type="text" id="username" placeholder="用户名">
</div>

<div>
    <input type="button" value="连接" id="connect">
    <input type="button" value="断开连接" id="disconnect" disabled="disabled">
</div>

<div id="chat"></div>

<div>
<label for="content">请输入聊天内容</label>
<input type="text" id="content" placeholder="聊天内容">
</div>


<input value="发送" type="button" id="send" disabled="disabled">发送</input>
<script type="text/javascript">
    //全部加载完毕之后再执行js
    //定义全部变量
    var stompClient;
    $(function () {
        $("#connect").click(function () {
            //在点击事件内部定义一个方法,完成websocket联接
            connect();
            $("#send").click(function () {
                stompClient.send('/hello',{},JSON.stringify({'name':$("#username").val(),'content':$("#content").val()}))
            })
            $("#disconnect").click(function () {
                stompClient.disconnect();
                setConnect(false);
            })
        })

    });

    function connect() {
        //首先判断是否输入用户名
        if (!$("#username").val()) {
            //若没有用户名 直接return
            return;
        }
        //若填了用户名,就建立websocket连接 填写服务端的注册端点
        var sockJS = new SockJS("/chat");
        stompClient = Stomp.over(sockJS);
        // 参数一 建立连接用的参数,可以不用给 参数二 连接成功之后的回调函数
        stompClient.connect({}, function (frame) {
            setConnect(true);
            //监听服务端发回来的消息
            console.log("调用之前")
            stompClient.subscribe("/topic/greetings",function (greeting) {
                //将json字符串转换成json对象

                var msgContent = JSON.parse(greeting.body);
                console.log("msgContent:"+msgContent);
                $("#chat").append("<div>"+msgContent.name+':'+msgContent.content+"</div>");
            })
        })
    }

    function setConnect(connected) {
        console.log("connected状态:"+connected)
        //设置按钮状态
        $("#connect").prop("disabled", connected);
        $("#disconnect").prop("disabled", !connected);
        $("#send").prop("disabled", !connected);
    }
</script>
</body>
</html>

八、运行测试:
若使用Chrome浏览器测试,可以使用添加用户的形式来模拟不同的用户:
在这里插入图片描述
在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值