thejinchao / turbolink Goto Github PK
View Code? Open in Web Editor NEWTurboLink is an unreal engine plugin enables Google gRPC work with Unreal Engine using C++ and Blueprint
License: MIT License
TurboLink is an unreal engine plugin enables Google gRPC work with Unreal Engine using C++ and Blueprint
License: MIT License
if I disable unity build for Turbolink plugin. There will be compiling error.
public TurboLinkGrpc(ReadOnlyTargetRules Target) : base(Target)
{
DefaultBuildSettings = BuildSettingsVersion.Latest;
PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs;
TurboLinkPlatformInstance = GetTurboLinkPlatformInstance(Target);
bUseUnity = false;
PublicDependencyModuleNames.AddRange(
new string[]
{
"Core"
}
);
Errors
memory(3089): [C2027] use of undefined type 'grpc::ClientAsyncReaderWriter<Greeter::WatchRequest,Greeter::NowResponse>'
GreeterMarshaling.h(23): [C2027] see declaration of 'grpc::ClientAsyncReaderWriter<Greeter::WatchRequest,Greeter::NowResponse>'
memory(3088): [C2027] while compiling class template member function 'void std::default_delete<T>::operator ()(_Ty *) noexcept const'
memory(3198): [C2027] see reference to function template instantiation 'void std::default_delete<T>::operator ()(_Ty *) noexcept const' being compiled
memory(3125): [C2027] see reference to class template instantiation 'std::default_delete<T>' being compiled
TurboLinkGrpcContext.h(69): [C2027] see reference to class template instantiation 'std::unique_ptr<T,std::default_delete<T>>' being compiled
TurboLinkGrpcContext.h(196): [C2027] see reference to class template instantiation 'TGrpcContext<T,R>' being compiled
GreeterContext.h(33): [C2027] see reference to class template instantiation 'GrpcContext_Stream_Stream<TimeService_Watch_ReaderWriter,Greeter::NowResponse,Greeter::WatchRequest>' being compiled
memory(3089): [C2338] can't delete an incomplete type
memory(3090): [C4150] deletion of pointer to incomplete type 'grpc::ClientAsyncReaderWriter<Greeter::WatchRequest,Greeter::NowResponse>'; no destructor called
GreeterMarshaling.h(23): [C4150] see declaration of 'grpc::ClientAsyncReaderWriter<Greeter::WatchRequest,Greeter::NowResponse>'
Platform.h(1148): [C4005] see previous definition of 'TEXT'
Platform.h(1148): [C4005] see previous definition of 'TEXT'
Platform.h(1148): [C4005] see previous definition of 'TEXT'
Platform.h(1148): [C4005] see previous definition of 'TEXT'
Platform.h(1148): [C4005] see previous definition of 'TEXT'
Platform.h(1148): [C4005] see previous definition of 'TEXT'
Platform.h(1148): [C4005] see previous definition of 'TEXT'
Platform.h(1148): [C4005] see previous definition of 'TEXT'
Platform.h(1148): [C4005] see previous definition of 'TEXT'
Microsoft.MakeFile.targets(44, 5): [MSB3073] The command "D:\Unreal\EpicUnreal\UE_5.1\Engine\Build\BatchFiles\Build.bat GrpcTestEditor Win64 Development -Project="D:\GitRepo\GrpcTest\GrpcTest.uproject" -WaitMutex -FromMsBuild" exited with code 6.
Probably we can fix this by change to include xxx.grpc.pb.h rather than xxx.pb.h in XXXMarshaling.h
Shipping build of the game crashes on iOS with the following message:
*** error for object %p: pointer being freed was not allocated
> MyGame-IOS-Shipping > MyGame-IOS-Shipping(45544,0x16be63000) malloc: *** error for object 0x4000000: pointer being freed was not allocated
According to captured crash call stacks the above error can come from a variety of places in plugin source code depending on the user's game flow (see the attachments). In some cases it can be "fixed" by not freeing up memory which was allocated for certain structs that the plugin's API exposes however that introduces memory leaks and doesn't feel like a proper solution by any means.
Callstack1.txt
Callstack2.txt
Callstack3.txt
Shipping build of the game is distributed via TestFlight and that's the only scenario when crash can be reproduced. The development build has been tested on several iOS devices and this configuration works as expected.
Also, here's an article that describes somewhat a similar problem but the suggested workaround doesn't seem to be applicable for engine downloaded via Epic Games launcher.
TurboLink plugin version: 1.3
Unreal Engine version: UE 5.3 (binary distribution)
macOS: 14.2.1
iOS: 17.2.1, 16.5
Xcode: 15.2
If there is no support for oneof
then any services using transcoding won't be supported. I believe this may be an issue for many developers. What's the main issue with supporting this field?
When a service is only a stream, the generated blueprint node files contains only #include statements and are otherwise empty.
This is expected due to the notice file stating that nodes for stream services are unsupported.
But the generated code causes problems because the files exist, and one of the includes is the Node.generated.h which obviously don't exist as no code has been spawned in the files that could cause the generated header to be created.
The project requires sending audio data from the client to the server, but the code generated by the plugin does not support client streaming. How should I complete this part?
Hi, Thank you for your great work.
I am blocked at the step 2
I didn't see any config contents on "project settings" window.
Did I missed anything at step 1?
1 . Installing the plugin
Download a release version from here.
You can also clone this repo locally through git, but you also need to download pre-built third party binaries libraries from here, and extract it to Source/ThirdParty.
Create a Plugins/TurboLink folder under your project folder, then copy this repo into it.
- Config service endpoint
created a plugins/TurboLink folder and pull all data from https://github.com/thejinchao/turbolink/releases
I trieed :
Appliciate that if somebody can help me fix this or help me to compile Turbolink for UE5.3.
Environment : UE 5.3
OS: Windows 10 Pro, 64bit
我看到你的project中把不被使用的 abseil libraries 过滤掉了,请问这是如何确定的呢?
我现在在做 grpc 1.50.0 的适配。 之后可以把我的分支提交到你的 repo。
https://github.com/ZezhongWang/turbolink-libraries/tree/grpc_v1.50.0
Hi, I have run into an issue multiple times now, but have a hard time tracking it down since it seems to come from the grpc library and not from your code.
I see the message in the log "New connected subchannel at for ". Normally when this comes, I get a callback through the registered callbacks and create a client and start communicating. But sometimes I get no notification at all. The connection remains open (netstat reveals it to be established), but since I don't get the callback, nothing is done with the connection.
If I then restart the whole connection setup, the channel is kept alive and is established immediately (i.e. the underlying allocations remains) - and I get the notification that I may proceed and everything works again. I have no way of mitigating this as it's only visible in the log that the service has connected...
Do you have any idea what might be going on here, or if there are conditions where the callbacks won't fire when the service has connected?
on the build stage LinuxEditor tries to link into .so library Turbolink module when cooking stage is processing. but with Errors - that third party libraries haven't Position Independent Code.
I have tried to recompile relevant gRPC, abseil and protobuf versions as shared libraries, but without luck - multiple errors with undefined symbols.
Did you try to make project builds on Linux OS?
Since I can't see another way of asking this more in private, I'm posting this question here.
I have an issue with the single TCP connection established not having enough bandwidth due to the re-sending of TCP frames etc, and would like to experiment with setting up several service connections and see if I can force TurboLink and the underlying library to open more than one TCP connection to the server.
The reason is that we're moving from a request/response over http/1 to a gRPC stream. With the http/1 solution a new TCP socket was opened and closed with each request/response (normally a problem with http/1), meaning that we could actually parallelize connections this way by making several concurrent requests.
gRPC is designed to make use of a single http/2 connection and multiplexing all kinds of communication over that, which means that the limitations of a single TCP connection comes into play: network issues and many hops means that the TCP socket will spend significant time re-sending lost frames and what not.
Experimenting with your library, it's clear that only a single service should exist for an endpoint according to your design.
But the question is, if I change your code to actually allow more than one service object to be created to an endpoint/service, will that mean that multiple http/2 connections will be set up in the underlying layer? I'm asking since I'm having a hard time following the code to see what's going on in this case...
So sorry for not being able to trace down the answer myself in your code, and hope you have an answer for me :)
The endpoint is empty when running a game build. It seems a bit too easy to do the wrong thing. If there is something else that should be done to build a game client rather than the editor that also has the correct endpoint settings, it is not in README.md, nor particularly clear that something is misconfigured.
Is this a bug, or a user error? How should the endpoint configuration be set in a game build?
For example, ConfigInstance appears to be empty in TurboLinkGrpcModule.cpp when WITH_EDITOR is not defined:
UTurboLinkGrpcConfig* FTurboLinkGrpcModule::GetTurboLinkGrpcConfig()
{
#if WITH_EDITOR
return ConfigInstance->GetConfig();
#else
return ConfigInstance;
#endif
}
It seems the changes made in the editor are not saved to DefaultGame.ini, as expected. They are captured elsewhere, so it looks like things work when in PIE. Cooking and running the game, however, does not seem to collect those changes.
Could be operator error on my part, but when I add config sections using UDeveloperSettings
, they work as advertised.
Hi,
First of all, thank you for bringing such a plugin to Unreal's weak ecosystem :) Am I missing something or are gRPC deadline and metadata not supported yet? If they aren't supported, can you give me a hint on how to add them?
在生成写proto时GreeterService根据自己调整应该就可以了
Hi,
I'm using your code in a program where the server address and port may be provided externally, and with 1.0 I could change the UTurboLinkGrpcConfig structure easily and it would connect to the server and port provided by other means than through the settings.
In 1.1 you declared the functions retrieving this structure as const, which now means that I have to const_cast<UTurboLinkGrpcConfig*> to remove the constness and change the value.
This is not really a problem for me, but I thought you might want to know that not all usages of your code relies on the specific project settings/ default INI for server and port as your code assumes, and you maybe want to introduce a controlled means of changing it through code if you have plans relying on the constness of the config :)
Hi,
Thanks again for a great plugin!
I'm struggling to find a proper way to close the connection in the APIs though after a stream is finished.
I've tried doing pClient->Shutdown() and assigning a nullptr to the pClient (pClient of course being the client received through the MakeClient call on the service). But I still get GOAWAY messages in the log after the stream is finished.
Here's an excerpt from the log showing the messages I get.
LogMYAPP: UgRPCDownloader::OnLiveStreamServiceContextChanged: State changed to Done. Closing connection. LogTurboLink: Destruct GrpcClient LogTurboLink: grpc:(E:\TurboLink\turbolink-libraries\Source\grpc\grpc-1.41.0\src\core\ext\transport\chttp2\transport\chttp2_transport.cc:1100)@xW�:�: Got goaway [11] err={"created":"@1685449280.543000000","description":"GOAWAY received","file":"E:\TurboLink\turbolink-libraries\Source\grpc\grpc-1.41.0\src\core\ext\transport\chttp2\transport\chttp2_transport.c c","file_line":1089,"grpc_status":14,"http2_error":11,"raw_bytes":"too_many_pings"} LogTurboLink: Error: grpc:(E:\TurboLink\turbolink-libraries\Source\grpc\grpc-1.41.0\src\core\ext\transport\chttp2\transport\chttp2_transport.cc:1111)Received a GOAWAY with error code ENHANCE_YOUR_CALM and debug data equal to "too_many_pings" LogMYAPP: UgRPCDownloader::OnLiveStreamServiceStateChanged: State changed to Idle.
Is the closing down of connections a missing feature, or have I missed something?
please update gRPC library in the Turbolink up to 1.57.0 . it has optimized tls connection . I've used this solution to work around the issue.
also, after this, you could support API token verification:
auto channel_creds = grpc::SslCredentials(getSslOptions());
auto call_creds = grpc::MetadataCredentialsFromPlugin(
std::unique_ptr<grpc::MetadataCredentialsPlugin>(new MyCustomAuthenticator("GetSecretValueFromConfig")));
channel->RpcChannel = grpc::CreateCustomChannel(EndPoint,grpc::CompositeChannelCredentials(channel_creds, call_creds), args);
where is:
class MyCustomAuthenticator : public grpc::MetadataCredentialsPlugin {
public:
MyCustomAuthenticator(const grpc::string& ticket) : ticket_(ticket) {}
grpc::Status GetMetadata(
grpc::string_ref service_url, grpc::string_ref method_name,
const grpc::AuthContext& channel_auth_context,
std::multimap<grpc::string, grpc::string>* metadata) override {
metadata->insert(std::make_pair("GetKeyFromConfig", ticket_));
return grpc::Status::OK;
}
private:
grpc::string ticket_;
};
and just in case:
grpc::SslCredentialsOptions getSslOptions()
{
// Fetch root certificate as required on Windows (s. issue 25533).
grpc::SslCredentialsOptions result;
// Open root certificate store.
HANDLE hRootCertStore = CertOpenSystemStoreW(NULL, L"ROOT");
if (!hRootCertStore)
return result;
// Get all root certificates.
PCCERT_CONTEXT pCert = NULL;
while ((pCert = CertEnumCertificatesInStore(hRootCertStore, pCert)) != NULL)
{
// Append this certificate in PEM formatted data.
DWORD size = 0;
CryptBinaryToStringW(pCert->pbCertEncoded, pCert->cbCertEncoded, CRYPT_STRING_BASE64HEADER, NULL, &size);
std::vector<WCHAR> pem(size);
CryptBinaryToStringW(pCert->pbCertEncoded, pCert->cbCertEncoded, CRYPT_STRING_BASE64HEADER, pem.data(), &size);
result.pem_root_certs += utf8Encode(pem.data());
}
CertCloseStore(hRootCertStore, 0);
return result;
}
Build fails when choosing DebugGame|Win64. Errors as follows:
[1/2] Link GrpcTest-Win64-DebugGame.exe grpc++.lib(completion_queue_cc.obj) : error LNK2038: mismatch detected for '_ITERATOR_DEBUG_LEVEL': value '2' doesn't match value '0' in SharedPCH.Engine.ShadowErrors.h.obj [W:\github\GrpcTest\Intermediate\ProjectFiles\GrpcTest.vcxproj] grpc++.lib(completion_queue_cc.obj) : error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MDd_DynamicDebug' doesn't match value 'MD_DynamicRelease' in SharedPCH.Engine.ShadowErrors.h.obj [W:\github\GrpcTest\Intermediate\ProjectFiles\GrpcTest.vcxproj] grpc++.lib(channel_cc.obj) : error LNK2038: mismatch detected for '_ITERATOR_DEBUG_LEVEL': value '2' doesn't match value '0' in SharedPCH.Engine.ShadowErrors.h.obj [W:\github\GrpcTest\Intermediate\ProjectFiles\GrpcTest.vcxproj] grpc++.lib(channel_cc.obj) : error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MDd_DynamicDebug' doesn't match value 'MD_DynamicRelease' in SharedPCH.Engine.ShadowErrors.h.obj [W:\github\GrpcTest\Intermediate\ProjectFiles\GrpcTest.vcxproj] grpc++.lib(client_context.obj) : error LNK2038: mismatch detected for '_ITERATOR_DEBUG_LEVEL': value '2' doesn't match value '0' in SharedPCH.Engine.ShadowErrors.h.obj [W:\github\GrpcTest\Intermediate\ProjectFiles\GrpcTest.vcxproj] grpc++.lib(client_context.obj) : error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MDd_DynamicDebug' doesn't match value 'MD_DynamicRelease' in SharedPCH.Engine.ShadowErrors.h.obj [W:\github\GrpcTest\Intermediate\ProjectFiles\GrpcTest.vcxproj] grpc++.lib(channel_arguments.obj) : error LNK2038: mismatch detected for '_ITERATOR_DEBUG_LEVEL': value '2' doesn't match value '0' in SharedPCH.Engine.ShadowErrors.h.obj [W:\github\GrpcTest\Intermediate\ProjectFiles\GrpcTest.vcxproj] grpc++.lib(channel_arguments.obj) : error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MDd_DynamicDebug' doesn't match value 'MD_DynamicRelease' in SharedPCH.Engine.ShadowErrors.h.obj [W:\github\GrpcTest\Intermediate\ProjectFiles\GrpcTest.vcxproj] grpc++.lib(create_channel.obj) : error LNK2038: mismatch detected for '_ITERATOR_DEBUG_LEVEL': value '2' doesn't match value '0' in SharedPCH.Engine.ShadowErrors.h.obj [W:\github\GrpcTest\Intermediate\ProjectFiles\GrpcTest.vcxproj] grpc++.lib(create_channel.obj) : error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MDd_DynamicDebug' doesn't match value 'MD_DynamicRelease' in SharedPCH.Engine.ShadowErrors.h.obj [W:\github\GrpcTest\Intermediate\ProjectFiles\GrpcTest.vcxproj] grpc++.lib(secure_credentials.obj) : error LNK2038: mismatch detected for '_ITERATOR_DEBUG_LEVEL': value '2' doesn't match value '0' in SharedPCH.Engine.ShadowErrors.h.obj [W:\github\GrpcTest\Intermediate\ProjectFiles\GrpcTest.vcxproj] grpc++.lib(secure_credentials.obj) : error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MDd_DynamicDebug' doesn't match value 'MD_DynamicRelease' in SharedPCH.Engine.ShadowErrors.h.obj [W:\github\GrpcTest\Intermediate\ProjectFiles\GrpcTest.vcxproj] grpc++.lib(insecure_credentials.obj) : error LNK2038: mismatch detected for '_ITERATOR_DEBUG_LEVEL': value '2' doesn't match value '0' in SharedPCH.Engine.ShadowErrors.h.obj [W:\github\GrpcTest\Intermediate\ProjectFiles\GrpcTest.vcxproj] grpc++.lib(insecure_credentials.obj) : error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MDd_DynamicDebug' doesn't match value 'MD_DynamicRelease' in SharedPCH.Engine.ShadowErrors.h.obj [W:\github\GrpcTest\Intermediate\ProjectFiles\GrpcTest.vcxproj] grpc++.lib(codegen_init.obj) : error LNK2038: mismatch detected for '_ITERATOR_DEBUG_LEVEL': value '2' doesn't match value '0' in SharedPCH.Engine.ShadowErrors.h.obj [W:\github\GrpcTest\Intermediate\ProjectFiles\GrpcTest.vcxproj] grpc++.lib(codegen_init.obj) : error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MDd_DynamicDebug' doesn't match value 'MD_DynamicRelease' in SharedPCH.Engine.ShadowErrors.h.obj [W:\github\GrpcTest\Intermediate\ProjectFiles\GrpcTest.vcxproj] grpc++.lib(core_codegen.obj) : error LNK2038: mismatch detected for '_ITERATOR_DEBUG_LEVEL': value '2' doesn't match value '0' in SharedPCH.Engine.ShadowErrors.h.obj [W:\github\GrpcTest\Intermediate\ProjectFiles\GrpcTest.vcxproj] grpc++.lib(core_codegen.obj) : error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MDd_DynamicDebug' doesn't match value 'MD_DynamicRelease' in SharedPCH.Engine.ShadowErrors.h.obj [W:\github\GrpcTest\Intermediate\ProjectFiles\GrpcTest.vcxproj] grpc++.lib(client_interceptor.obj) : error LNK2038: mismatch detected for '_ITERATOR_DEBUG_LEVEL': value '2' doesn't match value '0' in SharedPCH.Engine.ShadowErrors.h.obj [W:\github\GrpcTest\Intermediate\ProjectFiles\GrpcTest.vcxproj] grpc++.lib(client_interceptor.obj) : error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MDd_DynamicDebug' doesn't match value 'MD_DynamicRelease' in SharedPCH.Engine.ShadowErrors.h.obj [W:\github\GrpcTest\Intermediate\ProjectFiles\GrpcTest.vcxproj] grpc++.lib(version_cc.obj) : error LNK2038: mismatch detected for '_ITERATOR_DEBUG_LEVEL': value '2' doesn't match value '0' in SharedPCH.Engine.ShadowErrors.h.obj [W:\github\GrpcTest\Intermediate\ProjectFiles\GrpcTest.vcxproj]
It seems that it is because all the libraries are built with the "release" flag then can't be linked in Debug mode.
If an error happens the plugin doesn't provide any event
When I added the protoc-gen-validate, re2 started being included, but was unable to be found in generated code.
My file structure is:
\tools\protos\
common.proto
validate\
validate.proto
I've added these args to the protoc command in generate_code.cmd
. Also have protoc-gen-validate-cpp
on the Path:
--plugin=protoc-gen-validate-cpp ^
--validate_out="lang=cc:%CPP_OUTPUT_PATH%" ^
I created another script very similar to generate_code.cmd
, but it only touches validate/validate.proto
. It doesn't do the file renaming or logging and doesn't use the --validate_out arg.
common.proto
--plugin=protoc-gen-validate-cpp ^
--validate_out="lang=cc:%CPP_OUTPUT_PATH%" ^
After generating the files, re2 is unable to be included.
common.pb.validate.cc(9): Error C1083 : Cannot open include file: 're2/re2.h': No such file or directory
turbolink/Source/TurboLinkGrpc/TurboLinkGrpc.Build.cs
Lines 42 to 47 in 8e744e3
Adding re2 fixed compilation issues.
Path.Combine(ThirdPartyRoot(), "re2/include")
It's unclear to me if this is expected behavior or not.
UATHelper: Packaging (Linux): E:\UE_Projects\gRPC\TestGeneration\Client\Plugins\TurboLink\Source\TurboLinkGrpc\Private\TurboLinkGrpcManager_Private.cpp(7,51): error: non-friend class member 'GrpcStateToServiceState' cannot have a qualified name
UATHelper: Packaging (Linux): EGrpcServiceState UTurboLinkGrpcManager::Private::GrpcStateToServiceState(grpc_connectivity_state State)
UATHelper: Packaging (Linux): ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
PackagingResults: Error: non-friend class member 'GrpcStateToServiceState' cannot have a qualified name
UATHelper: Packaging (Linux): E:\UE_Projects\gRPC\TestGeneration\Client\Plugins\TurboLink\Source\TurboLinkGrpc\Private\TurboLinkGrpcManager_Private.cpp(30,97): error: non-friend class member 'CreateServiceChannel' cannot have a qualified name
UATHelper: Packaging (Linux): std::shared_ptrUTurboLinkGrpcManager::Private::ServiceChannel UTurboLinkGrpcManager::Private::CreateServiceChannel(const char* EndPoint, UGrpcService* AttachedService)
UATHelper: Packaging (Linux): ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
PackagingResults: Error: non-friend class member 'CreateServiceChannel' cannot have a qualified name
UATHelper: Packaging (Linux): E:\UE_Projects\gRPC\TestGeneration\Client\Plugins\TurboLink\Source\TurboLinkGrpc\Private\TurboLinkGrpcManager_Private.cpp(76,38): error: non-friend class member 'RemoveServiceChannel' cannot have a qualified name
UATHelper: Packaging (Linux): void UTurboLinkGrpcManager::Private::RemoveServiceChannel(std::shared_ptr Channel, UGrpcService* AttachedService)
UATHelper: Packaging (Linux): ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
PackagingResults: Error: non-friend class member 'RemoveServiceChannel' cannot have a qualified name
UATHelper: Packaging (Linux): E:\UE_Projects\gRPC\TestGeneration\Client\Plugins\TurboLink\Source\TurboLinkGrpc\Private\TurboLinkGrpcManager_Private.cpp(94,70): error: non-friend class member 'CreateRpcClientContext' cannot have a qualified name
UATHelper: Packaging (Linux): std::unique_ptrgrpc::ClientContext UTurboLinkGrpcManager::Private::CreateRpcClientContext(void)
UATHelper: Packaging (Linux): ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
PackagingResults: Error: non-friend class member 'CreateRpcClientContext' cannot have a qualified name
UATHelper: Packaging (Linux): E:\UE_Projects\gRPC\TestGeneration\Client\Plugins\TurboLink\Source\TurboLinkGrpc\Private\TurboLinkGrpcManager_Private.cpp(100,38): error: non-friend class member 'ShutdownCompletionQueue' cannot have a qualified name
UATHelper: Packaging (Linux): void UTurboLinkGrpcManager::Private::ShutdownCompletionQueue()
UATHelper: Packaging (Linux): ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
PackagingResults: Error: non-friend class member 'ShutdownCompletionQueue' cannot have a qualified name
UATHelper: Packaging (Linux): In file included from E:/UE_Projects/gRPC/TestGeneration/Client/Plugins/TurboLink/Intermediate/Build/Linux/x64/UnrealGame/Development/TurboLinkGrpc/Module.TurboLinkGrpc.3_of_3.cpp:31:
UATHelper: Packaging (Linux): In file included from E:/UE_Projects/gRPC/TestGeneration/Client/Plugins/TurboLink/Source/TurboLinkGrpc/Private/TurboLinkGrpcModule.cpp:8:
UATHelper: Packaging (Linux): C:\UnrealEngine\UE_5.2\Engine\Source\Runtime\Core\Public\HAL\ExceptionHandling.h(11,1): error: storage class specified for a member declaration
UATHelper: Packaging (Linux): extern CORE_API bool GAlwaysReportCrash;
UATHelper: Packaging (Linux): ^
PackagingResults: Error: storage class specified for a member declaration
UATHelper: Packaging (Linux): C:\UnrealEngine\UE_5.2\Engine\Source\Runtime\Core\Public\HAL\ExceptionHandling.h(14,1): error: storage class specified for a member declaration
UATHelper: Packaging (Linux): extern CORE_API bool GUseCrashReportClient;
UATHelper: Packaging (Linux): ^
PackagingResults: Error: storage class specified for a member declaration
UATHelper: Packaging (Linux): C:\UnrealEngine\UE_5.2\Engine\Source\Runtime\Core\Public\HAL\ExceptionHandling.h(16,1): error: storage class specified for a member declaration
UATHelper: Packaging (Linux): extern CORE_API TCHAR MiniDumpFilenameW[1024];
UATHelper: Packaging (Linux): ^
PackagingResults: Error: storage class specified for a member declaration
UATHelper: Packaging (Linux): C:\UnrealEngine\UE_5.2\Engine\Source\Runtime\Core\Public\HAL\ExceptionHandling.h(41,1): error: storage class specified for a member declaration
UATHelper: Packaging (Linux): extern CORE_API void ReportAssert(const TCHAR* ErrorMessage, void* ProgramCounter);
UATHelper: Packaging (Linux): ^
UATHelper: Packaging (Linux): C:\UnrealEngine\UE_5.2\Engine\Source\Runtime\Core\Public\HAL\ExceptionHandling.h(42,1): error: storage class specified for a member declaration
UATHelper: Packaging (Linux): extern CORE_API void ReportGPUCrash(const TCHAR* ErrorMessage, void* ProgramCounter);
UATHelper: Packaging (Linux): ^
PackagingResults: Error: storage class specified for a member declaration
PackagingResults: Error: storage class specified for a member declaration
UATHelper: Packaging (Linux): C:\UnrealEngine\UE_5.2\Engine\Source\Runtime\Core\Public\HAL\ExceptionHandling.h(43,1): error: storage class specified for a member declaration
UATHelper: Packaging (Linux): extern CORE_API void ReportEnsure(const TCHAR* ErrorMessage, void* ProgramCounter);
UATHelper: Packaging (Linux): ^
PackagingResults: Error: storage class specified for a member declaration
UATHelper: Packaging (Linux): C:\UnrealEngine\UE_5.2\Engine\Source\Runtime\Core\Public\HAL\ExceptionHandling.h(44,1): error: storage class specified for a member declaration
UATHelper: Packaging (Linux): extern CORE_API void ReportStall(const TCHAR* ErrorMessage, uint32 ThreadId);
UATHelper: Packaging (Linux): ^
PackagingResults: Error: storage class specified for a member declaration
UATHelper: Packaging (Linux): C:\UnrealEngine\UE_5.2\Engine\Source\Runtime\Core\Public\HAL\ExceptionHandling.h(45,1): error: storage class specified for a member declaration
UATHelper: Packaging (Linux): extern CORE_API void ReportHang(const TCHAR*, const uint64* StackFrames, int32 NumStackFrames, uint32 HungThreadId);
UATHelper: Packaging (Linux): ^
UATHelper: Packaging (Linux): C:\UnrealEngine\UE_5.2\Engine\Source\Runtime\Core\Public\HAL\ExceptionHandling.h(49,1): error: storage class specified for a member declaration
UATHelper: Packaging (Linux): extern CORE_API void ReportInteractiveEnsure(const TCHAR* InMessage);
UATHelper: Packaging (Linux): ^
PackagingResults: Error: storage class specified for a member declaration
PackagingResults: Error: storage class specified for a member declaration
UATHelper: Packaging (Linux): C:\UnrealEngine\UE_5.2\Engine\Source\Runtime\Core\Public\HAL\ExceptionHandling.h(50,1): error: storage class specified for a member declaration
UATHelper: Packaging (Linux): extern CORE_API bool IsInteractiveEnsureMode();
UATHelper: Packaging (Linux): ^
PackagingResults: Error: storage class specified for a member declaration
UATHelper: Packaging (Linux): In file included from E:/UE_Projects/gRPC/TestGeneration/Client/Plugins/TurboLink/Intermediate/Build/Linux/x64/UnrealGame/Development/TurboLinkGrpc/Module.TurboLinkGrpc.3_of_3.cpp:31:
UATHelper: Packaging (Linux): E:\UE_Projects\gRPC\TestGeneration\Client\Plugins\TurboLink\Source\TurboLinkGrpc\Private\TurboLinkGrpcModule.cpp(48,23): error: non-friend class member 'FTurboLinkGrpcModule' cannot have a qualified name
UATHelper: Packaging (Linux): FTurboLinkGrpcModule::FTurboLinkGrpcModule()
UATHelper: Packaging (Linux): ~~~~~~~~~~~~~~~~~~~~~~^
PackagingResults: Error: non-friend class member 'FTurboLinkGrpcModule' cannot have a qualified name
UATHelper: Packaging (Linux): E:\UE_Projects\gRPC\TestGeneration\Client\Plugins\TurboLink\Source\TurboLinkGrpc\Private\TurboLinkGrpcModule.cpp(53,23): error: non-friend class member '~FTurboLinkGrpcModule' cannot have a qualified name
UATHelper: Packaging (Linux): FTurboLinkGrpcModule::~FTurboLinkGrpcModule()
UATHelper: Packaging (Linux): ~~~~~~~~~~~~~~~~~~~~~~^
PackagingResults: Error: non-friend class member '~FTurboLinkGrpcModule' cannot have a qualified name
UATHelper: Packaging (Linux): E:\UE_Projects\gRPC\TestGeneration\Client\Plugins\TurboLink\Source\TurboLinkGrpc\Private\TurboLinkGrpcModule.cpp(57,28): error: non-friend class member 'StartupModule' cannot have a qualified name
UATHelper: Packaging (Linux): void FTurboLinkGrpcModule::StartupModule()
UATHelper: Packaging (Linux): ~~~~~~~~~~~~~~~~~~~~~~^
PackagingResults: Error: non-friend class member 'StartupModule' cannot have a qualified name
UATHelper: Packaging (Linux): E:\UE_Projects\gRPC\TestGeneration\Client\Plugins\TurboLink\Source\TurboLinkGrpc\Private\TurboLinkGrpcModule.cpp(116,28): error: non-friend class member 'ShutdownModule' cannot have a qualified name
UATHelper: Packaging (Linux): void FTurboLinkGrpcModule::ShutdownModule()
UATHelper: Packaging (Linux): ~~~~~~~~~~~~~~~~~~~~~~^
UATHelper: Packaging (Linux): fatal error: too many errors emitted, stopping now [-ferror-limit=]
UATHelper: Packaging (Linux): 1 warning and 20 errors generated.
PackagingResults: Error: non-friend class member 'ShutdownModule' cannot have a qualified name
PackagingResults: Error: too many errors emitted, stopping now [-ferror-limit=]
It seems that the turbolink has issue with deleting resource. It can easily crash when stop the game.
Reproduce crash:
Environment: Win 11, Unreal 5.1
local client: example client
remote Server: grpc.thecodeway.com:5050
LoginId:0efd37ca4c6c7474efb2c99e5bb384e9
EpicAccountId:11a9f14e5c654a5989f30cc488bee675
Unhandled Exception: EXCEPTION_ACCESS_VIOLATION 0x000007778a89b640
UnrealEditor_Engine
UnrealEditor_Engine
UnrealEditor_Engine
UnrealEditor_TurboLinkDemo!UTurboLinkDemoInstance::`vector deleting destructor'()
UnrealEditor_CoreUObject
UnrealEditor_CoreUObject
UnrealEditor_CoreUObject
UnrealEditor_CoreUObject
UnrealEditor_UnrealEd
UnrealEditor_UnrealEd
UnrealEditor_UnrealEd
UnrealEditor
UnrealEditor
UnrealEditor
UnrealEditor
UnrealEditor
UnrealEditor
kernel32
ntdll
Hi! Amazing job with this plugin!
We were using the library my making simple RPC calls and with server streaming without a problem, but the gRPC service we are using has moved to a bidirectional streaming RPC.
It sounds like TurboLink supports both client and server streaming, so we should be okay, but we're having trouble figuring out how to get the client streaming working. After we initialize the function and send a request, sending a second request to the same function doesn't seem to work.
Can you describe the general flow of how client streaming works with Blueprints?
Thanks in advance!
If the imported proto file has a function called GetMessage, TurboLink will generate a corresponding .h/cpp matching that interface, and including all of its standard includes.
Unfortunately, the include chain also pulls in WinUser.h, included through an upstream Windows.h include, which defines a macro:
#ifdef UNICODE
#define GetMessage GetMessageW
#else
#define GetMessage GetMessageA
#endif // !UNICODE
This ultimately causes the generated file to not compile because the macro has renamed the function.
This is a known problem within the Windows API, where many function names are redefined via macro to FunctionNameW or FunctionNameA, but still something that can cause problems with TurboLink. For now, I'm using #undef GetMessage
after the include in the generated file, but others might find better workarounds or a proper solution that avoids the accidental upstream inclusion of windows.h
.
现在 UGrpcService/UGrpcClient 在每次调用蓝图的节点时都会被新创建销毁,为什么不把 UGrpcService 做成和 ServiceChannel 一样全局唯一的呢?这样可以减少很多不必要的反复创建销毁。
个人认为只有 Context 是需要临时创建的。 GrpcService 不应该临时创建才对。
还有对 GrpcClient 这个类存在的目的不是很明白。 感觉 Manager -> Service -> Context 的抽象已经可以满足需求。
As far as I know, some functions in abseil will be redefined in webrtc.lib in PixelStreaming resulting in link errors. (This error can be replicated by adding the WebRTC module to UE)Does your plugin have this problem?
Trying to open full demo or demo we get a google - can't download this file due to it's violation of our terms and condition
https://drive.google.com/file/d/10qtKq2E2I7mS8M0fiFxAtuaO2Zb60-zB/view?usp=sharing
🙏🏼
Perhaps you can upload it to another repository?
I'm working with the branch v1.2.1, to rebuild plugin with UE_5.1.
The version of protoc is 3.19.0. I run the script in the Plugins/TutboLink/Tools
named generate-code.cmd
but it seems not work.
What I Do:
In the proto
folder, run the command as follow
..\generate_code.cmd .\hello.proto D:\Unreal_Projects\TurboLinkUE\Plugins\TurboLink\Source\TurboLinkGrpc
操作步骤:
1。 创建了一个新的c++项目
2。 按照教程创建了Plugins/TurboLink 并把仓库文件复制进去
3。 通过下载的full.demo.zip中的生成pb的工具,生成了相关文件
4。 把上述生成的文件,按照Public、Private复制到项目的Plugins/TurboLink/Source/TurboLinkGrpc对应的文件夹内
5。 通过Rider编译编辑器,并打开
6。 在蓝图中参考full.demo编写蓝图节点,访问本地的服务
7。 功能一切正常
8。 关闭编辑器
9。 再次通过Rider编译编辑器,并打开
10。 出问题了,如下图
基于第三人称模板,创建的项目中 有改动的部分如下:
1。 角色蓝图(包含相关蓝图节点)
2。 通过pb生成工具生成的相关文件
Hello to everyone,
I know that official gRPC c++ does not support custom name resolvers yet. Do you know a way to provide multiple server addresses/ips without using DNS A/SRV records? I only want to provide multiple server addresses to a channel for failover/retry mechanizm. I've tried ChannelArguments::SetServiceConfigJSON
, but it has not capabile of specify server address.
Thank you
Hi,
You're plugin looks very nice. However, I need a gRPC server in Unreal Engine. From the description it looks like this plugin only supports client side in UE. Is that correct?
On Fail pin won't be executed in the blueprint if the connection is not established correctly.
This is because when the node tries to connect and fails. It will call the OnFall delegate immediately. But his time the function still doesn't return the node. And its delegate is not correctly bound with the following nodes.
I have error:
Undefined symbols for architecture arm64
TurboLinkGrpcConfig.h(9): error C2504: 'UDeveloperSettings': base class undefined. need to #include "Engine/DeveloperSettings.h"
also TurboLinkGrpcUtilities.cpp - #include "Engine/GameInstance.h"
Hello,
As of 5.4, there is the following compile warning:
11>EXEC: Warning : do not include Windows/PreWindowsApi.h directly. Use Windows/WindowsHWrapper.h or Windows/AllowWindowsPlatformTypes.h instead
I believe this stems from TurboLinkGrpcModule.cpp line 14
Unsure which is the correct include to use for Turbolink
When generating the below common.proto & game-broken.proto, Private/SGame/GameContext.cpp has compilation issues.
GameContext.cpp(19): Error C2665 : 'TURBOLINK_TO_GRPC': no overloaded function could convert all the argument types
I found 2 ways to work around this:
common.proto
package common;
message Player {
uint64 id = 1;
string username = 2;
string auth_key = 3;
}
game-broken.proto
package game;
import "common.proto";
service TestTurbo {
rpc TestTurboFunc(common.Player) returns (common.Player);
}
game-workaround.proto
package game;
import "common.proto";
message TestTurboFuncMessage {
common.Player player = 1;
}
service TestTurbo {
rpc TestTurboFunc(TestTurboFuncMessage) returns (TestTurboFuncMessage);
}
Thank you for all your time and focus on turbolink. 👍
for example, AsyncNodes for Ticktok and Watch in the greeter.proto:
service TimeService {
rpc Now(Nothing) returns (NowResponse);
rpc Ticktok (TicktokRequest) returns (stream NowResponse);
rpc Watch (stream WatchRequest) returns (stream NowResponse);
}
Also, I'm very grateful for your work, guys. It's amazing, especially how to easily integrate custom gRPC services in the Unreal Engine with Turbolink.
Thank you!!!
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.