Какие существуют правильные методы для обработки сигналов от клиента на сервере?

Как настроить обработку сигналов с клиента на сервере и обратно в GODOT 3, используя NetworkedMultiplayerENet, чтобы вызывать функции на сервере и возвращать результат обратно на клиенте? Например, у меня на клиенте есть функция `_on_Start_button_pressed()`, и мне нужно вызвать функцию на сервере `_create_room()`, генерирующую 4-х буквенный код. Попробовал использовать `rpc_id(1, "_create_room", username)`, но что-то не получается. Как это сделать правильно?
  • 13 января 2024 г. 19:18
Ответы на вопрос 2
В Godot Engine для сетевого взаимодействия используется система удаленных вызовов (Remote Procedure Calls - RPCs). Для корректной работы RPC вам нужно правильно настроить и сетевой проект, и обработку сигналов на клиенте и сервере.

Прежде всего, убедитесь, что вы подключились к серверу и настроили `NetworkedMultiplayerENet`, включая методы авторизации и отключения. Кроме того, нужно корректно настроить группы сетевых команд (network peers), чтобы сигналы отправлялись на нужный экземпляр:

1. **Создание сервера**:
```gdscript
var server = NetworkedMultiplayerENet.new()
server.create_server(port, max_clients)
get_tree().set_network_peer(server)
```

2. **Подключение клиента к серверу**:
```gdscript
var client = NetworkedMultiplayerENet.new()
client.create_client(ip, port)
get_tree().set_network_peer(client)
```

3. **Настройка `rpc` и `rpc_id`**:
   - Для вызова функции на сервере, у клиента должна быть функция, помеченная как `remote` или `puppet` (если сервер вызывает функцию на клиенте).
   - Убедитесь, что функции, которые должны быть вызваны с помощью RPC, помечены правильным декоратором (`remote`, `sync`, `master`, `puppet`).

На стороне **сервера**:
```gdscript
# Удостоверьтесь, что сервер знает об этой функции как о remote function.
remote func _create_room(user_id):
    var room_code = _generate_room_code() # Ваша логика создания комнаты
    # ... Другой код для создания комнаты ...
    # Ответ клиенту
    rpc_id(user_id, "_on_room_created", room_code)

# Генерация 4-х буквенного кода
func _generate_room_code():
    var characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    var code = ""
    for _i in 4:
        code += str(characters[randi() % characters.length()])
    return code
```

На стороне **клиента**:
```gdscript
func _on_Start_button_pressed():
    # rpc_id отправляет вызов функции на экземпляр с определенным ID (в данном случае, сервер с ID 1).
    rpc_id(1, "_create_room", get_tree().get_network_unique_id())

# Удостоверьтесь, что клиент знает об этой функции как о remote function.
remote func _on_room_created(room_code):
    # Обработка полученного кода комнаты на клиенте.
    print("Room created with code: ", room_code)
```

Не забудьте, что перед вызовом функций удалённого вызова, должен быть установлен сетевой пир (network peer) и сеанс подключения должен быть активен. Только после этого клиент и сервер могут отправлять друг другу RPC-команды.

Если вы столкнулись с проблемами при вызове `rpc_id`, убедитесь в следующем:
- Процедура подключения была успешно выполнена и клиент подключился к серверу.
- Используемые функции `_create_room` и `_on_room_created` правильно помечены как `remote`.
- Идентификатор узла `1` действительно соответствует серверу (идентификатор сервера по умолчанию в рамках сети), иначе нужно использовать правильный ID.
- Сервер настроен на прием входящих соединений и обработку RPC.
- Обработка состояний ошибок после вызова методов подключения (`create_server` или `create_client`) и при отправке RPC-выз
Для вызовов rpc у вас должна быть одинаковый путь до нода. Если я не ошибаюсь, то при rpc вызове _create_room из root/MainNode/MainMenuUI на клиенте, Godot попытается найти на сервере такой же путь root/MainNode/MainMenuUI, но не найдет. 

Я бы создал что-то вроде root/MainNode/Multiplayer/RoomManager на клиенте и на сервере (у них должен быть одинаковый путь в дереве нодов). В RoomManager на клиенте сделал бы функцию

В RoomManager на сервере сделал бы функцию

То есть суть в том, чтобы у нодов, вызывающих и принимающих rpc в дереве был одинаковый путь на клиенте и сервере.

А так, это все вроде в документации есть ;-) https://docs.godotengine.org/ru/3.x/tutorials/netw...
Похожие вопросы