java 我如何使用套接字自动同步2客户端连接到一个服务器在Spring Boot

hgqdbh6s  于 2023-04-04  发布在  Java
关注(0)|答案(1)|浏览(125)

我目前正在尝试使用websockets来自动同步连接到同一个spring Boot 服务器的多个客户端。我添加了以下依赖项以能够使用sockets:

implementation 'org.springframework.boot:spring-boot-starter-websocket'
implementation 'org.springframework.boot:spring-boot-starter-websocket'

我使用这个配置文件为websockets:
WebSocketConfig.java

package server;

import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.config.annotation.AbstractWebSocketMessageBrokerConfigurer;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;

@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {

    /**
     * The method will be used to carry any messages that the server received
     * back to the client
     * @param config the configuration file that the method will use
     */
    @Override
    public void configureMessageBroker(MessageBrokerRegistry config) {
        config.enableSimpleBroker("/topic");
        config.setApplicationDestinationPrefixes("/app");
    }

    /**
     * The method is used to enable spring's STOMP support
     * @param registry the registry file that the method will use
     */
    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/chat");
        registry.addEndpoint("/chat").withSockJS();
    }
}

MessageController.java

package server;

import commons.Collection;
import commons.Message;
import commons.ResponseMessage;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.stereotype.Controller;
import org.springframework.web.util.HtmlUtils;

@Controller
public class MessageController {

    /**
     * @param collection the message that is being transmitted
     * @return the message that was received
     * @throws InterruptedException an exception which happens when the process is interrupted
     */
    @MessageMapping("/chat")
    @SendTo("/topic/messages")
    public Collection getMessage(final Collection collection) throws InterruptedException {
        Thread.sleep(1000);
        System.out.println("received message");
        return new Collection(collection.getId(), collection.getName(), collection.getBoardId(), collection.getCards());
    }

}

Collection.java

package commons;

import static org.apache.commons.lang3.builder.ToStringStyle.MULTI_LINE_STYLE;

import javax.persistence.*;

import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.apache.commons.lang3.builder.ToStringBuilder;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

@Entity
@Table(name = "collections")
public class Collection {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;

    @Column(name = "board_id")
    private Long boardId;

    @OneToMany(mappedBy = "collectionId", cascade = CascadeType.ALL, orphanRemoval = true)
    private List<Card> cards = new ArrayList<>();

    /**
     * the collection constructor
     * @param id the id used by database
     * @param name the name of the collection
     * @param boardId the board it is on
     * @param cards the list of cards
     */
    public Collection(Long id, String name, Long boardId, List<Card> cards) {
        this.id = id;
        this.name = name;
        this.boardId = boardId;
        this.cards = cards;
    }

    /**
     * Getter for the name of the collection
     * @return String - the name of the collection
     */
    public String getName() {
        return name;
    }

    /**
     * get the board id
     * @return board id
     */
    public Long getBoardId() {
        return boardId;
    }

    /**
     * Getter for the list of cards
     * @return List<Card> - list of all cards present in the
     */
    public List<Card> getCards() {
        return cards;
    }

    /**
     * get the id
     * @return id
     */
    public Long getId() {
        return id;
    }
}

所以目前我遇到的问题是这些文件实际上都没有做任何事情!所以当我在一个客户端上创建一个集合时,这涉及到将其发送到服务器,除非我用另一个动作更新它,否则它不会反映在任何其他客户端上!会不会是因为我没有很好地实现消息控制器?或者是我需要在客户端添加一些东西,使它能够监听某种输入?
我使用的所有信息都来自这些网站:
https://www.baeldung.com/websockets-spring
https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/socket/config/annotation/EnableWebSocketMessageBroker.html
https://guttikondaparthasai.medium.com/websocket-using-spring-boot-java-b95eb142f020
还有一些来自chatgpt的爱

20jt8wwn

20jt8wwn1#

我只需要添加客户端所需的标准文件即可,沿着如下:

StompSession session = connect("ws://localhost:8080/websocket");

    private StompSession connect(String url) {
        var client = new StandardWebSocketClient();
        var stomp = new WebSocketStompClient(client);
        stomp.setMessageConverter(new MappingJackson2MessageConverter());
        try {
            return stomp.connect(url, new StompSessionHandlerAdapter() {}).get();
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        } catch (ExecutionException e) {
            throw new RuntimeException(e);
        }
        throw new IllegalStateException();
    }

    public <T> void registerForCollections(String dest, Class<T> type, Consumer<T> consumer) {
        session.subscribe(dest, new StompFrameHandler() {
            @Override
            public Type getPayloadType(StompHeaders headers) {
                return type;
            }

            @Override
            public void handleFrame(StompHeaders headers, Object payload) {
                consumer.accept((T) payload);
            }
        });
    }

    public void send(String dest, Object o) {
        System.out.println(session);
        session.

然后使用registerForCollections方法订阅服务器端。
但这还不够,因为我需要很多API来实现它,但这不是我的问题的一部分,所以我不会在这里包括它。

相关问题