1

我是RSocket世界的新手。 你能告诉我如何将消息从服​​务器发送到 javascript(Angular) 应用程序中的特定观察者吗?我正在创建多人吃豆人游戏,我必须将怪物位置从服务器发送到客户端。我想在其他地方执行此操作,然后是控制器。我知道如何在 spring 到 spring 应用程序中执行此操作,因为我们可以使用 RsocketRequester.route() 将消息发送到客户端的特定端点,但我不知道如何在 js 环境中创建类似的东西。更准确地说,我想在 websocket ( + STOMP) 中做同样的事情。这是示例:

在这里我有确切的端点。我可以使用 SimpleMessagingTemplate( 在每个地方) 发送消息,但是如何在 rsocket 中做类似的事情?客户端:

const ws = new SockJS(this.serverUrl);
    this.stompClient = Stomp.over(ws);
    this.state = new BehaviorSubject<SocketClientState>(SocketClientState.ATTEMPTING);

    this.stompClient.connect({}, (frame) => {
        this.stompClient.subscribe('/pacman/update/monster', (monster) => {
            if (monster.body) {
                this.monsterToUpdate.next(JSON.parse(monster.body));
            }
        });
// other code ...

        this.state.next(SocketClientState.CONNECTED);
    }, (error) => {
        this.state.next(SocketClientState.ERROR);
    });

在 RSocket (js) 中,请求看起来像这样,例如,只有当我们在控制器中处理请求时,我们才能轻松地从服务器订阅响应。(控制器知道将响应发送到哪里)

socket.requestStream({
                data: {
                    'author': 'linustorvalds'
                },
                metadata: String.fromCharCode('tweets'.length) + 'tweets',
            }).subscribe({
                onComplete: () => console.log('complete'),
                onError: error => {
                    console.log(error);
                },
                onNext: payload => {
                    console.log(payload.data);
                },
                onSubscribe: subscription => {
                    console.error('Subskrybuje')
                    subscription.request(2147483647);
                },
            });

服务器

    @Service
public class GameObjectSender implements ISender {

private final SimpMessagingTemplate template;

public GameObjectSender(SimpMessagingTemplate template) {
    this.template = template;
}

@Override
public void send(String destination, GameObject gameObject) {
    // Here i want to send monster position using RScoket
    this.template.convertAndSend(destination, gameObject);
}

@Override
public void sendWithTimestamp(String destination, GameObject gameObject) {
    // Here i want to send monster position using RScoket
    this.template.convertAndSend(destination, gameObject, Map.of("timestamp", System.currentTimeMillis()));
}
}

在这里,我可以使用 SimpMessagingTemplate 将消息发送到特定位置,例如“/pacman/update/monster”(js)。怪物的应用流程看起来像(在服务中创建 5 个线程,它们移动并将所有时间位置发送到客户端(GameObjectSender 在这里注入)):

服务器:

 private void createMonsters() {
    for (int i = 0; i < Game.NUMBER_OF_MONSTERS; i++) {
        int[] position = positionSetterService.getStartPositionForFigure();
        Game.getGame().getMonsters().add(new Monster(i, position[0], position[1], Direction.NONE));

        new Thread(() -> {
            int idMonster = Integer.parseInt(Thread.currentThread().getName());
            logger.info("Stworzylem potwora o id: " + idMonster);
            Monster monster = Game.getGame().getMonsters().get(idMonster);

            while (true) {
                try {
                    Thread.sleep(50);
                    move(monster);
                } catch (InterruptedException e) {
                    logger.error("Przerwano watek potwora");
                    Thread.currentThread().interrupt();
                }
            }
        }, String.valueOf(i)).start();
    }
}

@Override
public void move(Monster monster) {
    int[] position = chasePlayer(monster);
    if (spriteCollisionService.checkCollisionWithMonsters(position[0], position[1])) {
        position[0] = position[0] - (position[0] % 32) + 16;
        position[1] = position[1] - (position[1] % 32) + 16;
    }
    monster.setPositionX(position[0]);
    monster.setPositionY(position[1]);

    Optional<Player> playerToRemove = spriteCollisionService.getPlayerWhoCollideWithMonster(position[0], position[1]);

    if (playerToRemove.isPresent()) {
        resetPreviousDirection();
        logger.info("Monster wpada na Gracza i go zabija");
        Game.getGame().getPlayers().remove(playerToRemove.get());
        this.spriteSender.send("/pacman/remove/player", playerToRemove.get());
    }

    synchronized (Game.getGame().getMonsters()) {
        Game.getGame().getMonsters().remove(monster);
        Game.getGame().getMonsters().add(monster);
    }
    this.spriteSender.send("/pacman/update/monster", monster);
}
4

0 回答 0