如何解决Websocket 不适用于 Spring Boot 应用程序和 Angular 前端
我查看并尝试了很多,但我找不到问题的原因... 我有一个 JHipster 生成的应用程序,它由一个 Spring Boot 应用程序和一个有角度的前端组成,我想使用 websockets 进行更新。为此,我使用 Stomp 和 SockJs
连接本身已经不起作用。 我收到以下错误:
WebSocket connection to 'ws://localhost:9000/updates/websocket/447/xxudq4ni/websocket' Failed: WebSocket is closed before the connection is established.
这是对端口 9000 的调用,然后将其代理到端口 8080 下的实际后端。 如果我直接调用8080端口下的后端,我得到:
WebSocket connection to 'ws://localhost:8080/updates/websocket/156/mg0dspp2/websocket' Failed: Error during WebSocket handshake: Unexpected response code: 200
我真的没有看到实际的响应是什么,但我想它是 JHIpster 错误消息“发生了错误”,并且此 html 返回的 http 状态码为 200。
我不知道实际问题是什么......我关注了这个intro here和其他几个...... 这是我的后端:
WebsocketConfig:
@Configuration
@EnableWebSocketMessagebroker
public class WebSocketConfig implements WebSocketMessagebrokerConfigurer {
public static final String IP_ADDRESS = "IP_ADDRESS";
@Override
public void configureMessagebroker(MessagebrokerRegistry config) {
config.enableSimplebroker("/topic");
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry
.addEndpoint("/updates/websocket")
//.setHandshakeHandler(defaultHandshakeHandler())
.setAllowedOrigins("*")
.withSockJS()
.setClientLibraryUrl("https://cdn.jsdelivr.net/npm/sockjs-client@1.5.0/dist/sockjs.min.js");
//.setInterceptors(httpSessionHandshakeInterceptor());
}
private DefaultHandshakeHandler defaultHandshakeHandler() {
return new DefaultHandshakeHandler() {
@Override
protected Principal determineUser(ServerHttpRequest request,WebSocketHandler wsHandler,Map<String,Object> attributes) {
Principal principal = request.getPrincipal();
if (principal == null) {
Collection<SimpleGrantedAuthority> authorities = new ArrayList<>();
authorities.add(new SimpleGrantedAuthority(AuthoritiesConstants.ANONYMOUS));
principal = new AnonymousAuthenticationToken("WebsocketConfiguration","anonymous",authorities);
}
return principal;
}
};
}
@Bean
public HandshakeInterceptor httpSessionHandshakeInterceptor() {
return new HandshakeInterceptor() {
@Override
public boolean beforeHandshake(
ServerHttpRequest request,ServerHttpResponse response,Object> attributes
) throws Exception {
if (request instanceof ServletServerHttpRequest) {
ServletServerHttpRequest servletRequest = (ServletServerHttpRequest) request;
attributes.put(IP_ADDRESS,servletRequest.getRemoteAddress());
}
return true;
}
@Override
public void afterHandshake(
ServerHttpRequest request,Exception exception
) {}
};
}
}
控制器:
@Controller
public class UpdateController {
private static final Logger log = LoggerFactory.getLogger(UpdateController.class);
@MessageMapping("/updates/websocket")
@SendTo("/topic/trucks")
public UpdateDto send(UpdateDto dto) {
return dto;
}
}
前端:
connect(): void {
if (this.stompClient?.connected || this.called) {
return;
}
this.called = true;
// building absolute path so that websocket doesn't fail when deploying with a context path
let url = '/updates/websocket';
url = this.location.prepareExternalUrl(url);
var socket = new SockJS(url);
this.stompClient = Stomp.over(socket);
this.stompClient.connect({},(frame) => {
this.connectionSubject.next();
this.sendActivity();
this.routerSubscription = this.router.events
.pipe(filter((event: Event) => event instanceof NavigationEnd))
.subscribe(() => this.sendActivity());
},error => {
console.log(error);
});
}
我在 Windows 上,我使用 Chrome 进行开发。但它在 FireFox 中也不起作用,所以我认为它与平台无关。 任何帮助将不胜感激。非常感谢!
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。