背景
事实上,在 3.x 版本中,一个明确的目标是使远程功能更容易使用并且更符合人体工程学,您可以在此处阅读更多关于这样做的动机。
为了帮助实现这一目标,我们从 SDK 表面移除了 Protobuf(我们仍在内部使用它),并提出了消息和类型抽象。
由于嵌入式 SDK 被认为更像是高级用户 SDK,因此您仍然可以使用 Protobuf 与远程功能进行通信。虽然这也是我们希望简化的事情,但存在一些技术问题。
类型值
这是一个在内部使用的 Protobuf 消息,每当远程函数调用另一个远程函数时。
message TypedValue {
string typename = 1;
// has_value is set to differentiate a zero length value bytes explicitly set,
// or a non existing value.
bool has_value = 2;
bytes value = 3;
}
typename字段是由用户定义的 / 形式的字符串。例如:“com.kkrugler.types/MyEvent”。StateFun 将传递该字符串 as-us,并将其视为不透明类型标记,由远程 SDK 端的用户解释。
has_value在这种情况下,需要始终设置为 true。(发送没有有效负载的消息被认为是错误的。
values - 是typename类型的序列化、不透明值。
嵌入式功能
需要调用远程函数的嵌入式函数需要使用TypedValue实例调用它。远程 SDK 知道如何将TypedValue转换为Message类。
替换任何
这是使用 TypedValue 包装 Protobuf 消息的有用方法:
public static <M extends Message> TypedValue pack(M message) {
return TypedValue.newBuilder()
.setTypename("type.googleapis.com/" + message.getDescriptorForType().getFullName())
.setHasValue(true)
.setValue(message.toByteString())
.build();
}
然后,像这样简单地使用它:
MyProtobufEvent myProtobufEvent = MyProtobufEvent.newBuilder() ... build();
context.send(.., pack(myProtobufEvent));
在远程 SDK 端(假设 Python,因为您已经提到过):
from statefun import make_protobuf_type
MyProtobufEventType = make_protobuf_type(MyProtobufEvent)
...
myProtobufEvent = message.as_type(MyProtobufEventType)