WebSocketSession.send不执行任何操作



我正在编写一个游戏,当玩家结束回合时,我想通知对手该轮到他玩了。

所以我将WebSocketSessions存储在";玩家";类,所以我只需要获得一个播放器的实例就可以访问他的websocketsession。

问题是当我使用";发送";存储在一个"文件"中的websocketsession的方法;玩家";例子

以下是我的代码,用于将WebSocketSession存储在播放器对象中,它实际上可以正确地从前端接收消息,并且能够发回消息,并且它可以工作:

@Component("ReactiveWebSocketHandler")
public class ReactiveWebSocketHandler implements WebSocketHandler {

@Autowired
private AuthenticationService authenticationService;

@Override
public Mono<Void> handle(WebSocketSession webSocketSession) {
Flux<WebSocketMessage> output = webSocketSession.receive()
.map(msg -> {
String payloadAsText = msg.getPayloadAsText();
Account account = authenticationService.getAccountByToken(payloadAsText);
Games.getInstance().getGames().get(account.getIdCurrentGame()).getPlayerById(account.getId()).setSession(webSocketSession);
return "WebSocketSession id: " + webSocketSession.getId();
})
.map(webSocketSession::textMessage);
return webSocketSession
.send(output);
}
}

这是我用来通知对手球员该上场的代码;opponentSession.send";方法似乎并没有产生结果,并没有错误消息,而且看起来我在前端什么也没收到。会话的ID与handle方法中的ID相同,所以我认为会话对象很好,而且当我进行测试时,websocket会话已经打开并准备好了:

@RequestMapping(value = "/game/endTurn", method = RequestMethod.POST)
GameBean endTurn(
@RequestHeader(value = "token", required = true) String token) {
ObjectMapper mapper = new ObjectMapper();
Account account = authenticationService.getAccountByToken(token);
gameService.endTurn(account);
Game game = gameService.getGameByAccount(account);
//GameBean opponentGameBean = game.getOpponentGameState(account.getId());
//WebSocketMessage webSocketMessage = opponentSession.textMessage(mapper.writeValueAsString(opponentGameBean));
WebSocketSession opponentSession = game.getPlayerById(game.getOpponentId(account.getId())).getSession();
WebSocketMessage webSocketMessage = opponentSession.textMessage("test message");
opponentSession.send(Mono.just(webSocketMessage));
return gameService.getGameStateByAccount(account);
}
}

你可以在屏幕截图上看到handle方法工作正常,我可以发送和接收消息。Websocket输入和输出

有人知道我如何使opponentSession.send方法正确工作,以便我可以在前端接收消息吗?

您正在为您的websocket使用反应堆栈,WebSocketSession#发送返回一个Mono<Void>,但您没有订阅这个Mono(您只是组装了它(,所以在订阅它之前不会发生任何事情。

在您的端点中,它看起来不像是在使用webflux,所以您处于同步世界中,所以除了block,您别无选择

opponentSession.send(Mono.just(webSocketMessage)).block();

如果你正在使用webflux,那么你应该改变你的方法,返回一个Mono,并做一些类似的事情:

return opponentSession.send(Mono.just(webSocketMessage)).then(gameService.getGameStateByAccount(account));

如果你不熟悉这一点,你应该看看projectreactor和WebFlux

相关内容

最新更新