GithubHelp home page GithubHelp logo

thejinchao / turbolink Goto Github PK

View Code? Open in Web Editor NEW
145.0 145.0 41.0 6.16 MB

TurboLink is an unreal engine plugin enables Google gRPC work with Unreal Engine using C++ and Blueprint

License: MIT License

C++ 88.77% C# 8.77% Batchfile 2.46%
blueprint grpc protobuf protoc unrealengine

turbolink's People

Contributors

gfrontera avatar justin-randall avatar rootux avatar thejinchao avatar zezhongwang avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

turbolink's Issues

Problems that occur when generating proto files in a batch file

image

After put the release version in the project path and completing compilation of the solution file, I checked that Turbo Link was installed in the editor plugin and ran the batch file, but the log above appeared. It doesn't solve what the problem is.

Compile fails when disable Unity build

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

Crashes in iOS Shipping build

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.

Additional info:

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

No Support For Transcoding

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?

Generated *Node.h and *Node.cpp files cause problems when service is a stream only

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.

Blocked at install step2

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.

  1. Config service endpoint

created a plugins/TurboLink folder and pull all data from https://github.com/thejinchao/turbolink/releases
I trieed :

  • restart ue5
  • put turbolink in to ue/engine/plugins/turbolink
    • ue5 says doesn't support turbolink 4.27

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

Connected subchannel without notification

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?

can't achieve to built Project on Linux for Linux

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?

Question on possibility of multiple http/2 connections

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 :)

Game builds do not use settings for default or specific endpoints set in the editor under Project Settings -> Game

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.

[Question] Deadline and metadata support

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?

reducing libraries size

  1. there are some libraries that are not using in the build.cs (grpc++_alts, grpc++_reflection etc.)
  2. also some linked by the build.cs could be deleted (from abseil group) without further build problems
  3. re2 library could be pickup from EngineThirdParty
  4. if make build from Linux, sizes of libraries significantly reduces:
    grpc - 150 -> 64
    protobuf - 70 -> 24
    abseil - 14 -> 5

Write access to server settings prohibited by const in version 1.1

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 :)

API Question/issue: How to close connection?

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?

embedded 1.41.0 gRPC library doesn't support empty certificates at Windows for API token verification

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;
}

The libraries linked failed when compiling debug version.

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.

Error handling

If an error happens the plugin doesn't provide any event

re2 path missing from PrivateIncludePaths in TurboLinkGrpc.Build.cs

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

PrivateIncludePaths.AddRange(
new string[] {
Path.Combine(ThirdPartyRoot(), "protobuf/include"),
Path.Combine(ThirdPartyRoot(), "grpc/include"),
Path.Combine(ThirdPartyRoot(), "abseil/include")
}

Adding re2 fixed compilation issues.

Path.Combine(ThirdPartyRoot(), "re2/include")

It's unclear to me if this is expected behavior or not.

can't build for Linux, Unreal Engine 5.2

Multiple errors

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=]

Example client crashes when stop the game client.

It seems that the turbolink has issue with deleting resource. It can easily crash when stop the game.

Reproduce crash:

  • Open the client in editor
  • Start the game, using blueprint widget
  • click connect, create client, tiktok, watch randomly
  • Stop the game. crash sometimes happen.

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

Client side streaming

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!

Windows conflict with GetMessage

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.

Reuse UGrpcService object

现在 UGrpcService/UGrpcClient 在每次调用蓝图的节点时都会被新创建销毁,为什么不把 UGrpcService 做成和 ServiceChannel 一样全局唯一的呢?这样可以减少很多不必要的反复创建销毁。

个人认为只有 Context 是需要临时创建的。 GrpcService 不应该临时创建才对。
还有对 GrpcClient 这个类存在的目的不是很明白。 感觉 Manager -> Service -> Context 的抽象已经可以满足需求。

Is it supported for use with PixelStreaming plugin?

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?

hyphen in proto file name isn't supported.

  1. generate-code.cmd
  2. add generated files and rebuild solution
  3. build full demo project, errors:
    test-statusMessage.generated.h(12): [C4067] unexpected tokens following preprocessor directive - expected a newline
    test-statusMessage.generated.h(15): [C2008] '-': unexpected in macro definition
    test-statusMessage.generated.h(12): [C4067] unexpected tokens following preprocessor directive - expected a newline
    test-statusMessage.generated.h(15): [C2008] '-': unexpected in macro definition

Need Help! How to generate ".gprc.pb.h/.c" files?

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

image

UE5.4 编写完蓝图,关闭编辑器前一切正常。关闭后,再次打开编辑器就全是错误了

操作步骤:
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。 出问题了,如下图

image

基于第三人称模板,创建的项目中 有改动的部分如下:
1。 角色蓝图(包含相关蓝图节点)
2。 通过pb生成工具生成的相关文件

code.zip

CLANG BUG FIX: expected a qualified name after 'typename'

While building the plugin in v22_clang-16.0.6-centos it gives the following error

Plugins\Turbolink\Source\TurboLinkGrpc\Private\TurboLinkGrpcContext.h(201,12): error: expected a qualified name after 'typename'
typename FSendCompleteCallbackFunc SendCompleteCallbackFunc)

To fix:
image

[QUESTION] Custom Name Resolver

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

gRPC server support?

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?

  • Is it planned to also support gRPC server in the plugin?
  • Since you've written the plugin yourself, what's your estimate how hard would it be to modify the plugin to also add in a server? I'm considering doing this myself at the moment. Are there any major roadblocks you can think of?

Node function OnFail doesn't work

On Fail pin won't be executed in the blueprint if the connection is not established correctly.

image

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.

image

5.4 Compile Warnings

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

Referencing a message from another proto file in an rpc causes missing imports in generated files

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:

  1. Editing the generated files. Manually add the include for /SCommon/CommonMarshaling.h to /SGame/GameContext.cpp.
  2. Wrapping the Player message from common.proto with a message defined inside game.proto. See game-workaround.proto below.

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. 👍

support AsyncNode for "stream" RPC parameters and HUGE Thank you for brilliant work!

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!!!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.