如何解决使用 Spring 的 WebSocket 配置问题
我正在做一些小项目,使用户可以向特定用户发送消息的聊天服务。 我遵循了使用 WebSocket 库的概念,然后将其应用到我的项目代码中。
我想我在将消息发送到特定的消息目的地时遇到了问题。
例如,如果某人的Id为'1',那么他想向'2'的用户发送一条消息,另外添加Item id(这是我项目的不同模型),我会的目的地喜欢发送的是:/user/1/2/1/queue/messages。
我在 spring 中编写了一个 Websocket Config 代码,控制器如下所示。
@Configuration
@EnableWebSocketMessagebroker
public class WebSocketConfig implements WebSocketMessagebrokerConfigurer {
@Override
public void configureMessagebroker(MessagebrokerRegistry config) {
config.enableSimplebroker("/user");
config.setUserDestinationPrefix("/user");
config.setApplicationDestinationPrefixes("/app");
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry
.addEndpoint("/ws")
.setAllowedOriginPatterns("*")
.withSockJS();
}
@Override
public boolean configureMessageConverters(List<MessageConverter> messageConverters) {
System.out.println("messageConverters = " + messageConverters);
DefaultContentTypeResolver resolver = new DefaultContentTypeResolver();
resolver.setDefaultMimeType(MimeTypeUtils.APPLICATION_JSON);
MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
converter.setobjectMapper(new ObjectMapper());
converter.setContentTypeResolver(resolver);
messageConverters.add(converter);
return false;
}
}
控制器.java
@MessageMapping("/chat")
@CrossOrigin
public void processMessage(@Payload MessageDto messageDto) {
System.out.println("messageDto = " + messageDto);
messageService.createMessage(messageDto);
}
MessageService.java
@Transactional
public void createMessage(@Payload MessageDto messageDto) {
Message originMessage = Message.builder()
.senderId(messageDto.getSenderId())
.receiverId(messageDto.getReceiverId())
.chatId(String.format("%s_%s_%s",messageDto.getSenderId(),messageDto.getReceiverId(),messageDto.getItemId()))
.messageStatus(MessageStatus.RECEIVED)
.content(messageDto.getContent())
.build();
messageRepository.save(originMessage);
Message createdMessage = Message.builder()
.senderId(messageDto.getSenderId())
.receiverId(messageDto.getReceiverId())
.chatId(String.format("%s_%s_%s",messageDto.getItemId()))
.messageStatus(MessageStatus.RECEIVED)
.content(messageDto.getContent())
.build();
messageRepository.save(createdMessage);
Member sender = memberService.searchMemberById(originMessage.getSenderId());
Member receiver = memberService.searchMemberById(originMessage.getReceiverId());
String destination1 = "/user/" + sender.getId() + "/" + receiver.getId() + "/" + messageDto.getItemId() + "/queue/messages";
String destination2 = "/user/" + receiver.getId() + "/" + sender.getId() + "/" + messageDto.getItemId() + "/queue/messages";
simpMessagingTemplate.convertAndSend(
destination1,originMessage
);
simpMessagingTemplate.convertAndSend(
destination2,originMessage
);
}
<html>
<head>
<title>Chat WebSocket</title>
<!-- <script src="/webjars/sockjs-client/1.0.2/sockjs.min.js"></script>-->
<script src="https://cdn.jsdelivr.net/npm/sockjs-client@1/dist/sockjs.min.js"></script>
<script src="/webjars/stomp-websocket/2.3.3/stomp.min.js"></script>
<script type="text/javascript">
var stompClient = null;
function setConnected(connected) {
document.getElementById('connect').disabled = connected;
document.getElementById('disconnect').disabled = !connected;
document.getElementById('conversationDiv').style.visibility
= connected ? 'visible' : 'hidden';
document.getElementById('response').innerHTML = '';
}
function connect() {
var socket = new SockJS("http://localhost:8080/ws");
stompClient = Stomp.over(socket);
// stompClient.debug = null;
stompClient.connect({},onConnected(),onError());
}
const onConnected=()=>{
var senderId = document.getElementById("sender_ID").value;
var receiverId = document.getElementById("receiver_ID").value;
var itemId = document.getElementById("item_ID").value;
console.log(senderId);
setConnected(true);
console.log("/user/" + senderId + "/" + receiverId + "/" + itemId + "/queue/messages");
stompClient.subscribe(
"/user/" + senderId + "/" + receiverId + "/" + itemId + "/queue/messages",function (message) {
var body = JSON.parse(message.body).content;
console.log(body);
showMessage(body);
});
};
function showMessage(message) {
let elementById = document.getElementById("messages");
var tag = document.createElement("p");
var text = document.createTextNode("Message");
tag.appendChild(text);
elementById.appendChild(tag);
}
const onMessageReceived = (msg) =>{
const message = JSON.parse(msg.body);
findChatMessage(message.senderId,message.receiverId,message.itemId);
}
function findChatMessage(senderId,receiverId,itemId) {
return request({
url: "http://localhost:8080" + "/message/" + senderId + "/" + receiverId + "/" + itemId,method: "GET"
});
}
const onError = (err) => {
console.log(err);
};
function disconnect() {
if(stompClient != null) {
stompClient.disconnect();
}
setConnected(false);
console.log("disconnected");
}
function sendMessage() {
var senderId = document.getElementById("sender_ID").value;
var receiverId = document.getElementById("receiver_ID").value;
var itemId = document.getElementById("item_ID").value;
var text = document.getElementById('text').value;
stompClient.send("/app/chat",{},JSON.stringify({'senderId':senderId,'receiverId':receiverId,'content':text,'itemId':itemId}));
}
</script>
</head>
<body onload="disconnect()">
<div>
<div>
<input type="text" id="sender_ID" placeholder="senderId"/>
<input type="text" id="receiver_ID" placeholder="receiverId"/>
<input type="text" id="item_ID" placeholder="itemId"/>
</div>
<br />
<div>
<button id="connect" value="senderId" onclick="connect();">Connect</button>
<button id="disconnect" disabled="disabled" onclick="disconnect();">
disconnect
</button>
</div>
<br />
<div id="conversationDiv">
<input type="text" id="text" placeholder="Write a message..."/>
<button id="sendMessage" onclick="sendMessage();">Send</button>
<p id="response"></p>
</div>
<div id="messages">
</div>
</div>
</body>
</html>
为了显示我的情况,当我点击下面的“连接”按钮时
发送一些消息后,
有趣的是,当然,消息数据很好地存储在我的数据库中,我无法使用 IntelliJ 中的 Debug 弄清楚。
我尝试在 messageservice 的 convertAndSend 方法中设置断点,但是在那里浏览整个流程太庞大了。
所以,为了结束我的问题,我知道如果 websocket 协议构建良好,它会显示像 MESSAGE 这样的协议消息,显示我指定的目的地,并根据我愚蠢的 HTML 代码,我添加了 console.log(body)所以控制台显示其他东西对吗?
但我不知道我在配置代码中遗漏了什么或做错了什么。
请帮我解决它或问我任何我没有提到的问题。
谢谢。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。