使用 TCP 在 GDScript 和 Rust 之间发送对象

发布于 2025-01-20 11:09:25 字数 736 浏览 1 评论 0原文

我想将我的游戏连接到 Rust 服务器并进行基于事件的通信。

rust 方面的枚举看起来有点像这样:

enum Event {
    Login(String),
    LoadChunk(Chunk),
    ChunkUpdate(Chunk),
}

我已经使用 StreamPeerTCP 和 std::net::TcpListener 工作了一个非常简单的客户端和服务器,并且我已经可以发送它们之间的字符串是utf8编码的。

现在我想从服务器向客户端发送一个事件。 为此,我将服务器上的事件序列化为 JSON,然后使用 as_bytes() 将此字符串中的字节发送到客户端。

这是客户端上处理从 StreamPeerTCP 接收到的数据的函数:

func _handle_client_data(data: PoolByteArray) -> void:
    var string_data: String = data.get_string_from_utf8();

    var parsed_data: Object = JSON.parse(string_data);

但现在由于输入松散,我不知道应该如何访问对象中的任何字段。

我认为我做的事情根本上是错误的,但我不知道有什么更好的解决方案。

谁能帮助我解决这样的问题?

I want to connect my game to a rust server and have an event based communication.

The enum on the rust side looks somewhat like this:

enum Event {
    Login(String),
    LoadChunk(Chunk),
    ChunkUpdate(Chunk),
}

I already got a very simple Client and Server using StreamPeerTCP and std::net::TcpListener working and I can already send utf8 encoded strings between them.

Now I want to send an event from the server to the client.
To do so I serialize the event on the server into JSON and then send the bytes from this string to the client using as_bytes().

This is the function on the client which processes the data received from StreamPeerTCP:

func _handle_client_data(data: PoolByteArray) -> void:
    var string_data: String = data.get_string_from_utf8();

    var parsed_data: Object = JSON.parse(string_data);

But now due to loose typing I do not know how I should access any fields from the object.

I think I am doing something fundamentally wrong but I do not know any better solution.

Can anyone help me on how to approach such a problem?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

我只土不豪 2025-01-27 11:09:25

我使用 GDNative 将整个 TCP 客户端移至 Rust 和 tokio。

Rust 和 GDscript 语言之间的接口仍然是 JSON。

客户端发出一个 Event 信号,该信号由 TcpClientWrapper 在此函数中处理:

func handle_event(event: String):
    var type: String = event.split('"', true, 2)[1];
    match type:
        "Error":
            var kind: String = JSON.parse(event).result.Error;
            self.emit_signal("Error", kind);
        "Token":
            var token: Array = JSON.parse(event).result.Token;
            self.emit_signal("Token", token);
        _:
            # ChunkUpdate not yet implemented
            print("invalid event type");
    

Rust 中的原始事件:

pub enum ServerToClient {
    Error(ClientError),
    Token(Token),
    ChunkUpdate(Chunk),
}

为了与客户端交互,我在 ClientTcpWrapper 中有此脚本:

extends Node;

# position and string
signal ChunkUpdate(position, chunk);
# array
signal Token(token);
# string
signal Error(kind);

export var host: String = "0.0.0.0:8000";

onready var client: Node = self.get_node("TcpClient");

func _ready():
    client.establish_connection(host);
    
    client.connect("Event", self, "handle_event");
    
func connection_established() -> bool:
    return client.connection_established();
    
func register(name: String):
    var string = '{"Register":{"name":"' + name + '"}}';
    client.send(string);

func move(pos: Vector3):
    var x = str(pos.x).pad_decimals(10);
    var y = str(pos.y).pad_decimals(10);
    var z = str(pos.z).pad_decimals(10);
    var string = '{"Move":{"coord":[' + x + "," + y + "," + z + ']}}';
    
    client.send(string);
    
func handle_event(event: String):
    var type: String = event.split('"', true, 2)[1];
    match type:
        "Error":
            var kind: String = JSON.parse(event).result.Error;
            self.emit_signal("Error", kind);
        "Token":
            var token: Array = JSON.parse(event).result.Token;
            self.emit_signal("Token", token);
        _:
            print("invalid event type");

I moved the whole TCP-client to rust and tokio using GDNative.

The interface between the rust and GDscript languages is still JSON.

the client emits a Event signal which gets handled in this function by the TcpClientWrapper:

func handle_event(event: String):
    var type: String = event.split('"', true, 2)[1];
    match type:
        "Error":
            var kind: String = JSON.parse(event).result.Error;
            self.emit_signal("Error", kind);
        "Token":
            var token: Array = JSON.parse(event).result.Token;
            self.emit_signal("Token", token);
        _:
            # ChunkUpdate not yet implemented
            print("invalid event type");
    

The original Event in rust:

pub enum ServerToClient {
    Error(ClientError),
    Token(Token),
    ChunkUpdate(Chunk),
}

To interface With the client I have this script in ClientTcpWrapper:

extends Node;

# position and string
signal ChunkUpdate(position, chunk);
# array
signal Token(token);
# string
signal Error(kind);

export var host: String = "0.0.0.0:8000";

onready var client: Node = self.get_node("TcpClient");

func _ready():
    client.establish_connection(host);
    
    client.connect("Event", self, "handle_event");
    
func connection_established() -> bool:
    return client.connection_established();
    
func register(name: String):
    var string = '{"Register":{"name":"' + name + '"}}';
    client.send(string);

func move(pos: Vector3):
    var x = str(pos.x).pad_decimals(10);
    var y = str(pos.y).pad_decimals(10);
    var z = str(pos.z).pad_decimals(10);
    var string = '{"Move":{"coord":[' + x + "," + y + "," + z + ']}}';
    
    client.send(string);
    
func handle_event(event: String):
    var type: String = event.split('"', true, 2)[1];
    match type:
        "Error":
            var kind: String = JSON.parse(event).result.Error;
            self.emit_signal("Error", kind);
        "Token":
            var token: Array = JSON.parse(event).result.Token;
            self.emit_signal("Token", token);
        _:
            print("invalid event type");
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文