我试图将使用AngularJS和Spring Boot的简单示例WebSocket应用放在一起。我正在使用this angularjs websocket library
问题是我无法将任何内容从客户端发送到服务器。前端没有错误,后端没有任何记录。
Websocket配置:
package org.example.project;
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfiguration implements
WebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.enableSimpleBroker("/report");
config.setApplicationDestinationPrefixes("/app");
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/socket").
setAllowedOrigins("*").withSockJS();
}
}
Websocket端点实现:
package org.example.project;
import java.util.Date;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.stereotype.Controller;
@Controller
public class WebSocketController {
private final SimpMessagingTemplate template;
@Autowired
WebSocketController(SimpMessagingTemplate template) {
this.template = template;
}
@MessageMapping("/uc/status/request")
public void onReceivedMessage(String message) {
System.out.println(" THIS CAME FROM WS CLIENT ");
this.template.convertAndSend("/uc/status/report",
"received " + message);
}
}
Angular客户端实现:
'use strict'
var app = angular.module('app', [
'ngWebSocket'
])
app.controller("MyController", function($scope, $http, $websocket) {
// path to the end point is actually /app/uc/status/request
// unable to add end point path when connecting
// and don't know how to subscribe
var ws = $websocket('ws://localhost:8080/socket/websocket/');
ws.onMessage(function(event) {
console.log('message: ', event);
});
ws.onError(function(event) {
console.log("error");
});
ws.onClose(function(event) {
});
ws.onOpen(function(event) {
console.log('connection open');
});
// nothing happens when this call is made
ws.send("message content", "/app/uc/status/request");
});
答案 0 :(得分:1)
this.template.convertAndSend("/uc/status/report",
"received " + message);
您的目的地(第一个参数)错误。您使用目标前缀/report
注册了经纪人频道,因此您必须发布/订阅该目标前缀。因此将其更改为
this.template.convertAndSend("/report",
"received " + message);
并且让前端客户端订阅并发送到特定的目的地
// sorry I dont work with angular below is mostly copied.
connect() {
const socket = new SockJS('/socket');
this.stompClient = Stomp.over(socket);
const _this = this;
this.stompClient.connect({}, function (frame) {
_this.stompClient.subscribe('/report', function (data) {
// do something with received data
});
});
}
// send message to destination
send() {
this.stompClient.send(
'/app/uc/status/request', // roughly put, ur applicationDestinationPrefix + @MessageMapping
{},
"my message"
);
}
根据应用程序的需要,您可以在/report
之后添加所需的任意路径,例如/report/myreport1, /report/myreport2
,以用于多个主题或队列。请注意,您在enableSimpleBroker("/report")
中定义的前缀在命名意义上并不重要,因为它对于Spring的内存中消息代理非常有用。对于其他专用经纪人,例如ActiveMQ或RabbitMQ,您应该将/topic
用于一对多(许多订户),将/queue
用于一对一(一个接收者)。进一步了解https://docs.spring.io/spring-framework/docs/5.0.0.M1/spring-framework-reference/html/websocket.html