首页 > 其他分享 >【SpringBoot】使用WebSocket做消息对话

【SpringBoot】使用WebSocket做消息对话

时间:2022-12-17 18:55:50浏览次数:45  
标签:websocket SpringBoot session 对话 import WebSocket message public name

Http协议只能客户端发送---服务器回复,

无法做到服务器主动向客户端发送消息,所以可以使用websocket来进行双向通道 发消息

 

研究了一下抖音 斗鱼的弹幕也是用的websocket,但是需要解密ws内容

可以使用拦截websocket 接管websocket的方式截取弹幕,做一个弹幕回复之类 游戏或者主播感谢回复 牛批哄哄的

 

 

后端:

pom载入websocket依赖

<!-- websocket -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-websocket</artifactId>
</dependency>

 

 

Springboot需要写个配置类

注入一个ServerEndpointExporter,该Bean会自动注册使用@ServerEndpoint注解申明的websocket endpoint

@Configuration
public class WebSocketConfig {

    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter();
    }



}

 

 

ws控制层各类事件处理和转发

package com.example.websocketdemo.websocket;

import cn.hutool.json.JSONObject;
import org.springframework.stereotype.Component;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

@ServerEndpoint("/websocket/{name}")//开启websocket
@Component
public class WebSocket {

    private String name;//建立用户
    private Session session;//当前链接

    private static Map<String,WebSocket> allClients = new HashMap<>();


//    用户连接事件
    @OnOpen
    public void onOpen(@PathParam("name")String name ,Session session){
        System.out.println("连接建立:" + name);
        this.name =name;
        this.session = session;

//        存入链接用户名字和session
        allClients.put(name,this);
    }


//    接收消息事件
    @OnMessage
    public void onMessage(Session session,String message){
        System.out.println(message);
        System.out.println("接收消息事件");

        String to = new JSONObject(message).getStr("toUser");//获取目标接收者
        String toMessage =new JSONObject(message).getStr("toMessage");//获取发送的内容
        WebSocket webSocket = allClients.get(to);//获取目标接收者websocket


//        判断目标接收者是否为空
        if (webSocket !=null){
            Session tosession = webSocket.getSession();//获取接收方session
//            若链接是打开状态
            if (tosession.isOpen()){
                tosession.getAsyncRemote().sendText(toMessage);//找到链接的另外一端然后发消息
            }
        }else {
            session.getAsyncRemote().sendText("对方不在线");
        }



    }


//    关闭连接事件
    @OnClose
    public  void  OnClose(){
        System.out.println("关闭连接事件");
        allClients.remove(this.name);//清除掉已退出的用户
    }


    //    出现异常事件
    @OnError
    public void one rror(Throwable e){
        System.out.println("出现异常事件");
    }

    public String getName() {
        return name;
    }

    public Session getSession() {
        return session;
    }

    public static Map<String, WebSocket> getAllClients() {
        Set<String> strings = allClients.keySet();
        for (String string : strings) {

        }
        return allClients;
    }


//    获取所有key
    public static ArrayList<String> getKey(){
        ArrayList<String> strings = new ArrayList<>();

        Set<String> keys = allClients.keySet();
        for (String string : keys) {
            strings.add(string);
        }
        return strings;
    }

}

 

 

前端:

一个简单的连接和对话页面,直接静态打开就能run

判断浏览器有没有WebSocket环境(一般都自带了 没有就是浏览器太垃圾 直接换)

需要注册一个WebSocket对象,和后端一样有各类事件触发


<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script type="text/javascript">
        function start() {
            alert(document.location.host)
        }

        var websocket = null;


        function connection() {
            var username = document.getElementById("name").value;
            if ('WebSocket' in window) {
                websocket = new WebSocket('ws://127.0.0.1:8080/websocket/' + username);

            } else {
                alert("当前浏览器没有WebSocket环境")
            }


            websocket.onopen = function () {
                document.getElementById("message").innerHTML = "链接已建立"
            };


            websocket.onmessage = function (event) {
                var data = event.data;
                document.getElementById("message").innerHTML = data;

            };

            websocket.onerror = function () {
                document.getElementById("message").innerHTML = "出现异常"
            };

            websocket.onclose = function () {
                document.getElementById("message").innerHTML = "链接已关闭"
            };


            // 监听窗口关闭事件
            window.onbeforeunload = function () {
                if (websocket != null) {
                    websocket.close()
                }
            }


        }

        // 发送
        function sendMessage() {
            var toUser = document.getElementById("toUser").value;
            var toMessage = document.getElementById("toMessage").value;

            if (websocket != null) {
                var message = '{"toUser":"' + toUser + '","toMessage":"' + toMessage + '"}';
                websocket.send(message);
            }

        }
    </script>
</head>

<body>
    <input type="text" id="name">
    <button onclick="connection()">链接</button><br>
    接收者:<input type="text" id="toUser"><br>
    内容:<input type="text" id="toMessage"><br>
    <button onclick="sendMessage()">发送</button>


    <span id="message"></span>

</body>

</html>

 

标签:websocket,SpringBoot,session,对话,import,WebSocket,message,public,name
From: https://www.cnblogs.com/Hello233/p/16989345.html

相关文章

  • springboot启动读取配置文件过程&自定义配置文件处理器
        最近看到看到spring的配置文件放在了resources/config/application.yal文件内部,第一次见。就想的研究下,springboot启动读取配置文件的过程。1.启动过程org.spring......
  • javaclient操作kafka&springboot整合kafka&kafka分区
    1.javaclient测试kafka1.配置kafka允许远程推送修改config/Kraft/server.properties文件,,将地址变为服务器公网IP地址。advertised.listeners=PLAINTEXT://localhost:90......
  • SpringBoot注解~@PropertySource
    1.@PropertySourceSpringBoot读取配置信息的方式有以下几种。但实际开发中一个配置文件是不够用的,比如项目中集成mongorediskafka等需要多个配置文件,这样有利于开发以......
  • SpringBoot启动流程
    1.简述Springboot启动是通过Application启动类实现@SpringBootApplication(exclude={MongoAutoConfiguration.class,MongoDataAutoConfiguration.class},......
  • 【SpringBoot】Spring Data Redis封装和Spring Cache
    一、参考资料​​RedisUtil:最全的Java操作Redis的工具类,使用StringRedisTemplate实现,封装了对Redis五种基本类型的各种操作!​​​​SpringCache-简书​​​​redis分布......
  • 【SpringBoot】封装自定义的starter
    一、参考资料​​SpringBoot封装自己的Starter-码农教程​​​​[Gradle]发布构件到本地仓库​​​​Gradle插件之maven-publish:发布androidlibrary到maven仓库-知乎......
  • SpringBoot2.x 优秀开源项目
    前后端分离vue开源项目:项目名开源地址eladmin-web​​https://gitee.com/elunez/eladmin-web​​eladmin​​https://gitee.com/elunez/eladmin​​RuoYi-Vue​​https://gi......
  • 阿里云服务器部署springboot项目
    一、安装jdk​​安装jdk​​二、安装mysql下载安装包:​​​rpm-ivhhttp://dev.mysql.com/get/mysql57-community-release-el7-8.noarch.rpm​​设置开机自启动:​​​yum......
  • SpringBoot(六):配置文件的位置以及优先级
    SpringApplication 从以下位置的 application.properties 文件中加载属性(properties),并将它们添加到Spring Environment 中:项目目录的 /config 子目录项目目录的......
  • 如何在SpringBoot中优雅地重试调用第三方API?
    前言作为后端程序员,我们的日常工作就是调用一些第三方服务,将数据存入数据库,返回信息给前端。但你不能保证所有的事情一直都很顺利。像有些第三方API,偶尔会出现超时。此时,......