spring WebSocket示例详解

下面我将详细讲解“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利用FileReader读取本地文件或者blob方式

    接下来我将详细讲解使用JavaScript中的FileReader对象来读取本地文件或Blob对象的方法。 FileReader对象简介 FileReader对象是WebAPI中的一个对象,用于读取本地文件中的数据。它提供了一种异步方式来读取文件,并且支持大量的文件类型。我们可以使用FileReader对象将文件读取为文本、DataURL或ArrayBuff…

    JavaScript 2023年5月27日
    00
  • 老生常谈JavaScript 函数表达式

    JavaScript 函数表达式是一种将函数作为值进行赋值或传递的方式。 函数表达式的语法 函数表达式的语法格式为:变量名 = function() {} 其中,变量名可以接受任何有效的 JavaScript 变量名。而函数表达式的主体内容则放在花括号中,可以包含任何有效的 JavaScript 语句和表达式。 下面是一个简单的例子: var func = …

    JavaScript 2023年6月11日
    00
  • 关于JSON.parse(),JSON.stringify(),jQuery.parseJSON()的用法

    JSON 是一种非常常用的数据格式,它被广泛应用于前后端数据的传输和存储。在 JavaScript 中,我们可以通过以下三种方法来处理 JSON 数据: JSON.parse(): 将 JSON 字符串解析为 JavaScript 对象。 JSON.stringify(): 将 JavaScript 对象序列化为 JSON 字符串。 $.parseJSON(…

    JavaScript 2023年5月27日
    00
  • 将json对象转换为字符串的方法

    将JSON对象转换为字符串通常使用JSON.stringify()方法,以下是该方法的完整攻略: 1. JSON.stringify()方法的语法 JSON.stringify()方法的语法如下: JSON.stringify(value[, replacer[, space]]) 其中,value参数表示待转换的JSON对象,必选且只能是以下类型之一:- …

    JavaScript 2023年5月27日
    00
  • IE浏览器与FF浏览器关于Ajax传递参数值为中文时的区别实例分析

    针对“IE浏览器与FF浏览器关于Ajax传递参数值为中文时的区别实例分析”,我们可以从以下几个方面进行讲解: URL编码的区别 在使用Ajax传递参数时,中文参数需要进行URL编码,然后再进行发送。而IE浏览器和FF浏览器对URL编码的处理是不同的: IE浏览器:使用escape()函数对中文参数进行编码。 FF浏览器:使用encodeURIComponen…

    JavaScript 2023年5月19日
    00
  • 使用SWFObject完美解决HTML插入Flash的各浏览器兼容性方案

    使用SWFObject插入Flash可以通过JavaScript动态生成Flash对象,并通过检测当前浏览器是否支持HTML5的canvas元素,自动选择使用原生HTML5的canvas元素或者使用Flash来显示动画。这种方法可以解决HTML插入Flash的各浏览器兼容性问题,并且也可以提高网站的性能。 以下是使用SWFObject完美解决HTML插入Fl…

    JavaScript 2023年6月10日
    00
  • javascript中的对象和数组的应用技巧

    让我来为你详细讲解 Javascript 中的对象和数组的应用技巧。 对象的应用技巧 1. 使用对象来封装数据和函数 在 JavaScript 中,对象是一个拥有若干属性的数据结构。我们可以使用对象封装一些通用的属性和方法,便于代码的维护和实现。 // 定义一个封装后的学生对象 const student = { name: ‘张三’, age: 20, g…

    JavaScript 2023年5月27日
    00
  • js的对象与函数详解

    JS的对象与函数详解 本文将讲解JavaScript中的对象和函数。对象是一种数据类型,它们可以具有属性和方法。函数是一种可调用的对象,它通常用来实现可重复使用的代码块。 对象 JavaScript中的对象可以看作是键值对的集合,每个键都是字符串,每个值可以是任意类型的数据。对象可以通过对象字面量的方式创建,也可以通过构造函数实例化。以下是创建对象的两种方式…

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