我有以下用于对等通信的WebSocket客户端和服务器:
package network;
import jakarta.websocket.ContainerProvider;
import jakarta.websocket.Session;
import jakarta.websocket.WebSocketContainer;
import java.net.URI;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.annotation.Bean;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.web.socket.client.WebSocketClient;
import org.springframework.web.socket.client.standard.StandardWebSocketClient;
@Service
public class WebsocketNetwork {
private final MessageHandler messageHandler;
@Bean
public WebSocketClient webSocketClient() {
return new StandardWebSocketClient();
}
@Autowired
public WebsocketNetwork(MessageHandler messageHandler) {
this.messageHandler = messageHandler;
}
@EventListener(value = ApplicationReadyEvent.class)
public void establishConnection() {
WebSocketContainer container = ContainerProvider.getWebSocketContainer();
URI address = new URI("ws://localhost:15000/websocket");
Session session = container.connectToServer(this.messageHandler, address);
}
}
经办人:
package network;
import jakarta.websocket.ClientEndpoint;
import jakarta.websocket.OnClose;
import jakarta.websocket.OnError;
import jakarta.websocket.OnMessage;
import jakarta.websocket.OnOpen;
import jakarta.websocket.Session;
import jakarta.websocket.server.ServerEndpoint;
import java.util.Map;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Component;
@Component
@ServerEndpoint(value = "/websocket", decoders = MessageDecoder.class, encoders = MessageEncoder.class)
@ClientEndpoint(decoders = MessageDecoder.class, encoders = MessageEncoder.class)
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class MessageHandler {
// MessageHandler should have no argument constructor else it fails with:
/*
Caused by: java.lang.NoSuchMethodException: network.MessageHandler.<init>()
at java.base/java.lang.Class.getConstructor0(Class.java:3641) ~[na:na]
at java.base/java.lang.Class.getConstructor(Class.java:2324) ~[na:na]
at org.apache.catalina.core.DefaultInstanceManager.newInstance(DefaultInstanceManager.java:135) ~[tomcat-embed-core-10.1.7.jar:10.1.7]
at org.apache.tomcat.websocket.WsSession.<init>(WsSession.java:275) ~[tomcat-embed-websocket-10.1.7.jar:10.1.7]
*/
@Autowired
private ApplicationEventPublisher eventPublisher; // <-- why this Null? And how to fix it?
@OnClose
public void onClose(Session session) {
System.out.println("Disconnected from server: " + session.getId());
}
@OnOpen
public void onOpen(Session session) {
System.out.println("Connected to server: " + session.getId());
}
// incoming messages
@OnMessage
public void receive(NetworkMessage message) {
// handle incoming message
}
@OnError
public void onError(Session session, Throwable throwable) {
// handle error
System.err.println(throwable.getMessage());
}
}
在上面的处理程序中,问题是ApplicationEventPublisher
是null
,即使它是Autowired,当我调试它时,WebSocket容器似乎正在创建一个newInstance,而没有考虑它的依赖关系,在这里,有人知道如何修复它吗?
1条答案
按热度按时间bvhaajcl1#
要使用Spring-managed bean作为WebSocket处理程序,您可以定义一个自定义的
javax.websocket.server.ServerEndpointConfig.Configurator
类并覆盖其getEndpointInstance()
方法以返回Spring-managed bean示例。要在Jakarta WebSocket应用程序中使用此Configurator类,您可以将以下注解添加到WebSocket端点类: