Spring Boot 开发私有即时通信系统(WebSocket)

Spring Boot是一个快速开发框架,可以帮助我们快速构建Web应用程序。在本攻略中,我们将使用Spring Boot和WebSocket创建一个私有即时通信系统。以下是完整攻略:

  1. 创建一个Maven项目,并在pom.xml文件添加以下依赖项:
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
  1. 创建一个WebSocket配置类,并使用@Configuration注解将其标记为Spring配置类。在配置类中,创建一个WebSocketHandler实例,并使用@Bean注解将其注入到Spring容器中。
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.WebSocketHandler;
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 {

    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        registry.addHandler(myHandler(), "/myHandler").setAllowedOrigins("*");
    }

    @Bean
    public WebSocketHandler myHandler() {
        return new MyHandler();
    }
}

在上面的示例中,我们使用@EnableWebSocket注解启用WebSocket支持。我们还使用registerWebSocketHandlers()方法注册WebSocket处理程序,并使用setAllowedOrigins()方法设置允许的来源。我们还使用@Bean注解将MyHandler实例注入到Spring容器中。

  1. 创建一个WebSocket处理程序类,并实现WebSocketHandler接口。在处理程序类中,实现afterConnectionEstablished()方法和handleTextMessage()方法。
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

public class MyHandler extends TextWebSocketHandler {

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

    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        sessions.put(session.getId(), session);
    }

    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        String payload = message.getPayload();
        String[] parts = payload.split(":");
        String recipient = parts[0];
        String content = parts[1];
        WebSocketSession recipientSession = sessions.get(recipient);
        if (recipientSession != null && recipientSession.isOpen()) {
            recipientSession.sendMessage(new TextMessage(content));
        }
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        sessions.remove(session.getId());
    }
}

在上面的示例中,我们使用ConcurrentHashMap来存储WebSocket会话。我们实现了afterConnectionEstablished()方法来添加新的会话。我们还实现了handleTextMessage()方法来处理文本消息。在该方法中,我们解析消息的接收者和内容,并将消息发送给接收者。最后,我们实现了afterConnectionClosed()方法来删除会话。

  1. 创建一个控制器类,并使用@RestController注解将其标记为控制器。在控制器类中,创建一个处理HTTP GET请求的方法,并使用@RequestMapping注解将其映射到URL路径。
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class MyController {

    @RequestMapping("/")
    public String index() {
        return "Hello, World!";
    }
}
  1. src/main/resources/static目录下创建一个index.html文件,并添加以下内容:
<!DOCTYPE html>
<html>
<head>
    <title>WebSocket Example</title>
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
    <script>
        var socket = new WebSocket("ws://" + window.location.host + "/myHandler");

        socket.onmessage = function(event) {
            var message = event.data;
            $("#messages").append("<p>" + message + "</p>");
        };

        function sendMessage() {
            var recipient = $("#recipient").val();
            var content = $("#content").val();
            var message = recipient + ":" + content;
            socket.send(message);
        }
    </script>
</head>
<body>
    <h1>WebSocket Example</h1>
    <div>
        <label for="recipient">Recipient:</label>
        <input type="text" id="recipient">
    </div>
    <div>
        <label for="content">Content:</label>
        <input type="text" id="content">
    </div>
    <button onclick="sendMessage()">Send</button>
    <div id="messages"></div>
</body>
</html>

在上面的示例中,我们使用JavaScript创建一个WebSocket连接,并使用onmessage事件处理程序来处理接收到的消息。我们还创建了一个sendMessage()函数来发送消息。在HTML中,我们使用<input>元素来获取接收者和内容,并使用<button>元素来触发sendMessage()函数。我们还使用<div>元素来显示接收到的消息。

  1. 运行应用程序。在浏览器中访问http://localhost:8080/,将看到一个Web页面。在页面中,输入接收者和内容,并单击“Send”按钮。在页面下方,将显示接收到的消息。

以上是使用Spring Boot和WebSocket创建私有即时通信系统的完整攻略。下面是两个示例,演示如何使用Spring Boot和WebSocket创建更复杂的Web应用程序:

示例1:使用Spring Security保护WebSocket连接

在这个示例中,我们将使用Spring Security来保护WebSocket连接。我们将创建一个控制器类,并使用Spring Security来限制访问WebSocket连接。

  1. 在pom.xml文件中添加以下依赖项:
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>
  1. 创建一个Spring Security配置类,并使用@Configuration注解将其标记为Spring配置类。在配置类中,创建一个UserDetailsService实例,并使用@Bean注解将其注入到Spring容器中。我们还使用configure()方法配置Spring Security。
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Bean
    public UserDetailsService userDetailsService() {
        InMemoryUserDetailsManager manager = new InMemoryUserDetailsManager();
        manager.createUser(User.withDefaultPasswordEncoder().username("user").password("password").roles("USER").build());
        return manager;
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
            .antMatchers("/myHandler").hasRole("USER")
            .and()
            .formLogin();
    }
}

在上面的示例中,我们使用@EnableWebSecurity注解启用Spring Security支持。我们使用userDetailsService()方法创建一个InMemoryUserDetailsManager实例,并使用withDefaultPasswordEncoder()方法设置密码编码器。我们还使用configure()方法配置Spring Security,限制访问WebSocket连接。

  1. 创建一个控制器类,并使用@RestController注解将其标记为控制器。在控制器类中,创建一个处理HTTP GET请求的方法,并使用@RequestMapping注解将其映射到URL路径。
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class MyController {

    @RequestMapping("/")
    public String index() {
        return "Hello, World!";
    }
}
  1. 创建一个WebSocket处理程序类,并实现WebSocketHandler接口。在处理程序类中,实现afterConnectionEstablished()方法和handleTextMessage()方法。
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

public class MyHandler extends TextWebSocketHandler {

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

    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        String username = authentication.getName();
        sessions.put(username, session);
    }

    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        String username = authentication.getName();
        String payload = message.getPayload();
        String[] parts = payload.split(":");
        String recipient = parts[0];
        String content = parts[1];
        WebSocketSession recipientSession = sessions.get(recipient);
        if (recipientSession != null && recipientSession.isOpen()) {
            recipientSession.sendMessage(new TextMessage(username + ": " + content));
        }
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        String username = authentication.getName();
        sessions.remove(username);
    }
}

在上面的示例中,我们使用SecurityContextHolder来获取当前用户的身份验证信息。我们使用身份验证信息的用户名来存储WebSocket会话。在handleTextMessage()方法中,我们将发送者的用户名添加到消息中。

  1. src/main/resources/static目录下创建一个index.html文件,并添加以下内容:
<!DOCTYPE html>
<html>
<head>
    <title>WebSocket Example</title>
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
    <script>
        var socket = new WebSocket("ws://" + window.location.host + "/myHandler");

        socket.onmessage = function(event) {
            var message = event.data;
            $("#messages").append("<p>" + message + "</p>");
        };

        function sendMessage() {
            var recipient = $("#recipient").val();
            var content = $("#content").val();
            var message = recipient + ":" + content;
            socket.send(message);
        }
    </script>
</head>
<body>
    <h1>WebSocket Example</h1>
    <div>
        <label for="recipient">Recipient:</label>
        <input type="text" id="recipient">
    </div>
    <div>
        <label for="content">Content:</label>
        <input type="text" id="content">
    </div>
    <button onclick="sendMessage()">Send</button>
    <div id="messages"></div>
</body>
</html>

在上面的示例中,我们使用JavaScript创建一个WebSocket连接,并使用onmessage事件处理程序来处理接收到的消息。我们还创建了一个sendMessage()函数来发送消息。在HTML中,我们使用<input>元素来获取接收者和内容,并使用<button>元素来触发sendMessage()函数。我们还使用<div>元素来显示接收到的消息。

  1. 运行应用程序。在浏览器中访问http://localhost:8080/,将看到一个Web页面。在页面中,输入接收者和内容,并单击“Send”按钮。在页面下方,将显示接收到的消息。

示例2:使用SockJS和STOMP协议

在这个示例中,我们将使用SockJS和STOMP协议来创建一个更高级的WebSocket应用程序。我们将创建一个控制器类,并使用SockJS和STOMP协议来实现WebSocket连接。

  1. 在pom.xml文件中添加以下依赖项:
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-websocket</artifactId>
</dependency>

<dependency>
    <groupId>org.webjars</groupId>
    <artifactId>sockjs-client</artifactId>
    <version>1.3.0</version>
</dependency>

<dependency>
    <groupId>org.webjars</groupId>
    <artifactId>stomp-websocket</artifactId>
    <version>2.3.3</version>
</dependency>
  1. 创建一个控制器类,并使用@RestController注解将其标记为控制器。在控制器类中,创建一个处理HTTP GET请求的方法,并使用@RequestMapping注解将其映射到URL路径。
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class MyController {

    @RequestMapping("/")
    public String index() {
        return "Hello, World!";
    }
}
  1. 创建一个WebSocket处理程序类,并实现WebSocketHandler接口。在处理程序类中,实现afterConnectionEstablished()方法和handleTextMessage()方法。
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

public class MyHandler extends TextWebSocketHandler {

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

    private SimpMessagingTemplate messagingTemplate;

    public MyHandler(SimpMessagingTemplate messagingTemplate) {
        this.messagingTemplate = messagingTemplate;
    }

    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        sessions.put(session.getId(), session);
    }

    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        String payload = message.getPayload();
        String[] parts = payload.split(":");
        String recipient = parts[0];
        String content = parts[1];
        messagingTemplate.convertAndSendToUser(recipient, "/queue/messages", content);
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        sessions.remove(session.getId());
    }
}

在上面的示例中,我们使用ConcurrentHashMap来存储WebSocket会话。我们实现了afterConnectionEstablished()方法来添加新的会话。我们还实现了handleTextMessage()方法来处理文本消息。在该方法中,我们解析消息的接收者和内容,并使用SimpMessagingTemplate来发送消息。最后,我们实现了afterConnectionClosed()方法来删除会话。

  1. 创建一个WebSocket配置类,并使用@Configuration注解将其标记为Spring配置类。在配置类中,创建一个WebSocketHandler实例,并使用@Bean注解将其注入到Spring容器中。我们还使用configureMessageBroker()方法配置消息代理。
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
import org.springframework.web.socket.server.standard.ServletServerContainerFactoryBean;

@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {

    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        registry.addHandler(myHandler(), "/myHandler").setAllowedOrigins("*");
    }

    @Bean
    public WebSocketHandler myHandler() {
        return new MyHandler(messagingTemplate());
    }

    @Bean
    public ServletServerContainerFactoryBean createWebSocketContainer() {
        ServletServerContainerFactoryBean container = new ServletServerContainerFactoryBean();
        container.setMaxTextMessageBufferSize(8192);
        container.setMaxBinaryMessageBufferSize(8192);
        return container;
    }

    @Bean
    public SimpMessagingTemplate messagingTemplate() {
        return new SimpMessagingTemplate(createWebSocketClient());
    }

    @Bean
    public WebSocketClient createWebSocketClient() {
        return new StandardWebSocketClient();
    }

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

在上面的示例中,我们使用@EnableWebSocket注解启用WebSocket支持。我们使用registerWebSocketHandlers()方法注册WebSocket处理程序,并使用setAllowedOrigins()方法设置允许的来源。我们还使用@Bean注解将MyHandler实例注入到Spring容器中。我们使用createWebSocketContainer()方法创建一个ServletServerContainerFactoryBean实例,并设置最大消息缓冲区大小。我们还使用messagingTemplate()方法创建一个SimpMessagingTemplate实例,并使用createWebSocketClient()方法创建一个WebSocketClient实例。最后,我们使用configureMessageBroker()方法配置消息代理。

  1. src/main/resources/static目录下创建一个index.html文件,并添加以下内容:

```html




WebSocket Example



  • Java利用for循环打印菱形的实例教程

    下面是Java利用for循环打印菱形的实例教程的完整攻略。 题目分析 我们需要打印一个菱形,实际上就是一个对称的四边形。那么我们可以通过for循环嵌套来实现。 代码实现 import java.util.Scanner; public class PrintDiamond { public static void main(String[] args) { …

    Java 2023年5月26日
    00
  • 合作推广
    合作推广
    分享本页
    返回顶部