关键词

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 的基本流程,如有问题请随时提问。

本文链接:http://task.lmcjl.com/news/9579.html

展开阅读全文