我正在尝试在客户端和服务器应用程序之间实现 Web Socket 通信。我的后端服务是一个 Spring Boot 应用程序,它通过套接字发送关于某个主题的自定义消息对象,而我的基于 Angular 的前端应用程序应该订阅套接字端点上的主题并接收数据。我在 Angular 应用程序中使用
@stomp/stompjs
(v7.0.0) 包通过 STOMP 实现 Web 套接字消息传递。然而,在stompjs代码中初始化WebSocket对象时似乎失败了。
后端应用代码如下: pom.xml:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
WebSocket配置:
package com.jh.demo.config;
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 {
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
registry.enableSimpleBroker("/topic");
registry.setApplicationDestinationPrefixes("/app");
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/ws-endpoint");
registry.addEndpoint("/ws-endpoint").withSockJS();
registry.addEndpoint("/ws-endpoint").setAllowedOrigins("*").withSockJS();
}
}
正在发出消息的我的服务类代码(通过计划的 cron 作业):
import org.springframework.messaging.simp.SimpMessagingTemplate;
// other imports here...
@Service
@Transactional
public class MyServiceImpl implements MyService {
private final SimpMessagingTemplate messagingTemplate;
public MyServiceImpl (SimpMessagingTemplate messagingTemplate) {
this.messagingTemplate = messagingTemplate;
}
// some code here...
@Scheduled(fixedDelay = 5000)
public void longRunningTask()
{
System.out.println("This is a cron job running");
JobStatusMessage jobStatusMessage = new JobStatusMessage(
Instant.now().toEpochMilli(),
"Job is Running",
JobStatus.RUNNING
);
messagingTemplate.convertAndSend("/topic", jobStatusMessage );
}
}
在我的 Angular 应用程序中,我使用节点安装了 stomp/stompjs v7.0.0:
$ npm install @stomp/stompjs
我创建了一个普通的角度组件来启动与 Web 套接字端点的连接以接收数据:
import { Component, OnInit } from '@angular/core';
import { Client, Message } from '@stomp/stompjs';
@Component({
selector: 'jhi-web-socket-impl',
templateUrl: './web-socket-impl.component.html',
styleUrls: ['./web-socket-impl.component.scss'],
})
export class WebSocketImplComponent implements OnInit {
public message: string;
private client: Client;
constructor() {
this.client = new Client();
this.message = '';
this.client.configure({
brokerURL: 'ws://localhost:8090/ws-endpoint',
onConnect: () => {
this.client.subscribe('/topic', (message: Message) => {
this.message = message.body;
console.log('Received message:', this.message);
});
},
onChangeState(state) {
console.log('State Changed to: ', state); // 0=active, 1=deactivating,2=inactive
},
onStompError(frame) {
console.log("Stomp Error Ocurred with frame: ",frame.body);
},
onUnhandledFrame(frame) {
console.log("Unhandled frame: ", frame.body);
},
onUnhandledReceipt(frame) {
console.log("Unhandled Recept: ", frame.body);
},
onUnhandledMessage(frame) {
console.log("Unhandled Message: ", frame.body);
},
onWebSocketClose() {
"Web Socket Closed"
},
onWebSocketError() {
"Web Socket Error Occurred"
},
onDisconnect(frame) {
console.log("Disconnected :", frame.body);
},
});
}
ngOnInit(): void {
console.log('WebSocketImplComponent ngOnInit() called');
this.client.activate();
}
}
现在,当我运行应用程序时,后端应用程序运行良好,没有任何错误,但前端没有收到数据。这是控制台显示的内容:
当点击错误源时,它会显示出现问题的代码行:
0 被打印意味着
ActivationStatus
根据本文档设置为“ACTIVE”https://stomp-js.github.io/api-docs/develop/miscellaneous/enumerations.html 但之后没有发生任何其他事情它会不断将连接失败日志打印到控制台,而不显示任何消息。
这里需要注意的一件事是我可以使用Postman成功连接到服务器套接字Endpoint:
如果有人能指出的话,我的实施中可能出了什么问题或遗漏了什么? 谢谢。
只保留这个代码就足够了。
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/ws-endpoint").setAllowedOrigins("*");
}