it编程 > 编程语言 > Javascript

springboot项目跟JavaScript简单websocket使用方式

7人参与 2026-01-31 Javascript

websocket 简绍

websocket 是一种在单个 tcp 连接上进行全双工通信的协议。websocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。

在 websocket api 中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。

websocket 的优势包括

创建更丰富的交互体验:实时更新数据的能力,使得应用能够更加流畅地响应用户的动作

可以通过 javascript 的 websocket 对象来创建一个 websocket 连接。

var ws = new websocket('ws://localhost:8080');

javascript 设置

处理事件

websocket 对象提供了几个事件处理器来处理连接的状态变化:

<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>websocket example</title>
    <script>
        document.addeventlistener('domcontentloaded', function () {
            const socket = new websocket('ws://localhost:8080/websocket');

            socket.onopen = function (event) {
                console.log('websocket connection established.');
            };

            socket.onmessage = function (event) {
                console.log('received from server:', event.data);
            };

            socket.onclose = function (event) {
                console.log('websocket connection closed.');
            };

            socket.onerror = function (error) {
                console.error('websocket error:', error);
            };

            function sendmessage() {
                let message = document.getelementbyid('message').value;
                socket.send(message);
                console.log('sent message:', message);
            }
        });
    </script>
</head>
<body>
    <input type="text" id="message" placeholder="type your message here">
    <button onclick="sendmessage()">send message</button>
</body>
</html>

确保你的服务器端已正确配置,并且能够接收来自客户端的连接请求。

使用https和wss(加密的websocket)可以提高安全性,特别是在生产环境中。

如果你的服务器部署在不同的域上,请确保服务器配置允许跨域访问。

java 服务端设置

导jar包

通过 maven 导入 spring boot 中 集成的 websocket jar 包

<dependency>
    <groupid>org.springframework.boot</groupid>
    <artifactid>spring-boot-starter-websocket</artifactid>
</dependency>

创建websocket端点

@enablewebsocket

@enablewebsocket 是 spring 框架中的一个注解,用于启用 websocket 支持。当一个类被标记为此注解时,spring 会自动配置必要的组件来处理 websocket 请求。这个注解通常应用在一个配置类上,该类负责设置 websocket 的处理逻辑。

registerwebsockethandlers

接下来,定义一个websocket处理器类,并配置一个端点来接受websocket连接:

import org.springframework.context.annotation.configuration;
import org.springframework.web.socket.config.annotation.enablewebsocket;
import org.springframework.web.socket.config.annotation.websocketconfigurer;
import org.springframework.web.socket.config.annotation.websockethandlerregistry;

@configuration
@enablewebsocket
public class websocketconfig implements websocketconfigurer {

    private final websockethandler websockethandler;

    public websocketconfig(websockethandler websockethandler) {
        this.websockethandler = websockethandler;
    }

    @override
    public void registerwebsockethandlers(websockethandlerregistry registry) {
        registry.addhandler(websockethandler, "/websocket").setallowedorigins("*");
    }
}

这里我们定义了一个websocket配置类,并注册了websocket处理器。/websocket 是websocket的端点路径。

实现websocket处理器

afterconnectionestablished

void afterconnectionestablished(websocketsession session) throws exception;

afterconnectionclosed

void afterconnectionclosed(websocketsession session, closestatus status) throws exception;

handletextmessage

void handletextmessage(websocketsession session, textmessage message) throws exception;
import org.springframework.web.socket.closestatus;
import org.springframework.web.socket.textmessage;
import org.springframework.web.socket.websocketsession;
import org.springframework.web.socket.handler.textwebsockethandler;

import java.util.concurrent.concurrenthashmap;

import org.springframework.web.socket.closestatus;
import org.springframework.web.socket.textmessage;
import org.springframework.web.socket.websocketsession;
import org.springframework.web.socket.handler.textwebsockethandler;
import java.util.concurrent.concurrenthashmap;

public class websockethandler extends textwebsockethandler {

    private static final concurrenthashmap<string, websocketsession> sessions = new concurrenthashmap<>();

    @override
		public void afterconnectionestablished(websocketsession session) throws exception {
        super.afterconnectionestablished(session);
        string id = session.getid();
        sessions.put(id, session);
        system.out.println("websocket connection established with session id: " + id);
    }

    @override
    public void afterconnectionclosed(websocketsession session, closestatus status) throws exception {
        super.afterconnectionclosed(session, status);
        string id = session.getid();
        sessions.remove(id);
        system.out.println("websocket connection closed with session id: " + id);
    }

    public void sendmessagetosession(string sessionid, string message) {
        websocketsession session = sessions.get(sessionid);
        if (session != null && session.isopen()) {
            try {
                session.sendmessage(new textmessage(message));
            } catch (exception e) {
                e.printstacktrace();
            }
        }
    }

    public void broadcastmessage(string message) {
        for (websocketsession session : sessions.values()) {
            if (session.isopen()) {
                try {
                    session.sendmessage(new textmessage(message));
                } catch (exception e) {
                    e.printstacktrace();
                }
            }
        }
    }
}

现在我们可以使用websockethandler类中的sendmessagetosession或broadcastmessage方法来发送数据给前端。

发送给特定会话:如果想要向特定的客户端发送消息,可以使用sendmessagetosession方法。你需要知道客户端的会话id。

websockethandler.sendmessagetosession(sessionid, "hello, client!");

广播消息:如果你想向所有已连接的客户端广播消息,可以使用broadcastmessage方法

websockethandler.broadcastmessage("hello, everyone!")

注销websocket连接

要在java后端注销websocket连接,可以通过调用 websockethandler 类中的 removesession 方法来实现。例如,你可以从http请求或其他服务中调用此方法:

@getmapping("/logout/{sessionid}")
public responseentity<string> logout(@pathvariable string sessionid) {
    websockethandler handler = new websockethandler(); // 或者通过依赖注入获取
    handler.removesession(sessionid);
    return responseentity.ok("session " + sessionid + " has been closed.");
}

自己定义一个 固定id 方便使用

前端 javascript 代码

后端 java 代码

前端 javascript

<!doctype html>
<html l	ang="en">
<head>
    <meta charset="utf-8">
    <title>websocket client example</title>
</head>
<body>
    <input type="text" id="messageinput" placeholder="enter your message here">
    <button id="sendbutton">send message</button>
    <div id="log"></div>

    <script>
        document.addeventlistener('domcontentloaded', function () {
            const socket = new websocket('ws://example.com/websocket');

            socket.onopen = function (event) {
                console.log('websocket connection established.');

                // 固定的客户端id
                const clientid = 'client-123';

                // 发送握手消息
                socket.send(json.stringify({
                    type: 'handshake',
                    clientid: clientid,
                    message: 'hello, server!'
                }));
            };

            socket.onmessage = function (event) {
                console.log('received from server:', event.data);
                document.getelementbyid('log').textcontent += 'received from server: ' + event.data + '\n';
            };

            socket.onclose = function (event) {
                console.log('websocket connection closed.');
                document.getelementbyid('log').textcontent += 'websocket connection closed.\n';
            };

            socket.onerror = function (error) {
                console.error('websocket error:', error);
                document.getelementbyid('log').textcontent += 'websocket error: ' + error + '\n';
            };

            document.getelementbyid('sendbutton').addeventlistener('click', function () {
                let message = document.getelementbyid('messageinput').value;
                if (socket.readystate === websocket.open) {
                    socket.send(message);
                    document.getelementbyid('log').textcontent += 'sent message: ' + message + '\n';
                } else {
                    alert('websocket connection is not open.');
                }
            });
        });
    </script>
</body>
</html>

java 服务器端配置

import com.fasterxml.jackson.databind.objectmapper;
import com.ruoyi.common.utils.socket.handshakemessage;
import org.springframework.stereotype.component;
import org.springframework.web.socket.closestatus;
import org.springframework.web.socket.textmessage;
import org.springframework.web.socket.websocketsession;
import org.springframework.web.socket.handler.textwebsockethandler;

import java.util.map;
import java.util.concurrent.concurrenthashmap;

@component
public class websockethandler extends textwebsockethandler {

    private static final map<string, websocketsession> clientsessions = new concurrenthashmap<>();
    private static final objectmapper objectmapper = new objectmapper();

    @override
    public void afterconnectionestablished(websocketsession session) throws exception {
        super.afterconnectionestablished(session);
        string sessionid = session.getid();
        system.out.println("websocket connection established with session id: " + sessionid);
    }

    @override
    protected void handletextmessage(websocketsession session, textmessage message) throws exception {
        string payload = message.getpayload();
        handshakemessage handshakemessage = objectmapper.readvalue(payload, handshakemessage.class);

        if ("handshake".equals(handshakemessage.gettype())) {
            string clientid = handshakemessage.getclientid();
            string sessionid = session.getid();

            // 存储clientid与sessionid的映射关系
            clientsessions.put(clientid, session);

            // 可以选择回复客户端确认握手成功的消息
            session.sendmessage(new textmessage("handshake successful"));
        }
    }

    @override
    public void afterconnectionclosed(websocketsession session, closestatus status) throws exception {
        super.afterconnectionclosed(session, status);
        string sessionid = session.getid();
        system.out.println("websocket connection closed with session id: " + sessionid);

        // 移除会话
        clientsessions.values().removeif(s -> s.getid().equals(sessionid));
    }

    public void sendmessagetoclient(string clientid, string message) {
        websocketsession session = clientsessions.get(clientid);
        if (session != null && session.isopen()) {
            try {
                session.sendmessage(new textmessage(message));
            } catch (exception e) {
                e.printstacktrace();
            }
        }
    }

    // 定义握手消息模型
    private static class handshakemessage {
        private string type;
        private string clientid;
        private string message;

        // getters and setters
    }
}

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。

(0)

您想发表意见!!点此发布评论

推荐阅读

JeecgBoot文件上传实现方式

01-20

JDK自带监控工具jstat、jmap、jstack的使用指南(附命令示例)

01-20

C#  .NET实现Excel到JSON的自动化转换

01-18

jacksonJson序列化Map时指定Long序列化为String的实践

01-17

在CentOS上快速安装NVM和Node.js 14的完整指南与优化方案

01-16

NGINX njs从基础配置到高级特性实战

01-14

猜你喜欢

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论