Spring WebSocket

Spring WebSocket 教程展示了如何在 Spring Web 应用中使用 WebSocket。

Spring 是用于创建企业应用的流行 Java 应用框架。

WebSocket

WebSocket 是一种计算机通信协议,可通过单个 TCP 连接提供全双工通信通道。 WebSocket 用于高度互动的应用,例如游戏,聊天或股票市场。

TextWebSocketHandler

Spring 使用WebSocketHandler处理 WebSocket 消息和生命周期事件。 TextWebSocketHandler是用于处理文本消息的WebSocketHandler实现。

Spring TextWebSocketHandler示例

以下应用使用TextWebSocketHandler通过 WebSocket 处理文本消息。

web.xml
src
├───main
│   ├───java
│   │   └───com
│   │       └───zetcode
│   │           ├───config
│   │           │       MyWebInitializer.java
│   │           │       WebConfig.java
│   │           │       WebSocketConfig.java
│   │           └───handler
│   │                   MyWebSocketHandler.java
│   ├───resources
│   └───webapp
│       │   index.html
│       └───WEB-INF
└───test
    └───java
Java

这是项目结构。

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
         http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.zetcode</groupId>
    <artifactId>textwebsocketex</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.1.2.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-websocket</artifactId>
            <version>5.1.2.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.1</version>
            <scope>provided</scope>
        </dependency>

    </dependencies>

    <build>
        <plugins>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>3.2.2</version>
            </plugin>

        </plugins>
    </build>

</project>
Java

pom.xml文件中,我们具有以下依存关系:spring-webmvcjavax.servlet-apispring-websocket

com/zetcode/config/MyWebInitializer.java

package com.zetcode.config;

import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

public class MyWebInitializer extends
        AbstractAnnotationConfigDispatcherServletInitializer {

    @Override
    protected Class<?>[] getRootConfigClasses() {
        return null;
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class[]{WebConfig.class, WebSocketConfig.class};
    }

    @Override
    protected String[] getServletMappings() {
        return new String[]{"/"};
    }
}
Java

MyWebInitializer初始化 Spring Web 应用。 它提供了两个配置类:WebConfigWebSocket

com/zetcode/config/WebConfig.java

package com.zetcode.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
@EnableWebMvc
@ComponentScan("com.zetcode")
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
    }
}
Java

WebConfig配置DefaultServlet。 在我们的应用中,我们有一个静态的index.html页面,该页面由DefaultServlet处理。

com/zetcode/config/WebSocketConfig.java

package com.zetcode.config;

import com.zetcode.handler.MyWebSocketHandler;
import org.springframework.beans.factory.annotation.Autowired;
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 {

    @Autowired
    private MyWebSocketHandler myWebSocketHandler;

    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        registry.addHandler(myWebSocketHandler, "/socketHandler");
    }
}
Java

WebSocketConfig使用@EnableWebSocket在 Spring Web 应用中配置 WebSocket。

@Autowired
private MyWebSocketHandler myWebSocketHandler;
Java

我们注入MyWebSocketHandler。 已在registerWebSocketHandlers()中注册。

com/zetcode/config/MyWebSocketHandler.java

package com.zetcode.handler;

import org.springframework.stereotype.Component;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;
import java.time.LocalTime;

@Component
public class MyWebSocketHandler extends TextWebSocketHandler {

    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message)
            throws Exception {

        var clientMessage = message.getPayload();

        if (clientMessage.startsWith("hello") || clientMessage.startsWith("greet")) {
            session.sendMessage(new TextMessage("Hello there!"));
        } else if (clientMessage.startsWith("time")) {
            var currentTime = LocalTime.now();
            session.sendMessage(new TextMessage(currentTime.toString()));
        } else {

            session.sendMessage(new TextMessage("Unknown command"));
        }
    }
}
Java

MyWebSocketHandler中,我们对套接字消息做出反应。

var clientMessage = message.getPayload();
Java

通过getPayLoad()方法,我们获得了客户端消息。

if (clientMessage.startsWith("hello") || clientMessage.startsWith("greet")) {
    session.sendMessage(new TextMessage("Hello there!"));
} else if (clientMessage.startsWith("time")) {
    var currentTime = LocalTime.now();
    session.sendMessage(new TextMessage(currentTime.toString()));
} else {

    session.sendMessage(new TextMessage("Unknown command"));
}
Java

根据消息,我们将TextMessage发送回客户端。

webapp/index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Home page</title>
    <link href="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.3.1/semantic.min.css"
            rel="stylesheet">
</head>
<body>

<div class="ui container">

    <h1>Spring MVC 5 WebSocket</h1>

    <div class="two column grid">
        <div class="row">
            <div class="column">
                <label for="myMessage">Message</label>
            </div>

            <div class="column">
                <div class="ui input">
                    <input type="text" id="myMessage">
                </div>
            </div>
        </div>

        <div class="row">
            <div class="column">
                <label for="output">Response from Server</label>
            </div>

            <div class="column">
                <textarea rows="8" cols="50" id="output" readonly="readonly"></textarea>
            </div>
        </div>

        <div class="row">
            <button class="ui button" onclick="send()">Send</button>
        </div>

    </div>
</div>

<script>
    const socketConn = new WebSocket('ws://localhost:8080/socketHandler');

    function send() {
        const clientMsg = document.getElementById('myMessage');

        if (clientMsg.value) {
            socketConn.send(clientMsg.value);
        }
    }

    socketConn.onmessage = (e) => {

        const output = document.getElementById('output');

        output.value += `${e.data}\n`;
    }
</script>
</body>
</html>
Java

index.html包含应用的客户端接口。

const socketConn = new WebSocket('ws://localhost:8080/socketHandler');
Java

JavaScript 中,我们创建一个套接字连接。

function send() {
    const clientMsg = document.getElementById('myMessage');

    if (clientMsg.value) {
        socketConn.send(clientMsg.value);
    }
}
Java

单击按钮后,我们将发送带有send()的短信。

socketConn.onmessage = (e) => {

    const output = document.getElementById('output');

    output.value += `${e.data}\n`;
}
Java

收到响应后,将调用onmessage()事件处理程序。 我们获得响应数据并将其添加到文本区域。

在本教程中,我们创建了一个支持 WebSocket 的简单 Spring Web 应用。

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程

登录

注册