spring WebSocket示例详解

yizhihongxing

下面我将详细讲解“spring WebSocket示例详解”的完整攻略。

简介

本文将详细介绍如何在 Spring 框架下使用 WebSocket。WebSocket 是一种实时通信协议,能够从客户端向服务器端推送消息,而服务器端能够主动向客户端推送消息。相比于传统的 HTTP 请求方式,WebSocket 具有实时性更强、资源占用更少等优点。

本文使用 Spring Boot 2.x,同时也会使用到 Spring Framework 中的 Spring WebSocket。

环境准备

要运行本文的示例代码,需要具备以下环境:

  • JDK 1.8 或以上;
  • Maven 3.2 或以上;
  • Idea 或 Eclipse 等 IDE。

项目搭建

首先,我们需要搭建一个 Spring Boot 的基础项目。可以使用 Spring Initializr 快速创建一个基础的 Spring Boot 项目。

然后,我们需要添加 Spring WebSocket 的依赖。在 pom.xml 中添加以下代码:

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

示例一:简单示例

本示例演示了如何在 Spring Boot 应用中实现 WebSocket 的基本功能。

  1. 创建一个 WebSocketConfig 类,配置消息代理和消息端点:
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {

    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry) {
        registry.enableSimpleBroker("/topic");
        registry.setApplicationDestinationPrefixes("/app");
    }

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/websocket-demo").withSockJS();
    }
}
  1. 创建一个控制器来处理 WebSocket 相关的请求:
@Controller
public class WebSocketController {

    @MessageMapping("/hello")
    @SendTo("/topic/greetings")
    public Greeting greeting(HelloMessage message) {
        return new Greeting("Hello, " + message.getName() + "!");
    }
}
  1. 创建一个 HelloMessage 类和一个 Greeting 类,用于传递消息:
public class HelloMessage {

    private String name;

    public String getName() {
        return name;
    }

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

public class Greeting {

    private String content;

    public Greeting(String content) {
        this.content = content;
    }

    public String getContent() {
        return content;
    }
}
  1. 最后,我们需要创建一个前端页面来测试 WebSocket。以下是一个基本的 HTML 页面:
<!DOCTYPE html>
<html>
<head>
    <title>WebSocket Demo</title>
    <script src="/webjars/sockjs-client/1.0.2/sockjs.min.js"></script>
    <script src="/webjars/stomp-websocket/2.3.3/stomp.min.js"></script>
    <script src="/js/app.js"></script>
</head>
<body>

<div>
    <label for="name">Name:</label> <input type="text" id="name">
    <button id="connect">Connect</button>
    <button id="disconnect">Disconnect</button>
</div>

<div id="greetings">
</div>

</body>
</html>

app.js 的代码如下:

var stompClient = null;

function connect() {
    var socket = new SockJS('/websocket-demo');
    stompClient = Stomp.over(socket);
    stompClient.connect({}, function (frame) {
        setConnected(true);
        console.log('Connected: ' + frame);
        stompClient.subscribe('/topic/greetings', function (greeting) {
            showGreeting(JSON.parse(greeting.body).content);
        });
    });
}

function disconnect() {
    if (stompClient !== null) {
        stompClient.disconnect();
    }
    setConnected(false);
    console.log("Disconnected");
}

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

function showGreeting(message) {
    $("#greetings").append("<tr><td>" + message + "</td></tr>");
}

function setConnected(connected) {
    $("#connect").prop("disabled", connected);
    $("#disconnect").prop("disabled", !connected);
    if (connected) {
        $("#greetings").show();
    }
    else {
        $("#greetings").hide();
    }
}

$(function () {
    $("form").on('submit', function (e) {
        e.preventDefault();
    });
    $("#connect").click(function () {
        connect();
    });
    $("#disconnect").click(function () {
        disconnect();
    });
    $("#send").click(function () {
        sendName();
    });
});

运行项目,访问 http://localhost:8080/index.html,测试 WebSocket 是否可用。

示例二:群聊示例

本示例演示了如何在 Spring Boot 应用中实现 WebSocket 群聊的功能。

  1. 创建一个 ChatRoom 类,该类保存了 WebSocket 会话的管理器和一个群聊列表:
@Component
public class ChatRoom {

    private final Map<String, WebSocketSession> sessions = new ConcurrentHashMap<>();

    private final List<String> messages = new CopyOnWriteArrayList<>();

    public void addSession(WebSocketSession session) {
        sessions.put(session.getId(), session);
    }

    public void removeSession(WebSocketSession session) {
        sessions.remove(session.getId());
    }

    public List<String> getMessages() {
        return messages;
    }

    public void addMessage(String message) {
        messages.add(message);
        if (messages.size() > 100) {
            messages.remove(0);
        }
    }

    public void broadcast(String message) {
        TextMessage textMessage = new TextMessage(message);
        sessions.values().forEach(session -> {
            try {
                session.sendMessage(textMessage);
            } catch (IOException e) {
                e.printStackTrace();
            }
        });
    }
}
  1. 创建一个 WebSocketHandler 类,用于处理 WebSocket 相关的请求:
@Component
public class WebSocketHandler extends TextWebSocketHandler {

    private final ObjectMapper objectMapper = new ObjectMapper();

    @Autowired
    private ChatRoom chatRoom;

    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        ChatMessage chatMessage = objectMapper.readValue(message.getPayload(), ChatMessage.class);
        chatRoom.addMessage(chatMessage.getFrom() + ": " + chatMessage.getMessage());
        chatRoom.broadcast(chatMessage.getFrom() + ": " + chatMessage.getMessage());
    }

    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        chatRoom.addSession(session);
        for (String message : chatRoom.getMessages()) {
            session.sendMessage(new TextMessage(message));
        }
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        chatRoom.removeSession(session);
    }
}
  1. 创建一个 ChatMessage 类,用于传递消息:
public class ChatMessage {

    private String from;

    private String message;

    public String getFrom() {
        return from;
    }

    public void setFrom(String from) {
        this.from = from;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}
  1. 创建一个控制器,用于处理页面请求:
@Controller
public class PageController {

    @RequestMapping("/")
    public String index() {
        return "index";
    }
}
  1. 创建一个前端页面来测试 WebSocket。以下是一个基本的 HTML 页面:
<!DOCTYPE html>
<html>
<head>
    <title>WebSocket Chat Demo</title>
</head>
<body>

<form onsubmit="return false;">
    Name: <input type="text" id="name" value="User1"><br>
    Message: <input type="text" id="message"><br>
    <button onclick="sendMessage()">Send</button>
</form>

<hr>

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

<script type="text/javascript">
    var ws;

    document.addEventListener("DOMContentLoaded", function(event) {
        ws = new WebSocket("ws://" + document.location.host + "/ws");
        ws.onmessage = showMessage;
        ws.onclose = console.warn;
    });

    function showMessage(event) {
        var data = JSON.parse(event.data);
        var chat = document.getElementById("chat");
        var message = document.createElement("p");
        message.innerText = data;
        chat.append(message);
    }

    function sendMessage() {
        var name = document.getElementById("name").value;
        var message = document.getElementById("message").value;
        var chatMessage = {from: name, message: message};
        ws.send(JSON.stringify(chatMessage));
        document.getElementById("message").value = "";
    }
</script>

</body>
</html>

以上就是使用 Spring WebSocket 的基本流程,如有问题请随时提问。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:spring WebSocket示例详解 - Python技术站

(0)
上一篇 2023年6月11日
下一篇 2023年6月11日

相关文章

  • js字符串日期yyyy-MM-dd转化为date示例代码

    将 JavaScript 的字符串日期 “yyyy-MM-dd” 转化为日期类型 date 的过程需要按字符串的年、月、日逐个提取解析,再调用 Date 对象的构造函数生成对应的日期对象。 以下是示例代码: // 定义要转化的字符串日期 const strDate = "2022-02-22"; // 按"-"分割字符…

    JavaScript 2023年5月27日
    00
  • JavaScript实现打字游戏

    下面是JavaScript实现打字游戏的完整攻略: 1. 准备工作 在HTML文件中添加一个文本框和一个按钮 引入jQuery库 引入word-list.js文件,该文件包含了所有的单词列表 2. 获取输入的单词 当用户在文本框中进行输入后,点击按钮,会触发事件,调用checkWord()函数,该函数获取文本框中的输入值,将其和随机生成的单词进行比较,判断是…

    JavaScript 2023年5月19日
    00
  • JavaScript中的this指向问题详解

    JavaScript中的this指向问题详解 1. this的概念 在JavaScript中,每个函数都有自己的上下文环境,而this关键字就是指向这个上下文环境,表示当前函数的执行环境。 2. this的指向 全局环境下,this指向全局对象(浏览器中为window对象)。 函数内部,this指向调用该函数的对象,如果没有上下文对象,则为window对象。…

    JavaScript 2023年6月10日
    00
  • Object.defineProperty()函数之属性描述对象

    我们来详细讲解一下“Object.defineProperty()函数之属性描述对象”。 属性描述对象介绍 在JavaScript中,一个对象的属性除了具有值(value)外,还可以具有其它的一些特性,例如它是否可遍历(enumerable)、是否可修改(writable)等。这些特性以属性描述对象(property descriptor)的形式来表示,通过…

    JavaScript 2023年5月27日
    00
  • JavaScript邮件附件可能携带恶意代码

    下面是详细讲解“JavaScript邮件附件可能携带恶意代码”的完整攻略。 背景 在安全领域中,“恶意邮件”这一术语用于指代包含恶意软件或链接的电子邮件。恶意邮件经常伪装成看上去很合法的邮件,以诱使接收者打开附件或者点开链接,从而导致计算机感染病毒、盗窃敏感信息等危害。 最近,安全专家发现一种以 JavaScript 编写的恶意代码,可以通过邮件附件的形式传…

    JavaScript 2023年5月27日
    00
  • php中preg_replace正则替换用法分析【一次替换多个值】

    《PHP中preg_replace正则替换用法分析【一次替换多个值】》是一篇介绍PHP中正则替换的文章,主要介绍preg_replace函数中的一些使用技巧,可以一次替换多个值。 一、preg_replace函数 preg_replace是PHP中用于正则替换的函数。它的语法如下: preg_replace($pattern, $replacement, $…

    JavaScript 2023年6月10日
    00
  • gulp-htmlmin压缩html的gulp插件实例代码

    下面是“gulp-htmlmin压缩html的gulp插件实例代码”的完整攻略。 什么是gulp-htmlmin gulp-htmlmin 是一个用于压缩 HTML 文件的 Gulp 插件。 安装gulp-htmlmin 在使用 gulp-htmlmin 之前,需要先安装 Gulp 和 gulp-htmlmin,可以使用以下命令安装: npm install…

    JavaScript 2023年6月10日
    00
  • Javascript数组循环遍历之forEach详解

    Javascript数组循环遍历之forEach详解 foreEach()方法的基本使用 JavaScript中的数组可以使用forEach()方法进行遍历,forEach()方法接收一个函数作为参数,该函数将在数组中的每个元素上运行,基本语法如下: array.forEach(function(currentValue, index, arr), this…

    JavaScript 2023年5月27日
    00
合作推广
合作推广
分享本页
返回顶部