问题描述
我正在 Spring Boot 上使用 Stomp 和 Rabbitmq 开发一个聊天应用程序。
当客户端向服务器发送消息(Spring Boot)时,服务器将消息保存到数据库中,然后将消息发送给接收者。
我想做的是在客户端发送消息时向客户端发送一个带有 function test(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var ws = ss.getSheetByName("SalesPlan");
const lastData = ws.getRange(2,1,6).getValues();
WeeklySalesPlan(lastData)
}
function WeeklySalesPlan(lastData){
//Debemos validar de que es un nuevo registro sin procesar
var ss = SpreadsheetApp.getActiveSpreadsheet();
var ws = ss.getSheetByName("SalesPlan");
if(lastData[0][5] == "Unprocessed"){
//Debemos capturar todos los open deals que existen al momento
var ss = SpreadsheetApp.getActiveSpreadsheet();
var activeSheet = ss.getSheetByName("SalesPlanWeekly");
var dateFrom = new Date(lastData[0][1]);
var dateto = new Date(lastData[0][2]);
Logger.log('dateFrom :' + dateFrom)
var salesPlan_MonthFrom = dateFrom.getMonth();
Logger.log("salesPlan_MonthTo: " + salesPlan_MonthTo);
var salesPlan_YearFrom = dateFrom.getYear();
Logger.log("salesPlan_YearFrom: " + salesPlan_YearFrom);
var salesPlan_Product = lastData[0][3];
var salesPlan_Quantity = lastData[0][4];
for(var i = 0; i < 31; i++){
var e = new Date(salesPlan_YearFrom,salesPlan_MonthFrom,i + 1,0);
var day = e.getDay();
var firstWeekBegin = 1;
if(day == 1){
break;
}else{
firstWeekBegin = firstWeekBegin + 1;
}
}
var firstWeekDate = new Date(salesPlan_YearFrom,firstWeekBegin,0);
Logger.log("firstWeekDate: " + firstWeekDate);
}
}
的 RECEIPT
帧,让他们知道他们的消息已保存到数据库中。
我可以从 message-id
类的 RECEIPT
发送 afterMessageHandled()
帧。但它多次发送相同的 ExecutorChannelInterceptor
帧,例如 3 次。
因此,对于一条消息,客户端会收到 3 次相同的 RECEIPT
帧。
这是我的 RECEIPT
,它将消息保存到 ChannelInterceptor
中的数据库
presend()
这是我的 public class StompChannelInterceptor implements ChannelInterceptor {
@Autowired
private ChatService chatService;
@Autowired
private CompositeMessageConverter compositeMessageConverter;
@Override
public Message<?> preSend(Message<?> message,@NonNull MessageChannel channel) {
MessageHeaders messageHeaders = message.getHeaders();
StompHeaderAccessor stompHeaderAccessor = StompHeaderAccessor.wrap(message);
StompCommand stompCommand = stompHeaderAccessor.getCommand();
if (StompCommand.SUBSCRIBE.equals(stompCommand)) {
//validate subscribe
} else if (StompCommand.SEND.equals(stompCommand)) {
System.out.println("presend!!!!!!!!!!!!!!!!!!!");
ChatMessageDTO chatMessageDTO =
(ChatMessageDTO) compositeMessageConverter.fromMessage(message,ChatMessageDTO.class);
chatService.validateAndSaveMessage(chatMessageDTO);
}
return message;
}
}
函数,用于处理传入的消息
MessageMapping
最后,这是我的 @MessageMapping("/chat/send")
public void send(@Payload ChatMessageDTO chatMessageDTO,MessageHeaders messageHeaders) {
System.out.println("send!!!!!!!!!!!!!!!!!!!!!!!!!");
simpMessagingTemplate.convertAndSend(queue,chatMessageDTO);
}
,它在 ExecutorChannelInterceptor
RECEIPT
帧
afterMessageHandled()
如果我运行这段代码,我会得到这个日志,它表明 @Override
public void configureClientInboundChannel(ChannelRegistration registration) {
registration.interceptors(chatChannelInterceptor());
registration.interceptors(new ExecutorChannelInterceptor() {
@Override
public void afterMessageHandled(Message<?> inMessage,MessageChannel inChannel,MessageHandler handler,Exception ex) {
StompHeaderAccessor inAccessor = StompHeaderAccessor.wrap(inMessage);
if (StompCommand.SEND.equals(inAccessor.getCommand())) {
System.out.println("afterMessageHandled");
if (outChannel != null) {
StompHeaderAccessor outAccessor = StompHeaderAccessor.create(StompCommand.RECEIPT);
outAccessor.setSessionId(inAccessor.getSessionId());
outAccessor.setReceiptId(receipt);
outAccessor.setLeaveMutable(true);
outAccessor.setMessageId(inAccessor.getMessageId());
Message<byte[]> outMessage =
MessageBuilder.createMessage(new byte[0],outAccessor.getMessageHeaders());
outChannel.send(outMessage);
}
}
}
});
}
被调用了 3 次。
afterMessageHandled()
所以,问题是
-
有什么方法可以在
presend!!!!!!!!!!!!!!!!!!! afterMessageHandled!!!!!!!!!!!!!!!!!!!!! afterMessageHandled!!!!!!!!!!!!!!!!!!!!! send!!!!!!!!!!!!!!!!!!!!!!!!! afterMessageHandled!!!!!!!!!!!!!!!!!!!!!
之后立即向客户端发送一次 RECEIPT 帧,因为我想在确认消息已发送后发送 RECEIPT 帧已保存到数据库中发生在presend()
中? -
请问可以更改
presend()
中的负载或标头吗?
解决方法
我发现对 afterHanldedMessage() 的每次调用都带有不同的处理程序。所以你可以根据不同的处理程序做你想做的。您可能想要执行 If(handler instanceof SomeHandlerClass)。