springboot集成websocket实现聊天室(极简版)

前情描述

最近想了解websocket的相关原理,于是写了一个极简版的程序,后端使用springboot集成websocket模块,前端手敲了一个html页面(页面很丑很丑很丑,勿喷勿喷),整个程序仅支持简单的websocket通信。

websocket优势

百度百科对websocket的定义是:WebSocket是一种在单个TCP连接上进行全双工通信的协议。
websocket的优势:
1:数据包更小,创建连接后数据包头部较小,减少网络传输的开销,提高了传输效率;
2:实时性更强,webwocket是全双工协议,服务器和客户端可以同时相互发送数据;
3:保持连接状态,websocket创建连接之后,会保持服务器和客户端的联系状态,之后通信可以省略部分状态信息。

效果展示

下面是use_one和user_two的聊天记录:
两个相互发送消息,消息内容会显示在聊天框
在这里插入图片描述

spring-boot后端

一: 依赖
在springboot的基础上引入websocket相关依赖

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

二: 重要代码
1:向springboot容器注入ServerEnpointExporter实例
该实例是spring集成websocket的重要内容,它可以将标注有@ServerEndpoint的类注册到websocket服务器中,从而让客户端可以正常访问到websocket服务器。

@Configuration
public class WebSocketConfig {

    /**
     * 注入一个ServerEndpointExporter,该Bean会自动注册使用@ServerEndpoint注解申明的websocket endpoint
     */
    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter();
    }
}

2:创建websocket服务器
在类上标注@ServerEnpoint(“/url”),需要注意的是不同的url会由不同的实例来维护,然后需要我们实现@OnOpen【开始链接】,@OnClose【结束链接】,@OnMessage【客户端向服务器发送消息】,@OnError【链接发生错误】注解的方法,这些方法参数会带有一个Session,我们可以将session保存起来,当需要向客户端发送信信息可以调用session.getBasicRemote().sendText(message);

@ServerEndpoint("/person/{userId}")
@Component
@Slf4j
public class WebSocketServer {

    private static Map<String, WebSocketServer> SOCKET_MAP = new ConcurrentHashMap<>();

    @Getter
    private Session session;


    @OnOpen
    public void open(Session session, @PathParam("userId") String userId) {
        this.session = session;
        SOCKET_MAP.put(userId, this);
        log.info("用户{}连接成功,当前链接总人数{}", userId, SOCKET_MAP.size());
    }

    @OnClose
    public void close(Session session, @PathParam("userId") String userId) {
        SOCKET_MAP.remove(userId);
        log.info("用户{}断开连接,当前链接总人数{}", userId, SOCKET_MAP.size());
    }

    @OnMessage
    public void onMessage(String message, Session session) {
        log.info("收到用户{}的消息:{}", session.getId(), message);
        ChatEntityStr chatEntity = JSONObject.parseObject(message, ChatEntityStr.class);
        WebSocketServer socketServer = SOCKET_MAP.get(chatEntity.getTo());
        if (null == socketServer) {
            //用户不在线
            log.info("用户{}不在线", chatEntity.getTo());
            return;
        }
        SendHelper.sendToPersonStr(message, socketServer.getSession());
    }

    @OnError
    public void onError(Session session, Throwable error) {
        log.error("发生错误:{}", session.getId());
        error.printStackTrace();
    }

}

html前端代码

这里写了两个html,one.html【代表user_one】,two.html【代表user_two】,下面仅展示了one.html,前端代码在项目目录下,one.html和two.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>简易聊天框</title>
    <style type="text/css">
    </style>
</head>
<body>
<div style="flex-direction: column">
    <div>
        <label>
            <textarea rows="3" id="chatMsg" style="height: 500px;width: 500px;resize: none;"></textarea>
        </label>
    </div>
    <div>
        <label>
            <input type="text" style="width: 400px" name="inputMsg" id="inputMsg" onkeyup="inputChange(this.value)">
            <button type="button" onclick="sendMsg()">发送</button>
        </label>
    </div>
</div>
</body>
<script type="application/javascript">
    /**
     * 一般情况下,只需要改动self,other,websocket服务器地址即可使用
     */
    const self = "user_one";
    const other = "user_two";

    const message = {attr: ""};
    const input = document.getElementById("inputMsg");
    const chatMsg = document.getElementById("chatMsg");

    let websocket = {
        send: function (str) {
        }
    };
    window.onload = function () {
        if (!'WebSocket' in window) return;
        webSocketInit();
    };
    //初始化websocket
    function webSocketInit() {
        websocket = new WebSocket("ws://127.0.0.1:7777/person/" + self);
        //成功建立连接
        websocket.onopen = function () {
            linkSuccess(self, self, "链接成功");
        };
        //接收到消息
        websocket.onmessage = function (event) {
            const data = JSON.parse(event.data);
            chatMsg.value = chatMsg.value + data.from + " >>> " + data.message + "\n";
        };
        //连接发生错误
        websocket.onerror = function () {
            alert("WebSocket连接发生错误");
        };
        //连接关闭
        websocket.onclose = function () {
            alert("WebSocket连接关闭");
        };
        //监听窗口关闭事件,当窗口关闭时,主动关闭websocket连接
        window.onbeforeunload = function () {
            websocket.close()
        };
    }

    //对message.attr进行绑定
    Object.defineProperty(message, "attr", {
        configurable: true,
        enumerable: true,
        set: function (newValue) {
            attr = newValue;
            input.value = newValue
        },
        get: function () {
            return attr;
        },
    });
    function inputChange(newValue) {
        message.attr = newValue
        if (event.keyCode === 13 &&
            message.attr !== undefined && message.attr !== null && message.attr.length > 0) {
            sendMsg();
        }
    }

    //发送消息
    function sendMsg() {
        if (message.attr.length <= 0) {
            return
        }
        const msg = {
            from: self,
            to: other,
            createTime: new Date(),
            message: message.attr
        };
        chatMsg.value = chatMsg.value + msg.from + " >>> " + msg.message + "\n";
        websocket.send(JSON.stringify(msg))
        message.attr = ""
    }

    //链接成功
    function linkSuccess(from, to, msg) {
        const successMsg = {
            from: from,
            to: to,
            createTime: new Date(),
            message: msg
        };
        websocket.send(JSON.stringify(successMsg))
    }
</script>
</html>

资源地址

项目地址:https://gitee.com/ryfz-git/springboot-websocket.git

结语

共同学习,共同进步,欢迎交流。

  • 6
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Boot是一个开源的Java Web框架,提供了一种快速、便捷的方式来构建基于Spring的应用程序。它的优点在于,它自动配置了许多常见的应用程序配置,使构建应用程序变得非常简单。 WebSocket是一种在客户端和服务器之间实现双向通信的协议。它允许服务器向客户端发送实时数据,而无需客户端发出请求。Spring Boot提供了一个简单的方式来集成WebSocket。 下面是在Spring Boot集成WebSocket的步骤: 1. 添加依赖:在pom.xml文件中添加以下依赖: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency> ``` 2. 创建WebSocket配置类:创建一个WebSocket配置类,用于配置WebSocket相关的参数。在该类中,我们需要创建一个WebSocketHandler类,用于处理WebSocket连接和消息。 ```java @Configuration @EnableWebSocket public class WebSocketConfig implements WebSocketConfigurer { @Override public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { registry.addHandler(new MyWebSocketHandler(), "/my-websocket"); } class MyWebSocketHandler extends TextWebSocketHandler { // 处理WebSocket连接和消息 } } ``` 3. 处理WebSocket连接和消息:在WebSocketHandler类中,我们需要重写一些方法来处理WebSocket连接和消息。例如,我们可以在onOpen方法中处理WebSocket连接,将连接添加到一个Map中,以便在后续的消息处理中使用。 ```java class MyWebSocketHandler extends TextWebSocketHandler { private Map<WebSocketSession, String> sessions = new HashMap<>(); @Override public void afterConnectionEstablished(WebSocketSession session) throws Exception { // 处理WebSocket连接 sessions.put(session, "user_" + sessions.size()); } @Override protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception { // 处理WebSocket消息 String payload = message.getPayload(); String username = sessions.get(session); String response = "Hello, " + username + "! You said: " + payload; session.sendMessage(new TextMessage(response)); } } ``` 4. 在页面中使用WebSocket:在前端页面中,我们可以使用JavaScript创建WebSocket连接,并发送和接收消息。例如: ```javascript var socket = new WebSocket("ws://" + window.location.host + "/my-websocket"); socket.onopen = function(event) { console.log("WebSocket opened"); socket.send("Hello, server!"); }; socket.onmessage = function(event) { console.log("WebSocket received message: " + event.data); }; ``` 5. 运行应用程序:运行Spring Boot应用程序,并访问http://localhost:8080/index.html。在浏览器控制台中,我们可以看到WebSocket连接和消息的输出。 以上就是在Spring Boot集成WebSocket的简单步骤。通过WebSocket,我们可以实现实时通信,例如聊天室、数据推送等应用场景。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值