我使用 Spring 4 通过 WebSockets 开发实时通知系统。
源代码如下:
WebSocketConfig:
@Configuration
@EnableScheduling
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/lrt").withSockJS();
}
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
registry.enableSimpleBroker("/queue/", "/topic/");
registry.setApplicationDestinationPrefixes("/app");
}
}
LRTStatusListener:
@Service
public class LRTStatusListener implements ApplicationListener<BrokerAvailabilityEvent>{
private static final Logger LOG = LoggerFactory.getLogger(LRTStatusListener.class);
private final static long LRT_ID = 1234567890;
private final static String LRT_OWNER = "Walter White";
private final LRTStatusGenerator lrtStatusGenerator = new LRTStatusGenerator(LRT_ID, LRT_OWNER);
private final MessageSendingOperations<String> messagingTemplate;
private AtomicBoolean brokerAvailable = new AtomicBoolean();
@Autowired
public LRTStatusListener(MessageSendingOperations<String> messagingTemplate) {
this.messagingTemplate = messagingTemplate;
}
@Override
public void onApplicationEvent(BrokerAvailabilityEvent event) {
this.brokerAvailable.set(event.isBrokerAvailable());
}
@Scheduled(fixedDelay=2000)
public void sendLRTStatus() {
LRTStatus lrtStatus = this.lrtStatusGenerator.generateLRTStatus();
if (LOG.isTraceEnabled())
LOG.trace("Sending LRT status");
if (this.brokerAvailable.get())
this.messagingTemplate
.convertAndSend("/topic/status" + lrtStatus.getLRTId(), lrtStatus);
}
// Random status generator
private static class LRTStatusGenerator {
private LRTStatus lrtStatus;
public LRTStatusGenerator(long lrtId, String owner) {
lrtStatus = new LRTStatus(lrtId, owner, getCurrentTimestamp(), generateLRTStatusMessage());
}
public LRTStatus generateLRTStatus() {
lrtStatus.setMessage(generateLRTStatusMessage());
return lrtStatus;
}
private String getCurrentTimestamp() {
Date date = new Date();
Timestamp timestamp = new Timestamp(date.getTime());
return timestamp.toString();
}
private String generateLRTStatusMessage() {
String statusMessage;
switch ((int) Math.random() * 2) {
case 1:
statusMessage =
"HANK: What? You want me to beg? You're the smartest guy I ever met. " +
"And you're too stupid to see... he made up his mind ten minutes ago.";
break;
case 2:
statusMessage =
"WALTER: That's right. Now say my name. " +
"- DECLAN: ...You're Heisenberg. - WALTER: You're goddamn right.";
break;
default:
statusMessage =
"WALTER: I am not in danger, Skyler. I am the danger! " +
"A guy opens his door and gets shot and you think that of me? " +
"No. I am the one who knocks!";
break;
}
return statusMessage;
}
}
}
CheckLRTStatusController
@Controller
public class CheckLRTStatusController {
@MessageExceptionHandler
@SendToUser("/topic/errors")
public String handleException(Throwable exception) {
return exception.getMessage();
}
}
应用程序通过每2000毫秒更改一次信息来模拟长时间运行事务(LRT)的状态。
现在,我通过 SockJS 定义客户端来测试WebSocket:
<script src="http://cdn.sockjs.org/sockjs-0.3.min.js"></script>
<script>
var sock = new SockJS('/lrt');
sock.onopen = function() {
console.log('open');
};
sock.onmessage = function(e) {
console.log('message', e.data);
};
sock.onclose = function() {
console.log('close');
};
</script>
连接正常,但我无法看到数据流。
如何正确配置我的应用程序,以便在我的客户端控制台上生成然后路由WebSocket服务器发送的消息?
请注意,我还使用内置 Message Broker ,目的是管理邮件队列。
答案 0 :(得分:4)
这是您目前唯一的JavaScript代码吗?:
<script src="http://cdn.sockjs.org/sockjs-0.3.min.js"></script>
<script>
var sock = new SockJS('/lrt');
sock.onopen = function() {
console.log('open');
};
sock.onmessage = function(e) {
console.log('message', e.data);
};
sock.onclose = function() {
console.log('close');
};
</script>
仅在SockJS上建立与回退的连接,但您没有订阅消息代理。你也需要这样做。
在您当前的设置中,您有:
registry.enableSimpleBroker("/queue/", "/topic/");
您需要创建一个JavaScript STOMP客户端(通过SockJS)订阅这些客户端,例如:
stompClient.subscribe("/topic/status*", function(message) {
...
});
stompClient.subscribe("/queue/whatever", function(message) {
...
});
查看spring-websocket-portfolio应用程序以获取完整的工作示例。