Initial commit

This commit is contained in:
2023-01-16 14:44:59 +08:00
parent 315bcda15f
commit 620e192d07
53 changed files with 2174 additions and 0 deletions
View File
View File
+35
View File
@@ -0,0 +1,35 @@
[/Script/EngineSettings.GameMapsSettings]
GameDefaultMap=/Game/TurboLinkTest/Maps/TestMap.TestMap
GameInstanceClass=/Game/TurboLinkTest/Blueprint/BP_GameInstance.BP_GameInstance_C
EditorStartupMap=/Game/TurboLinkTest/Maps/TestMap.TestMap
GlobalDefaultGameMode=/Game/TurboLinkTest/Blueprint/BP_GameMode.BP_GameMode_C
ServerDefaultMap=/Game/TurboLinkTest/Maps/TestMap.TestMap
[/Script/HardwareTargeting.HardwareTargetingSettings]
TargetedHardwareClass=Desktop
AppliedTargetedHardwareClass=Desktop
DefaultGraphicsPerformance=Maximum
AppliedDefaultGraphicsPerformance=Maximum
[/Script/Engine.Engine]
+ActiveGameNameRedirects=(OldGameName="TP_Blank",NewGameName="/Script/TurboLinkTest")
+ActiveGameNameRedirects=(OldGameName="/Script/TP_Blank",NewGameName="/Script/TurboLinkTest")
+ActiveClassRedirects=(OldClassName="TP_BlankGameModeBase",NewClassName="TurboLinkTestGameModeBase")
[/Script/AndroidRuntimeSettings.AndroidRuntimeSettings]
PackageName=com.joyworkshop.turbolink
StoreVersionOffsetArm64=1
StoreVersionOffsetX8664=2
ApplicationDisplayName=TurboLink
TargetSDKVersion=31
bPackageDataInsideApk=True
bBuildForArm64=True
bBuildForX8664=True
[/Script/IOSRuntimeSettings.IOSRuntimeSettings]
BundleDisplayName=TurboLink
BundleName=turbolink
BundleIdentifier=com.joyworkshop.turbolink
+8
View File
@@ -0,0 +1,8 @@
[/Script/EngineSettings.GeneralProjectSettings]
ProjectID=D413C97A4B452488FCA7348D322284BA
[/Script/TurboLinkGrpc.TurboLinkGrpcConfig]
DefaultEndPoint=grpc.thecodeway.net:5050
EnableServerSideTLS=True
ServerRootCerts=-----BEGIN CERTIFICATE-----\nMIIDUzCCAjugAwIBAgIJANELcq+JkuytMA0GCSqGSIb3DQEBCwUAMEsxCzAJBgNV\nBAYTAkNOMRAwDgYDVQQHDAdCZWlqaW5nMRIwEAYDVQQKDAlUdXJib0xpbmsxFjAU\nBgNVBAMMDXR1cmJvbGluay5kZXYwHhcNMjIxMTMwMDMwMjA5WhcNMzIxMTI3MDMw\nMjA5WjBLMQswCQYDVQQGEwJDTjEQMA4GA1UEBwwHQmVpamluZzESMBAGA1UECgwJ\ndHVyYm9saW5rMRYwFAYDVQQDDA10dXJib2xpbmsuZGV2MIIBIjANBgkqhkiG9w0B\nAQEFAAOCAQ8AMIIBCgKCAQEAr8vdbsXtLWOEWoygSluR3BtYJcp+1nbDwrytr7WX\nXcnzSB1rQ0lt3yQmQ5BKm6CLbUeKtQd7fIUT1JRn3KJ/dSHXT4qEWWO0XJLJeoAI\nFXprLWolbrBA8QCAs8Hcbm8F/efHphKU4a10HhD6ENa4YqYPnd89vfYgSPGS/UmF\nojWicWjmmT7Np5PBo81mzpbyhGTlOeZj6LLp77w8772MRBDZTn4eDXDuCdfbs2HM\nYFK4OQ2QQjrh2LSCA6VQgi8gGaXtp2k8CwVlXQpOFWmYX0FyXX/4qvkvXl8rG07T\nAvX7iCaG3owAYrDeQUL7NqbTvAMHiqivCwrFzThNq+XSkQIDAQABozowODA2BgNV\nHREELzAtgg8qLnR1cmJvbGluay5kZXaCDyoubGV5b3V0ZWNoLm5ldIIJbG9jYWxo\nb3N0MA0GCSqGSIb3DQEBCwUAA4IBAQB+8r4YO/vozHSa+VFcT8MmgJc8z8MDy6FE\ntD04ImGGWzs0bH+JPRI4gUF6kprHNs06B4UbvXGUO8o8QD7BGN+eSlxQ3GsnOKeu\nfeW5UOD/15q+zIZE6YT8VW3mHpQMJFlP0cVMLj9dUSs43dIwcjj2HhvmY731IZZp\nAXWbD5Vo6qM+8TmGh4ESlRh42yKsbq66Y5vd68oHk1bBcQ1xDPsEZ1GJ3zzj5KxH\nYppLeaZu7T7oSuMjzn8aLFj2Cbclu2nl7GSg1ZLPNBdAxuMC1VKgi5sPIKajWkRR\nlJad7CKjVESSM3ZrVUz/z/+/Yjn8u/jMKEqyMz3uAT0LyUbIu6ua\n-----END CERTIFICATE-----
+87
View File
@@ -0,0 +1,87 @@
[/Script/Engine.InputSettings]
-AxisConfig=(AxisKeyName="Gamepad_LeftX",AxisProperties=(DeadZone=0.25,Exponent=1.f,Sensitivity=1.f))
-AxisConfig=(AxisKeyName="Gamepad_LeftY",AxisProperties=(DeadZone=0.25,Exponent=1.f,Sensitivity=1.f))
-AxisConfig=(AxisKeyName="Gamepad_RightX",AxisProperties=(DeadZone=0.25,Exponent=1.f,Sensitivity=1.f))
-AxisConfig=(AxisKeyName="Gamepad_RightY",AxisProperties=(DeadZone=0.25,Exponent=1.f,Sensitivity=1.f))
-AxisConfig=(AxisKeyName="MouseX",AxisProperties=(DeadZone=0.f,Exponent=1.f,Sensitivity=0.07f))
-AxisConfig=(AxisKeyName="MouseY",AxisProperties=(DeadZone=0.f,Exponent=1.f,Sensitivity=0.07f))
-AxisConfig=(AxisKeyName="Mouse2D",AxisProperties=(DeadZone=0.f,Exponent=1.f,Sensitivity=0.07f))
+AxisConfig=(AxisKeyName="Gamepad_LeftX",AxisProperties=(DeadZone=0.250000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="Gamepad_LeftY",AxisProperties=(DeadZone=0.250000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="Gamepad_RightX",AxisProperties=(DeadZone=0.250000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="Gamepad_RightY",AxisProperties=(DeadZone=0.250000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="MouseX",AxisProperties=(DeadZone=0.000000,Sensitivity=0.070000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="MouseY",AxisProperties=(DeadZone=0.000000,Sensitivity=0.070000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="Mouse2D",AxisProperties=(DeadZone=0.000000,Sensitivity=0.070000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="MouseWheelAxis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="Gamepad_LeftTriggerAxis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="Gamepad_RightTriggerAxis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="Gamepad_Special_Left_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="Gamepad_Special_Left_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="Daydream_Left_Trackpad_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="Daydream_Left_Trackpad_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="Daydream_Right_Trackpad_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="Daydream_Right_Trackpad_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="Vive_Left_Trigger_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="Vive_Left_Trackpad_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="Vive_Left_Trackpad_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="Vive_Right_Trigger_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="Vive_Right_Trackpad_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="Vive_Right_Trackpad_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="MixedReality_Left_Trigger_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="MixedReality_Left_Thumbstick_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="MixedReality_Left_Thumbstick_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="MixedReality_Left_Trackpad_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="MixedReality_Left_Trackpad_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="MixedReality_Right_Trigger_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="MixedReality_Right_Thumbstick_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="MixedReality_Right_Thumbstick_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="MixedReality_Right_Trackpad_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="MixedReality_Right_Trackpad_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="OculusTouch_Left_Grip_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="OculusTouch_Left_Trigger_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="OculusTouch_Left_Thumbstick_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="OculusTouch_Left_Thumbstick_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="OculusTouch_Right_Grip_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="OculusTouch_Right_Trigger_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="OculusTouch_Right_Thumbstick_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="OculusTouch_Right_Thumbstick_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="ValveIndex_Left_Grip_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="ValveIndex_Left_Grip_Force",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="ValveIndex_Left_Trigger_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="ValveIndex_Left_Thumbstick_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="ValveIndex_Left_Thumbstick_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="ValveIndex_Left_Trackpad_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="ValveIndex_Left_Trackpad_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="ValveIndex_Left_Trackpad_Force",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="ValveIndex_Left_Trackpad_Touch",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="ValveIndex_Right_Grip_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="ValveIndex_Right_Grip_Force",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="ValveIndex_Right_Trigger_Axis",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="ValveIndex_Right_Thumbstick_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="ValveIndex_Right_Thumbstick_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="ValveIndex_Right_Trackpad_X",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="ValveIndex_Right_Trackpad_Y",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
+AxisConfig=(AxisKeyName="ValveIndex_Right_Trackpad_Force",AxisProperties=(DeadZone=0.000000,Sensitivity=1.000000,Exponent=1.000000,bInvert=False))
bAltEnterTogglesFullscreen=True
bF11TogglesFullscreen=True
bUseMouseForTouch=False
bEnableMouseSmoothing=True
bEnableFOVScaling=True
bCaptureMouseOnLaunch=True
bAlwaysShowTouchInterface=False
bShowConsoleOnFourFingerTap=True
bEnableGestureRecognizer=False
bUseAutocorrect=False
DefaultViewportMouseCaptureMode=CapturePermanently_IncludingInitialMouseDown
DefaultViewportMouseLockMode=LockOnCapture
FOVScale=0.011110
DoubleClickTime=0.200000
+ActionMappings=(ActionName="LeftShoulder",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=Gamepad_LeftShoulder)
+ActionMappings=(ActionName="RightShoulder",bShift=False,bCtrl=False,bAlt=False,bCmd=False,Key=Gamepad_RightShoulder)
DefaultPlayerInputClass=/Script/Engine.PlayerInput
DefaultInputComponentClass=/Script/Engine.InputComponent
DefaultTouchInterface=/Engine/MobileResources/HUD/DefaultVirtualJoysticks.DefaultVirtualJoysticks
-ConsoleKeys=Tilde
+ConsoleKeys=Tilde
Binary file not shown.
View File
+14
View File
@@ -0,0 +1,14 @@
// Copyright Epic Games, Inc. All Rights Reserved.
using UnrealBuildTool;
using System.Collections.Generic;
public class TurboLinkTestTarget : TargetRules
{
public TurboLinkTestTarget( TargetInfo Target) : base(Target)
{
Type = TargetType.Game;
DefaultBuildSettings = BuildSettingsVersion.V2;
ExtraModuleNames.AddRange( new string[] { "TurboLinkTest" } );
}
}
@@ -0,0 +1,170 @@
// Fill out your copyright notice in the Description page of Project Settings.
#include "TimeTestDSWidget.h"
#include "TurboLinkTestController.h"
#include "Components/Button.h"
#include "Components/EditableText.h"
#include "Components/TextBlock.h"
#include "TurboLinkGrpcManager.h"
#include "TurboLinkGrpcUtilities.h"
#include "TurboLinkGrpcConfig.h"
void UTimeTestDSWidget::NativeConstruct()
{
Super::NativeConstruct();
Button_ConnectTimeService->OnClicked.AddDynamic(this, &UTimeTestDSWidget::OnConnectServiceButtonClicked);
Button_ShutdownTimeService->OnClicked.AddDynamic(this, &UTimeTestDSWidget::OnShutdownServiceButtonClicked);
Button_CreateTimeClient->OnClicked.AddDynamic(this, &UTimeTestDSWidget::OnCreateClientButtonClicked);
Button_ShutdownTimeClient->OnClicked.AddDynamic(this, &UTimeTestDSWidget::OnShutdownClientButtonClicked);
Button_Now->OnClicked.AddDynamic(this, &UTimeTestDSWidget::OnNowButtonClicked);
Button_Now_Cancel->OnClicked.AddDynamic(this, &UTimeTestDSWidget::OnNowCancelButtonClicked);
Button_Ticktok->OnClicked.AddDynamic(this, &UTimeTestDSWidget::OnTicktokButtonClicked);
Button_Ticktok_Cancel->OnClicked.AddDynamic(this, &UTimeTestDSWidget::OnTicktokCancelButtonClicked);
Button_Watch->OnClicked.AddDynamic(this, &UTimeTestDSWidget::OnWatchButtonClicked);
Button_Watch_Send->OnClicked.AddDynamic(this, &UTimeTestDSWidget::OnWatchSendButtonClicked);
Button_Watch_Cancel->OnClicked.AddDynamic(this, &UTimeTestDSWidget::OnWatchCancelButtonClicked);
FString timeServiceEndPoint = UTurboLinkGrpcUtilities::GetTurboLinkGrpcConfig()->GetServiceEndPoint(TEXT("TimeService"));
TimeServiceAddress->SetText(FText::FromString(*timeServiceEndPoint));
TimeServiceAddress->SetIsReadOnly(true);
PC = Cast<ATurboLinkTestController>(GetWorld()->GetFirstPlayerController());
if (PC) {
PC->ClientWidget = this;
}
UpdateControlState();
}
void UTimeTestDSWidget::UpdateControlState()
{
if (!PC) return;
bool serviceConnected = (PC->GetTimeServiceState() == EGrpcServiceState::Ready || PC->GetTimeServiceState()== EGrpcServiceState::Idle);
bool clientCreated = PC->IsClientCreated();
Button_ConnectTimeService->SetIsEnabled(!serviceConnected);
Button_ShutdownTimeService->SetIsEnabled(serviceConnected || PC->GetTimeServiceState()== EGrpcServiceState::TransientFailure);
Button_CreateTimeClient->SetIsEnabled(serviceConnected && !clientCreated);
Button_ShutdownTimeClient->SetIsEnabled(clientCreated);
Button_Now->SetIsEnabled(serviceConnected && clientCreated && PC->GetCtxNowState() == EGrpcContextState::Done);
Button_Now_Cancel->SetIsEnabled(serviceConnected && clientCreated && (PC->GetCtxNowState() == EGrpcContextState::Initialing || PC->GetCtxNowState() == EGrpcContextState::Busy));
Button_Ticktok->SetIsEnabled(serviceConnected && clientCreated && PC->GetCtxTicktokState() == EGrpcContextState::Done);
Button_Ticktok_Cancel->SetIsEnabled(serviceConnected && clientCreated && (PC->GetCtxTicktokState() == EGrpcContextState::Initialing || PC->GetCtxTicktokState() == EGrpcContextState::Busy));
Button_Watch->SetIsEnabled(serviceConnected && clientCreated && PC->GetCtxWatchState() == EGrpcContextState::Done);
Button_Watch_Send->SetIsEnabled(serviceConnected && clientCreated && PC->GetCtxWatchState() == EGrpcContextState::Busy);
Button_Watch_Cancel->SetIsEnabled(serviceConnected && clientCreated && (PC->GetCtxWatchState() == EGrpcContextState::Initialing || PC->GetCtxWatchState() == EGrpcContextState::Busy));
}
void UTimeTestDSWidget::OnConnectServiceButtonClicked()
{
if (!PC) return;
bool serviceConnected = (PC->GetTimeServiceState() == EGrpcServiceState::Ready);
if (serviceConnected) return;
PC->ConnectToTimeService();
}
void UTimeTestDSWidget::OnShutdownServiceButtonClicked()
{
if (!PC) return;
bool serviceConnected = (PC->GetTimeServiceState() == EGrpcServiceState::Ready);
if (serviceConnected || PC->GetTimeServiceState() == EGrpcServiceState::TransientFailure)
{
PC->ShutdownTimeService();
}
}
void UTimeTestDSWidget::OnCreateClientButtonClicked()
{
if (!PC) return;
if (PC->IsClientCreated()) return;
PC->CreateTimeClient();
}
void UTimeTestDSWidget::OnShutdownClientButtonClicked()
{
if (!PC) return;
if (!(PC->IsClientCreated())) return;
PC->ShutdownTimeClient();
}
void UTimeTestDSWidget::OnNowButtonClicked()
{
if (!PC) return;
if (!(PC->IsClientCreated())) return;
if (PC->GetCtxNowState() != EGrpcContextState::Done) return;
PC->CallTimeNow();
}
void UTimeTestDSWidget::OnNowCancelButtonClicked()
{
if (!PC) return;
if (!(PC->IsClientCreated())) return;
if (PC->GetCtxNowState() == EGrpcContextState::Done) return;
PC->CancelTimeNow();
}
void UTimeTestDSWidget::OnTicktokButtonClicked()
{
if (!PC) return;
if (!(PC->IsClientCreated())) return;
if (PC->GetCtxTicktokState() != EGrpcContextState::Done) return;
int32 counts = FCString::Atoi(*(TicktokCounts->GetText().ToString()));
PC->CallTimeTicktok(counts);
}
void UTimeTestDSWidget::OnTicktokCancelButtonClicked()
{
if (!PC) return;
if (!(PC->IsClientCreated())) return;
if (PC->GetCtxTicktokState() == EGrpcContextState::Done) return;
PC->CancelTimeTicktok();
}
void UTimeTestDSWidget::OnWatchButtonClicked()
{
if (!PC) return;
if (!(PC->IsClientCreated())) return;
if (PC->GetCtxWatchState() != EGrpcContextState::Done) return;
PC->InitTimeWatch();
}
void UTimeTestDSWidget::OnWatchSendButtonClicked()
{
if (!PC) return;
if (!(PC->IsClientCreated())) return;
if (PC->GetCtxWatchState() != EGrpcContextState::Busy) return;
PC->CallTimeWatch();
}
void UTimeTestDSWidget::OnWatchCancelButtonClicked()
{
if (!PC) return;
if (!(PC->IsClientCreated())) return;
if (PC->GetCtxWatchState() == EGrpcContextState::Done) return;
PC->CancelTimeWatch();
}
@@ -0,0 +1,117 @@
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "Blueprint/UserWidget.h"
#include "SGreeter/GreeterService.h"
#include "TimeTestDSWidget.generated.h"
class ATurboLinkTestController;
/**
*
*/
UCLASS()
class TURBOLINKTEST_API UTimeTestDSWidget : public UUserWidget
{
GENERATED_BODY()
public:
virtual void NativeConstruct() override;
public:
UPROPERTY(BlueprintReadOnly, meta = (BindWidget))
class UEditableText* TimeServiceAddress;
UPROPERTY(BlueprintReadOnly, meta = (BindWidget))
class UTextBlock* TimeServiceStatus;
UPROPERTY(BlueprintReadOnly, meta = (BindWidget))
class UButton* Button_ConnectTimeService;
UPROPERTY(BlueprintReadOnly, meta = (BindWidget))
class UButton* Button_ShutdownTimeService;
UPROPERTY(BlueprintReadOnly, meta = (BindWidget))
class UButton* Button_CreateTimeClient;
UPROPERTY(BlueprintReadOnly, meta = (BindWidget))
class UButton* Button_ShutdownTimeClient;
UPROPERTY(BlueprintReadOnly, meta = (BindWidget))
class UButton* Button_Now;
UPROPERTY(BlueprintReadOnly, meta = (BindWidget))
class UTextBlock* TextResultNow;
UPROPERTY(BlueprintReadOnly, meta = (BindWidget))
class UButton* Button_Now_Cancel;
UPROPERTY(BlueprintReadOnly, meta = (BindWidget))
class UButton* Button_Ticktok;
UPROPERTY(BlueprintReadOnly, meta = (BindWidget))
class UEditableText* TicktokCounts;
UPROPERTY(BlueprintReadOnly, meta = (BindWidget))
class UTextBlock* TextResultTicktok;
UPROPERTY(BlueprintReadOnly, meta = (BindWidget))
class UButton* Button_Ticktok_Cancel;
UPROPERTY(BlueprintReadOnly, meta = (BindWidget))
class UButton* Button_Watch;
UPROPERTY(BlueprintReadOnly, meta = (BindWidget))
class UButton* Button_Watch_Send;
UPROPERTY(BlueprintReadOnly, meta = (BindWidget))
class UTextBlock* TextResultWatch;
UPROPERTY(BlueprintReadOnly, meta = (BindWidget))
class UButton* Button_Watch_Cancel;
protected:
UFUNCTION()
void OnConnectServiceButtonClicked();
UFUNCTION()
void OnShutdownServiceButtonClicked();
UFUNCTION()
void OnCreateClientButtonClicked();
UFUNCTION()
void OnShutdownClientButtonClicked();
UFUNCTION()
void OnNowButtonClicked();
UFUNCTION()
void OnNowCancelButtonClicked();
UFUNCTION()
void OnTicktokButtonClicked();
UFUNCTION()
void OnTicktokCancelButtonClicked();
UFUNCTION()
void OnWatchButtonClicked();
UFUNCTION()
void OnWatchSendButtonClicked();
UFUNCTION()
void OnWatchCancelButtonClicked();
protected:
UPROPERTY(BlueprintReadOnly)
ATurboLinkTestController* PC;
public:
void UpdateControlState();
};
@@ -0,0 +1,270 @@
// Fill out your copyright notice in the Description page of Project Settings.
#include "TimeTestWidget.h"
#include "Components/Button.h"
#include "Components/EditableText.h"
#include "Components/TextBlock.h"
#include "TurboLinkGrpcManager.h"
#include "TurboLinkGrpcUtilities.h"
#include "TurboLinkGrpcConfig.h"
void UTimeTestWidget::NativeConstruct()
{
Super::NativeConstruct();
Button_ConnectTimeService->OnClicked.AddDynamic(this, &UTimeTestWidget::OnConnectServiceButtonClicked);
Button_ShutdownTimeService->OnClicked.AddDynamic(this, &UTimeTestWidget::OnShutdownServiceButtonClicked);
Button_CreateTimeClient->OnClicked.AddDynamic(this, &UTimeTestWidget::OnCreateClientButtonClicked);
Button_ShutdownTimeClient->OnClicked.AddDynamic(this, &UTimeTestWidget::OnShutdownClientButtonClicked);
Button_Now->OnClicked.AddDynamic(this, &UTimeTestWidget::OnNowButtonClicked);
Button_Now_Cancel->OnClicked.AddDynamic(this, &UTimeTestWidget::OnNowCancelButtonClicked);
Button_Ticktok->OnClicked.AddDynamic(this, &UTimeTestWidget::OnTicktokButtonClicked);
Button_Ticktok_Cancel->OnClicked.AddDynamic(this, &UTimeTestWidget::OnTicktokCancelButtonClicked);
Button_Watch->OnClicked.AddDynamic(this, &UTimeTestWidget::OnWatchButtonClicked);
Button_Watch_Send->OnClicked.AddDynamic(this, &UTimeTestWidget::OnWatchSendButtonClicked);
Button_Watch_Cancel->OnClicked.AddDynamic(this, &UTimeTestWidget::OnWatchCancelButtonClicked);
FString timeServiceEndPoint = UTurboLinkGrpcUtilities::GetTurboLinkGrpcConfig()->GetServiceEndPoint(TEXT("TimeService"));
TimeServiceAddress->SetText(FText::FromString(*timeServiceEndPoint));
TimeServiceAddress->SetIsReadOnly(true);
UpdateControlState();
}
void UTimeTestWidget::UpdateControlState()
{
bool serviceConnected = (TimeService!=nullptr && (TimeService->GetServiceState()==EGrpcServiceState::Ready || TimeService->GetServiceState() == EGrpcServiceState::Idle));
bool clientCreated = (TimeServiceClient != nullptr);
Button_ConnectTimeService->SetIsEnabled(TimeService == nullptr);
Button_ShutdownTimeService->SetIsEnabled(serviceConnected || (TimeService != nullptr && TimeService->GetServiceState() == EGrpcServiceState::TransientFailure));
Button_CreateTimeClient->SetIsEnabled(serviceConnected && !clientCreated);
Button_ShutdownTimeClient->SetIsEnabled(clientCreated);
Button_Now->SetIsEnabled(serviceConnected && clientCreated && TimeServiceClient->GetContextState(CtxNow) == EGrpcContextState::Done);
Button_Now_Cancel->SetIsEnabled(serviceConnected && clientCreated&& (TimeServiceClient->GetContextState(CtxNow) == EGrpcContextState::Initialing || TimeServiceClient->GetContextState(CtxNow) == EGrpcContextState::Busy));
Button_Ticktok->SetIsEnabled(serviceConnected && clientCreated && TimeServiceClient->GetContextState(CtxTicktok) == EGrpcContextState::Done);
Button_Ticktok_Cancel->SetIsEnabled(serviceConnected && clientCreated && (TimeServiceClient->GetContextState(CtxTicktok) == EGrpcContextState::Initialing || TimeServiceClient->GetContextState(CtxTicktok) == EGrpcContextState::Busy));
Button_Watch->SetIsEnabled(serviceConnected && clientCreated && TimeServiceClient->GetContextState(CtxWatch) == EGrpcContextState::Done);
Button_Watch_Send->SetIsEnabled(serviceConnected && clientCreated && TimeServiceClient->GetContextState(CtxWatch) == EGrpcContextState::Busy);
Button_Watch_Cancel->SetIsEnabled(serviceConnected && clientCreated && (TimeServiceClient->GetContextState(CtxWatch) == EGrpcContextState::Initialing || TimeServiceClient->GetContextState(CtxWatch) == EGrpcContextState::Busy));
}
void UTimeTestWidget::OnConnectServiceButtonClicked()
{
if (TimeService != nullptr) return;
UTurboLinkGrpcManager* turboLinkManager = UTurboLinkGrpcUtilities::GetTurboLinkGrpcManager();
//create service adapter
TimeService = Cast<UTimeService>(turboLinkManager->MakeService("TimeService"));
if (TimeService==nullptr)
{
UE_LOG(LogTemp, Error, TEXT("Can't find time service!"));
return;
}
TimeService->OnServiceStateChanged.AddUniqueDynamic(this, &UTimeTestWidget::OnTimeServiceStateChanged);
TimeService->Connect();
UpdateControlState();
}
void UTimeTestWidget::OnShutdownServiceButtonClicked()
{
if (TimeService != nullptr)
{
if (TimeServiceClient!=nullptr)
{
TimeServiceClient->Shutdown();
TimeServiceClient = nullptr;
}
TimeService->Shutdown();
TimeService = nullptr;
UpdateControlState();
}
}
void UTimeTestWidget::OnCreateClientButtonClicked()
{
if (TimeService != nullptr && TimeService->GetServiceState() == EGrpcServiceState::Ready)
{
if (TimeServiceClient != nullptr) return;
//create client
TimeServiceClient = TimeService->MakeClient();
TimeServiceClient->OnContextStateChange.AddUniqueDynamic(this, &UTimeTestWidget::OnContextStateChange);
TimeServiceClient->OnNowResponse.AddUniqueDynamic(this, &UTimeTestWidget::OnTimeNowResponse);
TimeServiceClient->OnTicktokResponse.AddUniqueDynamic(this, &UTimeTestWidget::OnTimeTicktokResponse);
TimeServiceClient->OnWatchResponse.AddUniqueDynamic(this, &UTimeTestWidget::OnTimeWatchResponse);
UpdateControlState();
}
}
void UTimeTestWidget::OnShutdownClientButtonClicked()
{
if (TimeServiceClient != nullptr)
{
TimeServiceClient->Shutdown();
TimeServiceClient = nullptr;
UpdateControlState();
}
}
void UTimeTestWidget::OnTimeServiceStateChanged(EGrpcServiceState NewState)
{
int preFixLen = FString(TEXT("EGrpcServiceState::")).Len();
TimeServiceStatus->SetText(FText::FromString(UEnum::GetValueAsString(NewState).RightChop(preFixLen)));
UpdateControlState();
}
void UTimeTestWidget::OnContextStateChange(FGrpcContextHandle Handle, EGrpcContextState State)
{
UpdateControlState();
}
void UTimeTestWidget::OnNowButtonClicked()
{
if (TimeService == nullptr ||
(TimeService->GetServiceState() != EGrpcServiceState::Ready && TimeService->GetServiceState()!= EGrpcServiceState::Idle) ||
TimeServiceClient==nullptr)
{
UE_LOG(LogTemp, Warning, TEXT("Connect to time service first!"));
return;
}
if (TimeServiceClient->GetContextState(CtxNow) != EGrpcContextState::Done)
{
UE_LOG(LogTemp, Warning, TEXT("Busy!"));
return;
}
CtxNow = TimeServiceClient->InitNow();
TimeServiceClient->Now(CtxNow, {});
}
void UTimeTestWidget::OnNowCancelButtonClicked()
{
if (TimeServiceClient && TimeServiceClient->GetContextState(CtxNow) != EGrpcContextState::Done)
{
TimeServiceClient->TryCancelContext(CtxNow);
}
}
void UTimeTestWidget::OnTimeNowResponse(FGrpcContextHandle Handle, const FGrpcResult& Result, const FGrpcGreeterNowResponse& Response)
{
if (Result.Code == EGrpcResultCode::Ok)
{
FString value = FString::Printf(TEXT("%lld"), Response.Now);
TextResultNow->SetText(FText::FromString(value));
}
else
{
TextResultNow->SetText(FText::FromString(Result.GetCodeString()));
}
}
void UTimeTestWidget::OnTicktokButtonClicked()
{
if (TimeService == nullptr ||
(TimeService->GetServiceState() != EGrpcServiceState::Ready && TimeService->GetServiceState() != EGrpcServiceState::Idle) ||
TimeServiceClient == nullptr)
{
UE_LOG(LogTemp, Warning, TEXT("Connect to time service first!"));
return;
}
if (TimeServiceClient->GetContextState(CtxTicktok) != EGrpcContextState::Done)
{
UE_LOG(LogTemp, Warning, TEXT("Busy!"));
return;
}
CtxTicktok = TimeServiceClient->InitTicktok();
FGrpcGreeterTicktokRequest request;
request.Counts = FCString::Atoi(*(TicktokCounts->GetText().ToString()));
TimeServiceClient->Ticktok(CtxTicktok, request);
}
void UTimeTestWidget::OnTimeTicktokResponse(FGrpcContextHandle Handle, const FGrpcResult& Result, const FGrpcGreeterNowResponse& Response)
{
if (Result.Code == EGrpcResultCode::Ok)
{
FString value = FString::Printf(TEXT("%lld/%d"), Response.Now, Response.Counts);
TextResultTicktok->SetText(FText::FromString(value));
}
else
{
TextResultTicktok->SetText(FText::FromString(Result.GetCodeString()));
}
}
void UTimeTestWidget::OnTicktokCancelButtonClicked()
{
if (TimeServiceClient && TimeServiceClient->GetContextState(CtxTicktok) != EGrpcContextState::Done)
{
TimeServiceClient->TryCancelContext(CtxTicktok);
}
}
void UTimeTestWidget::OnWatchButtonClicked()
{
if (TimeService == nullptr ||
(TimeService->GetServiceState() != EGrpcServiceState::Ready && TimeService->GetServiceState() != EGrpcServiceState::Idle) ||
TimeServiceClient == nullptr)
{
UE_LOG(LogTemp, Warning, TEXT("Connect to time service first!"));
return;
}
if (TimeServiceClient->GetContextState(CtxWatch) != EGrpcContextState::Done)
{
UE_LOG(LogTemp, Warning, TEXT("Busy!"));
return;
}
CtxWatch = TimeServiceClient->InitWatch();
}
void UTimeTestWidget::OnWatchSendButtonClicked()
{
if (TimeServiceClient && TimeServiceClient->GetContextState(CtxWatch) == EGrpcContextState::Busy)
{
TimeServiceClient->Watch(CtxWatch, {});
}
}
void UTimeTestWidget::OnWatchCancelButtonClicked()
{
if (TimeServiceClient && TimeServiceClient->GetContextState(CtxWatch) != EGrpcContextState::Done)
{
TimeServiceClient->TryCancel(CtxWatch);
}
}
void UTimeTestWidget::OnTimeWatchResponse(FGrpcContextHandle Handle, const FGrpcResult& Result, const FGrpcGreeterNowResponse& Response)
{
if (Result.Code == EGrpcResultCode::Ok)
{
FString value = FString::Printf(TEXT("%lld"), Response.Now);
TextResultWatch->SetText(FText::FromString(value));
}
else
{
TextResultWatch->SetText(FText::FromString(Result.GetCodeString()));
}
}
@@ -0,0 +1,141 @@
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "Blueprint/UserWidget.h"
#include "SGreeter/GreeterService.h"
#include "TimeTestWidget.generated.h"
/**
*
*/
UCLASS()
class TURBOLINKTEST_API UTimeTestWidget : public UUserWidget
{
GENERATED_BODY()
public:
virtual void NativeConstruct() override;
protected:
UPROPERTY(BlueprintReadOnly, meta = (BindWidget))
class UEditableText* TimeServiceAddress;
UPROPERTY(BlueprintReadOnly, meta = (BindWidget))
class UTextBlock* TimeServiceStatus;
UPROPERTY(BlueprintReadOnly, meta = (BindWidget))
class UButton* Button_ConnectTimeService;
UPROPERTY(BlueprintReadOnly, meta = (BindWidget))
class UButton* Button_ShutdownTimeService;
UPROPERTY(BlueprintReadOnly, meta = (BindWidget))
class UButton* Button_CreateTimeClient;
UPROPERTY(BlueprintReadOnly, meta = (BindWidget))
class UButton* Button_ShutdownTimeClient;
UPROPERTY(BlueprintReadOnly, meta = (BindWidget))
class UButton* Button_Now;
UPROPERTY(BlueprintReadOnly, meta = (BindWidget))
class UTextBlock* TextResultNow;
UPROPERTY(BlueprintReadOnly, meta = (BindWidget))
class UButton* Button_Now_Cancel;
UPROPERTY(BlueprintReadOnly, meta = (BindWidget))
class UButton* Button_Ticktok;
UPROPERTY(BlueprintReadOnly, meta = (BindWidget))
class UEditableText* TicktokCounts;
UPROPERTY(BlueprintReadOnly, meta = (BindWidget))
class UTextBlock* TextResultTicktok;
UPROPERTY(BlueprintReadOnly, meta = (BindWidget))
class UButton* Button_Ticktok_Cancel;
UPROPERTY(BlueprintReadOnly, meta = (BindWidget))
class UButton* Button_Watch;
UPROPERTY(BlueprintReadOnly, meta = (BindWidget))
class UButton* Button_Watch_Send;
UPROPERTY(BlueprintReadOnly, meta = (BindWidget))
class UTextBlock* TextResultWatch;
UPROPERTY(BlueprintReadOnly, meta = (BindWidget))
class UButton* Button_Watch_Cancel;
protected:
UPROPERTY(BlueprintReadOnly)
UTimeService* TimeService;
UPROPERTY(BlueprintReadOnly)
UTimeServiceClient* TimeServiceClient;
FGrpcContextHandle CtxNow;
UFUNCTION()
void OnTimeNowResponse(FGrpcContextHandle Handle, const FGrpcResult& Result, const FGrpcGreeterNowResponse& Response);
FGrpcContextHandle CtxTicktok;
UFUNCTION()
void OnTimeTicktokResponse(FGrpcContextHandle Handle, const FGrpcResult& Result, const FGrpcGreeterNowResponse& Response);
FGrpcContextHandle CtxWatch;
UFUNCTION()
void OnTimeWatchResponse(FGrpcContextHandle Handle, const FGrpcResult& Result, const FGrpcGreeterNowResponse& Response);
protected:
UFUNCTION()
void OnTimeServiceStateChanged(EGrpcServiceState NewState);
UFUNCTION()
void OnContextStateChange(FGrpcContextHandle Handle, EGrpcContextState State);
UFUNCTION()
void OnConnectServiceButtonClicked();
UFUNCTION()
void OnShutdownServiceButtonClicked();
UFUNCTION()
void OnCreateClientButtonClicked();
UFUNCTION()
void OnShutdownClientButtonClicked();
UFUNCTION()
void OnNowButtonClicked();
UFUNCTION()
void OnNowCancelButtonClicked();
UFUNCTION()
void OnTicktokButtonClicked();
UFUNCTION()
void OnTicktokCancelButtonClicked();
UFUNCTION()
void OnWatchButtonClicked();
UFUNCTION()
void OnWatchSendButtonClicked();
UFUNCTION()
void OnWatchCancelButtonClicked();
protected:
void UpdateControlState();
};
@@ -0,0 +1,30 @@
// Copyright Epic Games, Inc. All Rights Reserved.
using UnrealBuildTool;
public class TurboLinkTest : ModuleRules
{
public TurboLinkTest(ReadOnlyTargetRules Target) : base(Target)
{
PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
PublicDependencyModuleNames.AddRange(new string[] {
"Core",
"CoreUObject",
"Engine",
"InputCore"
});
PrivateDependencyModuleNames.AddRange(new string[] {
"TurboLinkGrpc"
});
// Uncomment if you are using Slate UI
// PrivateDependencyModuleNames.AddRange(new string[] { "Slate", "SlateCore" });
// Uncomment if you are using online features
// PrivateDependencyModuleNames.Add("OnlineSubsystem");
// To include OnlineSubsystemSteam, add it to the plugins section in your uproject file with the Enabled attribute set to true
}
}
@@ -0,0 +1,6 @@
// Copyright Epic Games, Inc. All Rights Reserved.
#include "TurboLinkTest.h"
#include "Modules/ModuleManager.h"
IMPLEMENT_PRIMARY_GAME_MODULE( FDefaultGameModuleImpl, TurboLinkTest, "TurboLinkTest" );
@@ -0,0 +1,6 @@
// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
@@ -0,0 +1,304 @@
// Fill out your copyright notice in the Description page of Project Settings.
#include "TurboLinkTestController.h"
#include "TurboLinkGrpcManager.h"
#include "TurboLinkGrpcUtilities.h"
#include "TimeTestDSWidget.h"
#include "Net/UnrealNetwork.h"
#include "Components/TextBlock.h"
void ATurboLinkTestController::GetLifetimeReplicatedProps(TArray <FLifetimeProperty>& OutLifetimeProps) const
{
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
//Replicate current health.
DOREPLIFETIME(ATurboLinkTestController, TimeServiceState);
DOREPLIFETIME(ATurboLinkTestController, bIsClientCreated);
DOREPLIFETIME(ATurboLinkTestController, CtxNowState);
DOREPLIFETIME(ATurboLinkTestController, NowResult);
DOREPLIFETIME(ATurboLinkTestController, CtxTicktokState);
DOREPLIFETIME(ATurboLinkTestController, TicktokResult);
DOREPLIFETIME(ATurboLinkTestController, CtxWatchState);
DOREPLIFETIME(ATurboLinkTestController, WatchResult);
}
void ATurboLinkTestController::ConnectToTimeService_Implementation()
{
if (TimeService != nullptr) return;
UTurboLinkGrpcManager* turboLinkManager = UTurboLinkGrpcUtilities::GetTurboLinkGrpcManager();
//create service adapter
TimeService = Cast<UTimeService>(turboLinkManager->MakeService("TimeService"));
if (TimeService == nullptr)
{
UE_LOG(LogTemp, Error, TEXT("Can't find time service!"));
return;
}
TimeService->OnServiceStateChanged.AddUniqueDynamic(this, &ATurboLinkTestController::OnTimeServiceStateChanged);
UE_LOG(LogTemp, Warning, TEXT("[DS]Connect to time service"));
TimeService->Connect();
}
void ATurboLinkTestController::ShutdownTimeService_Implementation()
{
if (TimeService != nullptr)
{
if (TimeServiceClient != nullptr)
{
TimeServiceClient->Shutdown();
TimeServiceClient = nullptr;
}
TimeService->Shutdown();
TimeService = nullptr;
bIsClientCreated = false;
TimeServiceState = EGrpcServiceState::Shutdown;
}
}
void ATurboLinkTestController::CreateTimeClient_Implementation()
{
if (TimeService != nullptr && TimeService->GetServiceState() == EGrpcServiceState::Ready)
{
if (TimeServiceClient != nullptr) return;
//create client
TimeServiceClient = TimeService->MakeClient();
TimeServiceClient->OnContextStateChange.AddUniqueDynamic(this, &ATurboLinkTestController::OnContextStateChange);
TimeServiceClient->OnNowResponse.AddUniqueDynamic(this, &ATurboLinkTestController::OnTimeNowResponse);
TimeServiceClient->OnTicktokResponse.AddUniqueDynamic(this, &ATurboLinkTestController::OnTimeTicktokResponse);
TimeServiceClient->OnWatchResponse.AddUniqueDynamic(this, &ATurboLinkTestController::OnTimeWatchResponse);
bIsClientCreated = true;
}
}
void ATurboLinkTestController::ShutdownTimeClient_Implementation()
{
if (TimeServiceClient != nullptr)
{
TimeServiceClient->Shutdown();
TimeServiceClient = nullptr;
bIsClientCreated = false;
}
}
void ATurboLinkTestController::OnTimeServiceStateChanged(EGrpcServiceState NewState)
{
TimeServiceState = NewState;
}
void ATurboLinkTestController::OnRep_TimeServiceState()
{
int preFixLen = FString(TEXT("EGrpcServiceState::")).Len();
FString timeServiceStateString = UEnum::GetValueAsString(TimeServiceState).RightChop(preFixLen);
UE_LOG(LogTemp, Warning, TEXT("[Client]Time service state:%s"), *timeServiceStateString);
if (ClientWidget && ClientWidget->TimeServiceStatus)
{
ClientWidget->TimeServiceStatus->SetText(FText::FromString(timeServiceStateString));
ClientWidget->UpdateControlState();
}
}
void ATurboLinkTestController::OnRep_ClientCreated()
{
if (ClientWidget)
{
ClientWidget->UpdateControlState();
}
}
void ATurboLinkTestController::CallTimeNow_Implementation()
{
if (TimeService == nullptr ||
(TimeService->GetServiceState() != EGrpcServiceState::Ready && TimeService->GetServiceState() != EGrpcServiceState::Idle) ||
TimeServiceClient == nullptr)
{
UE_LOG(LogTemp, Error, TEXT("[DS]Connect to time service first!"));
return;
}
if (TimeServiceClient->GetContextState(CtxNow) != EGrpcContextState::Done)
{
UE_LOG(LogTemp, Error, TEXT("[DS] Busy!"));
return;
}
UE_LOG(LogTemp, Warning, TEXT("[DS] Call Time Now!"));
CtxNow = TimeServiceClient->InitNow();
TimeServiceClient->Now(CtxNow, {});
}
void ATurboLinkTestController::CancelTimeNow_Implementation()
{
if (TimeServiceClient && TimeServiceClient->GetContextState(CtxNow) != EGrpcContextState::Done)
{
UE_LOG(LogTemp, Warning, TEXT("[DS] Cancel Time Now!"));
TimeServiceClient->TryCancelContext(CtxNow);
}
}
void ATurboLinkTestController::CallTimeTicktok_Implementation(int32 Counts)
{
if (TimeService == nullptr ||
(TimeService->GetServiceState() != EGrpcServiceState::Ready && TimeService->GetServiceState() != EGrpcServiceState::Idle) ||
TimeServiceClient == nullptr)
{
UE_LOG(LogTemp, Error, TEXT("[DS]Connect to time service first!"));
return;
}
if (TimeServiceClient->GetContextState(CtxTicktok) != EGrpcContextState::Done)
{
UE_LOG(LogTemp, Error, TEXT("[DS] Busy!"));
return;
}
UE_LOG(LogTemp, Warning, TEXT("[DS] Call Time Clock(%d)!"), Counts);
CtxTicktok = TimeServiceClient->InitTicktok();
FGrpcGreeterTicktokRequest request;
request.Counts = Counts;
TimeServiceClient->Ticktok(CtxTicktok, request);
}
void ATurboLinkTestController::CancelTimeTicktok_Implementation()
{
if (TimeServiceClient && TimeServiceClient->GetContextState(CtxTicktok) != EGrpcContextState::Done)
{
UE_LOG(LogTemp, Warning, TEXT("[DS] Cancel Time Clock!"));
TimeServiceClient->TryCancelContext(CtxTicktok);
}
}
void ATurboLinkTestController::InitTimeWatch_Implementation()
{
if (TimeService == nullptr ||
(TimeService->GetServiceState() != EGrpcServiceState::Ready && TimeService->GetServiceState() != EGrpcServiceState::Idle) ||
TimeServiceClient == nullptr)
{
UE_LOG(LogTemp, Error, TEXT("[DS]Connect to time service first!"));
return;
}
if (TimeServiceClient->GetContextState(CtxWatch) != EGrpcContextState::Done)
{
UE_LOG(LogTemp, Error, TEXT("[DS] Busy!"));
return;
}
UE_LOG(LogTemp, Warning, TEXT("[DS] Init Time Watch!"));
CtxWatch = TimeServiceClient->InitWatch();
}
void ATurboLinkTestController::CallTimeWatch_Implementation()
{
if (TimeServiceClient && TimeServiceClient->GetContextState(CtxWatch) == EGrpcContextState::Busy)
{
UE_LOG(LogTemp, Warning, TEXT("[DS] Send Time Watch!"));
TimeServiceClient->Watch(CtxWatch, {});
}
}
void ATurboLinkTestController::CancelTimeWatch_Implementation()
{
if (TimeServiceClient && TimeServiceClient->GetContextState(CtxWatch) != EGrpcContextState::Done)
{
UE_LOG(LogTemp, Warning, TEXT("[DS] Cancel Time Watch!"));
TimeServiceClient->TryCancel(CtxWatch);
}
}
void ATurboLinkTestController::OnContextStateChange(FGrpcContextHandle Handle, EGrpcContextState State)
{
CtxNowState = TimeServiceClient->GetContextState(CtxNow);
CtxTicktokState = TimeServiceClient->GetContextState(CtxTicktok);
CtxWatchState = TimeServiceClient->GetContextState(CtxWatch);
}
void ATurboLinkTestController::OnRep_TimeContextState()
{
if (ClientWidget)
{
ClientWidget->UpdateControlState();
}
}
void ATurboLinkTestController::OnTimeNowResponse(FGrpcContextHandle Handle, const FGrpcResult& Result, const FGrpcGreeterNowResponse& Response)
{
if (Result.Code == EGrpcResultCode::Ok)
{
NowResult = FString::Printf(TEXT("%lld"), Response.Now);
}
else
{
NowResult = Result.GetCodeString();
}
UE_LOG(LogTemp, Warning, TEXT("[DS] On Time Now Response: %s"), *NowResult);
}
void ATurboLinkTestController::OnRep_TimeNowResult()
{
if (ClientWidget && ClientWidget->TextResultNow)
{
ClientWidget->TextResultNow->SetText(FText::FromString(NowResult));
ClientWidget->UpdateControlState();
}
}
void ATurboLinkTestController::OnTimeTicktokResponse(FGrpcContextHandle Handle, const FGrpcResult& Result, const FGrpcGreeterNowResponse& Response)
{
if (Result.Code == EGrpcResultCode::Ok)
{
TicktokResult = FString::Printf(TEXT("%lld/%d"), Response.Now, Response.Counts);
}
else
{
TicktokResult = Result.GetCodeString();
}
UE_LOG(LogTemp, Warning, TEXT("[DS] On Time Clock Response: %s"), *TicktokResult);
}
void ATurboLinkTestController::OnRep_TimeTicktokResult()
{
if (ClientWidget && ClientWidget->TextResultTicktok)
{
ClientWidget->TextResultTicktok->SetText(FText::FromString(TicktokResult));
ClientWidget->UpdateControlState();
}
}
void ATurboLinkTestController::OnTimeWatchResponse(FGrpcContextHandle Handle, const FGrpcResult& Result, const FGrpcGreeterNowResponse& Response)
{
if (Result.Code == EGrpcResultCode::Ok)
{
WatchResult = FString::Printf(TEXT("%lld"), Response.Now);
}
else
{
WatchResult = Result.GetCodeString();
}
UE_LOG(LogTemp, Warning, TEXT("[DS] On Time Watch Response: %s"), *WatchResult);
}
void ATurboLinkTestController::OnRep_TimeWatchResult()
{
if (ClientWidget && ClientWidget->TextResultWatch)
{
ClientWidget->TextResultWatch->SetText(FText::FromString(WatchResult));
ClientWidget->UpdateControlState();
}
}
@@ -0,0 +1,149 @@
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/PlayerController.h"
#include "SGreeter/GreeterService.h"
#include "TurboLinkTestController.generated.h"
class UTimeTestDSWidget;
/**
*
*/
UCLASS()
class TURBOLINKTEST_API ATurboLinkTestController : public APlayerController
{
GENERATED_BODY()
public:
UFUNCTION(BlueprintCallable, Server, Reliable)
void ConnectToTimeService();
UFUNCTION(BlueprintCallable, Server, Reliable)
void ShutdownTimeService();
UFUNCTION(BlueprintCallable, Server, Reliable)
void CreateTimeClient();
UFUNCTION(BlueprintCallable, Server, Reliable)
void ShutdownTimeClient();
UFUNCTION(BlueprintCallable, Server, Reliable)
void CallTimeNow();
UFUNCTION(BlueprintCallable, Server, Reliable)
void CancelTimeNow();
UFUNCTION(BlueprintCallable, Server, Reliable)
void CallTimeTicktok(int32 Counts);
UFUNCTION(BlueprintCallable, Server, Reliable)
void CancelTimeTicktok();
UFUNCTION(BlueprintCallable, Server, Reliable)
void InitTimeWatch();
UFUNCTION(BlueprintCallable, Server, Reliable)
void CallTimeWatch();
UFUNCTION(BlueprintCallable, Server, Reliable)
void CancelTimeWatch();
protected:
UPROPERTY(BlueprintReadOnly)
UTimeService* TimeService;
UFUNCTION()
void OnTimeServiceStateChanged(EGrpcServiceState NewState);
UPROPERTY(BlueprintReadOnly)
UTimeServiceClient* TimeServiceClient;
UFUNCTION()
void OnContextStateChange(FGrpcContextHandle Handle, EGrpcContextState State);
FGrpcContextHandle CtxNow;
UFUNCTION()
void OnTimeNowResponse(FGrpcContextHandle Handle, const FGrpcResult& Result, const FGrpcGreeterNowResponse& Response);
FGrpcContextHandle CtxTicktok;
UFUNCTION()
void OnTimeTicktokResponse(FGrpcContextHandle Handle, const FGrpcResult& Result, const FGrpcGreeterNowResponse& Response);
FGrpcContextHandle CtxWatch;
UFUNCTION()
void OnTimeWatchResponse(FGrpcContextHandle Handle, const FGrpcResult& Result, const FGrpcGreeterNowResponse& Response);
public:
EGrpcServiceState GetTimeServiceState() const {
return TimeServiceState;
}
bool IsClientCreated() const {
return bIsClientCreated;
}
EGrpcContextState GetCtxNowState() const {
return CtxNowState;
}
EGrpcContextState GetCtxTicktokState() const {
return CtxTicktokState;
}
EGrpcContextState GetCtxWatchState() const {
return CtxWatchState;
}
UPROPERTY(BlueprintReadOnly)
UTimeTestDSWidget* ClientWidget;
protected:
UPROPERTY(ReplicatedUsing = OnRep_TimeServiceState)
EGrpcServiceState TimeServiceState;
UFUNCTION()
void OnRep_TimeServiceState();
UPROPERTY(ReplicatedUsing = OnRep_ClientCreated)
bool bIsClientCreated = false;
UFUNCTION()
void OnRep_ClientCreated();
protected:
UFUNCTION()
void OnRep_TimeContextState();
UPROPERTY(ReplicatedUsing = OnRep_TimeContextState)
EGrpcContextState CtxNowState = EGrpcContextState::Done;
UPROPERTY(ReplicatedUsing = OnRep_TimeContextState)
EGrpcContextState CtxTicktokState = EGrpcContextState::Done;
UPROPERTY(ReplicatedUsing = OnRep_TimeContextState)
EGrpcContextState CtxWatchState = EGrpcContextState::Done;
UPROPERTY(ReplicatedUsing = OnRep_TimeNowResult)
FString NowResult;
UFUNCTION()
void OnRep_TimeNowResult();
UPROPERTY(ReplicatedUsing = OnRep_TimeTicktokResult)
FString TicktokResult;
UFUNCTION()
void OnRep_TimeTicktokResult();
UPROPERTY(ReplicatedUsing = OnRep_TimeWatchResult)
FString WatchResult;
UFUNCTION()
void OnRep_TimeWatchResult();
};
@@ -0,0 +1,21 @@
// Fill out your copyright notice in the Description page of Project Settings.
#include "TurboLinkTestGameInstance.h"
#include "TurboLinkGrpcManager.h"
#include "TurboLinkGrpcUtilities.h"
void UTurboLinkTestGameInstance::Init()
{
Super::Init();
TurboLinkManager = UTurboLinkGrpcUtilities::GetTurboLinkGrpcManager();
TurboLinkManager->InitManager();
}
void UTurboLinkTestGameInstance::Shutdown()
{
// Unregister ticker delegate
TurboLinkManager->Shutdown();
TurboLinkManager = nullptr;
}
@@ -0,0 +1,25 @@
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "Engine/GameInstance.h"
#include "TurboLinkTestGameInstance.generated.h"
class UTurboLinkGrpcManager;
/**
*
*/
UCLASS()
class TURBOLINKTEST_API UTurboLinkTestGameInstance : public UGameInstance
{
GENERATED_BODY()
public:
void Init() override;
void Shutdown() override;
protected:
UPROPERTY()
UTurboLinkGrpcManager* TurboLinkManager;
};
@@ -0,0 +1,5 @@
// Copyright Epic Games, Inc. All Rights Reserved.
#include "TurboLinkTestGameModeBase.h"
@@ -0,0 +1,17 @@
// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/GameModeBase.h"
#include "TurboLinkTestGameModeBase.generated.h"
/**
*
*/
UCLASS()
class TURBOLINKTEST_API ATurboLinkTestGameModeBase : public AGameModeBase
{
GENERATED_BODY()
};
@@ -0,0 +1,34 @@
// Fill out your copyright notice in the Description page of Project Settings.
#include "TurboLinkTestPawn.h"
// Sets default values
ATurboLinkTestPawn::ATurboLinkTestPawn()
{
// Set this pawn to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
}
// Called when the game starts or when spawned
void ATurboLinkTestPawn::BeginPlay()
{
Super::BeginPlay();
}
// Called every frame
void ATurboLinkTestPawn::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
// Called to bind functionality to input
void ATurboLinkTestPawn::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);
}
@@ -0,0 +1,29 @@
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Pawn.h"
#include "TurboLinkTestPawn.generated.h"
UCLASS()
class TURBOLINKTEST_API ATurboLinkTestPawn : public APawn
{
GENERATED_BODY()
public:
// Sets default values for this pawn's properties
ATurboLinkTestPawn();
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
// Called to bind functionality to input
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
};
@@ -0,0 +1,14 @@
// Copyright Epic Games, Inc. All Rights Reserved.
using UnrealBuildTool;
using System.Collections.Generic;
public class TurboLinkTestEditorTarget : TargetRules
{
public TurboLinkTestEditorTarget( TargetInfo Target) : base(Target)
{
Type = TargetType.Editor;
DefaultBuildSettings = BuildSettingsVersion.V2;
ExtraModuleNames.AddRange( new string[] { "TurboLinkTest" } );
}
}
@@ -0,0 +1,21 @@
// Copyright Epic Games, Inc. All Rights Reserved.
using UnrealBuildTool;
using System.Collections.Generic;
[SupportedPlatforms(UnrealPlatformClass.Server)]
public class TurboLinkTestServerTarget : TargetRules
{
public TurboLinkTestServerTarget( TargetInfo Target) : base(Target)
{
Type = TargetType.Server;
ExtraModuleNames.AddRange( new string[] { "TurboLinkTest" } );
//These configurations are invalid for a Linux server build.
DisablePlugins.Add("WMFMediaPlayer");
DisablePlugins.Add("AsyncLoadingScreen"); //if you are using this plugin
DisablePlugins.Add("WindowsMoviePlayer");
DisablePlugins.Add("MediaFoundationMediaPlayer");
}
}
+18
View File
@@ -0,0 +1,18 @@
{
"FileVersion": 3,
"EngineAssociation": "4.27",
"Category": "",
"Description": "",
"Modules": [
{
"Name": "TurboLinkTest",
"Type": "Runtime",
"LoadingPhase": "Default",
"AdditionalDependencies": [
"Engine",
"UMG",
"CoreUObject"
]
}
]
}
+21
View File
@@ -0,0 +1,21 @@
-----BEGIN CERTIFICATE-----
MIIDaTCCAlGgAwIBAgIJALg9FEgTMGPaMA0GCSqGSIb3DQEBCwUAMEsxCzAJBgNV
BAYTAkNOMRAwDgYDVQQHDAdCZWlqaW5nMRIwEAYDVQQKDAlUdXJib0xpbmsxFjAU
BgNVBAMMDXR1cmJvbGluay5kZXYwHhcNMjIxMTMwMDI1NTE2WhcNMzIxMTI3MDI1
NTE2WjBLMQswCQYDVQQGEwJDTjEQMA4GA1UEBwwHQmVpamluZzESMBAGA1UECgwJ
VHVyYm9MaW5rMRYwFAYDVQQDDA10dXJib2xpbmsuZGV2MIIBIjANBgkqhkiG9w0B
AQEFAAOCAQ8AMIIBCgKCAQEAqLjDp7Xh4TVyMZnajYTm73U0I0k7WRkR0TqxHeyO
sUQ/yKk9Bv6XNxAEsJj7ofIwMDG7VWI6uuzCWdRD11HIf/fuEDOYqK46LFf+yQXf
+P6Y0I2t2vvMS/FntSzzkuz1veRWfFa0ssGV3Iv8jEgSvAfV1xU5rvnlULhVcevz
CMOvmesu5DSeEo9EIeugaUasiS2RR+TRJb4gflCPLZu0rL0+/mDNhsd3BXuRp/jE
h63F47/eFv3Us9jZ0D/hzmXnmJVzkVbyRwMYKZ8BnDuVhdBzT1yPjbL2A0Q9OIh6
IuGlHnbo907ZZgheGxyqSpDq794J5lWhHn5KY/fmpMPZiwIDAQABo1AwTjAdBgNV
HQ4EFgQUeRpYmEkuEnGbhwF66uNSmjVzgRkwHwYDVR0jBBgwFoAUeRpYmEkuEnGb
hwF66uNSmjVzgRkwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAeOuJ
nKz5/Ez1CiwMT4FwZoJPtjJw4ONSzbxMsekb/aubzNYY0T3w693DqZwVFmM573yq
d96ghHBfvVanPMJyHOJFRayZNgrDRKHHW75Jth03cAbQ6MahgVyys0VUrCsAFdAj
Zo2q504vVxBtq2pHzYetNDTF6SVjZp/XrMtgepggEtU6Zf1sDpk0Si694rksrO2p
3C+zkPtgVFd5cT2fihZ5imjUNqu/iRP95mjoKwtPRRGBUhJjN8UOuRyS08L/eUSf
IbN7ogcp6Y+WL6rmNvSVoXBl7wIWhGEWTscyzm66bWisZxGUFTicezL56CpkHdbo
NzR3/aU8S0eIDHSaiQ==
-----END CERTIFICATE-----
+16
View File
@@ -0,0 +1,16 @@
-----BEGIN CERTIFICATE REQUEST-----
MIICkDCCAXgCAQAwSzELMAkGA1UEBhMCQ04xEDAOBgNVBAcMB0JlaWppbmcxEjAQ
BgNVBAoMCVR1cmJvTGluazEWMBQGA1UEAwwNdHVyYm9saW5rLmRldjCCASIwDQYJ
KoZIhvcNAQEBBQADggEPADCCAQoCggEBAKi4w6e14eE1cjGZ2o2E5u91NCNJO1kZ
EdE6sR3sjrFEP8ipPQb+lzcQBLCY+6HyMDAxu1ViOrrswlnUQ9dRyH/37hAzmKiu
OixX/skF3/j+mNCNrdr7zEvxZ7Us85Ls9b3kVnxWtLLBldyL/IxIErwH1dcVOa75
5VC4VXHr8wjDr5nrLuQ0nhKPRCHroGlGrIktkUfk0SW+IH5Qjy2btKy9Pv5gzYbH
dwV7kaf4xIetxeO/3hb91LPY2dA/4c5l55iVc5FW8kcDGCmfAZw7lYXQc09cj42y
9gNEPTiIeiLhpR526PdO2WYIXhscqkqQ6u/eCeZVoR5+SmP35qTD2YsCAwEAAaAA
MA0GCSqGSIb3DQEBCwUAA4IBAQAuyGqqQmOE/ccKoCsvF3b/GuAPWCNcfJZhK7vr
Uje970+xuXqRboFEvHuw7SifKxkoAW2d6+nlwMWsS/cLht+8Z9Sul2p5CA67LVMo
Y0FmWxO8blzeGXDg6In5s3WXNTeIKMGRfIIQwS5TdHrb2cR/y0hnfHkysfyQ4BBy
MvCWDhXMfx37ahCeGPzf0G7Gwv76ZtkGU4cbffv0AFFoaMDUVOhz5MXipDDeFfvy
gYfi0OB+V3RZlAJ9hRev+rTkn+QRKLUmV26YSIJxmBzmu2cv5A/gC2yYSipKQTIG
TdAEwqMhBUVpwjltXHqBd63O85OmQvF67jTMobgJa0HxSxUx
-----END CERTIFICATE REQUEST-----
+27
View File
@@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAqLjDp7Xh4TVyMZnajYTm73U0I0k7WRkR0TqxHeyOsUQ/yKk9
Bv6XNxAEsJj7ofIwMDG7VWI6uuzCWdRD11HIf/fuEDOYqK46LFf+yQXf+P6Y0I2t
2vvMS/FntSzzkuz1veRWfFa0ssGV3Iv8jEgSvAfV1xU5rvnlULhVcevzCMOvmesu
5DSeEo9EIeugaUasiS2RR+TRJb4gflCPLZu0rL0+/mDNhsd3BXuRp/jEh63F47/e
Fv3Us9jZ0D/hzmXnmJVzkVbyRwMYKZ8BnDuVhdBzT1yPjbL2A0Q9OIh6IuGlHnbo
907ZZgheGxyqSpDq794J5lWhHn5KY/fmpMPZiwIDAQABAoIBAG+Cfb1wFjO0ER77
Ilj6B28ntSfFFLZUPVRdSAYQ/FXoV4eVYsImrWY07gSRd22XFYYkuD08SLiWFfUs
txGt+aeqAusuTqzdSZFZLwlJGrgD/JeJq+fZFzLx/6rcZLcsaVXxfb97xr2F+Dfl
RSqpz8f6HbijTJZ6jraEveQnH18gczjFu5Bo5qXd+P8lLDMfegReALCGcj9GXYLR
hDd4f3HUMYLqsEPF4s5ZWZQFN0Nq1iuBTCf1G37Xixrk09PYTt5U70zE1XIAvV7I
OQLCafN9b6Ajpeu5tlwyuaICzFAm8fRQrB/Ux0qKVR/vXgwDhnvPlv2LeLLQqDaS
H4CK4DECgYEA1OVPgHh9hM8nm+pUK8f2E7e/D1/sM8nr/T9v8PDor/yUSjKpgGXP
0Uqw/3azyoGDpyZEEVfta2O4C4z403jq1S3aBbnJqCsDBKii/z2BiNtwMRuExMI/
wTypmQrNmA5g3S6K097r8km8ZKLsagCRChnFmOtG40pJ+7RY1WTk2N8CgYEAyuHa
Gq9x4eoYnntt6/I0nFdxPlwaN1wf46rIOdmpXgPRIfS4gACN4nBtNkFOLWedCv9m
E07p/1pYzOyrAdjp8gxVYi1AOrbEX63SlD4zH9DI8pTAw+Ii0z57luZRoUwZmQyM
UhY90JKTlgVM86jNwXfcWij9bD21H3GDfUZJmNUCgYAn+PopY/YlRoPoWWH+amgA
ocJkz5zYyHPfs9Z/xavaxzDMkaCTtAoGAOEkxhPR1Ol0K9Ih84FnZWy79ncNtalZ
52cFJjH/ujux1zvrco/ss07oWYNfMh2oWYx6aLXbc++p98AnMbbZYhDWUGTVLlAN
NnOMV7iSmnMzqFP5lR0GvwKBgQCfdYBtdPP3cn1DIxQ0XLwJHZk+QDnCxT+zO2oA
PhmmcS2QmL3irYzXKzJLcGy3tzZxjGd4SZAVSbd96Y5G92x4+ESr05EmFLynzwEx
zulz2i/2qgAQdc6VZgjRg9kpA50i8//eDOks4+foA+aFpGmD5Gdm3czBpIaVXizQ
68uwuQKBgQC1GzYqpNyYT6wB5yBMQJ3qUjWumQ2r1uzhyQNgG73QZUZlo9xNJimY
4qulWv8oTT0MLzDeYTKri6kLPBuHxZpwc7wLcQegGthnBqdWCGMzOl8kmcxil0aD
NWBgtCkZMrLmg0I4YviWvCCJPtTLEn2vjINlDAuCX06YnUfoIoVMnA==
-----END RSA PRIVATE KEY-----
+21
View File
@@ -0,0 +1,21 @@
-----BEGIN CERTIFICATE-----
MIIDZTCCAk2gAwIBAgIJAOFO3+DpMNlLMA0GCSqGSIb3DQEBCwUAMEsxCzAJBgNV
BAYTAkNOMRAwDgYDVQQHDAdCZWlqaW5nMRIwEAYDVQQKDAlUdXJib0xpbmsxFjAU
BgNVBAMMDXR1cmJvbGluay5kZXYwHhcNMjIxMjA5MTQwNjI4WhcNMzIxMjA2MTQw
NjI4WjBLMQswCQYDVQQGEwJDTjEQMA4GA1UEBwwHQmVpamluZzESMBAGA1UECgwJ
dHVyYm9saW5rMRYwFAYDVQQDDA10dXJib2xpbmsuZGV2MIIBIjANBgkqhkiG9w0B
AQEFAAOCAQ8AMIIBCgKCAQEAr8vdbsXtLWOEWoygSluR3BtYJcp+1nbDwrytr7WX
XcnzSB1rQ0lt3yQmQ5BKm6CLbUeKtQd7fIUT1JRn3KJ/dSHXT4qEWWO0XJLJeoAI
FXprLWolbrBA8QCAs8Hcbm8F/efHphKU4a10HhD6ENa4YqYPnd89vfYgSPGS/UmF
ojWicWjmmT7Np5PBo81mzpbyhGTlOeZj6LLp77w8772MRBDZTn4eDXDuCdfbs2HM
YFK4OQ2QQjrh2LSCA6VQgi8gGaXtp2k8CwVlXQpOFWmYX0FyXX/4qvkvXl8rG07T
AvX7iCaG3owAYrDeQUL7NqbTvAMHiqivCwrFzThNq+XSkQIDAQABo0wwSjBIBgNV
HREEQTA/gg8qLnR1cmJvbGluay5kZXaCECoudGhlY29kZXdheS5jb22CDyoubGV5
b3V0ZWNoLm5ldIIJbG9jYWxob3N0MA0GCSqGSIb3DQEBCwUAA4IBAQCUlziOgdSF
+GrN2PxrZmRP9bhbLEc1GAWGzStN4xsZFcPIesrDbf74tua65idKvSL4vyx6lpPb
ino6mwIgP8ZUV3jdkgKTUMzeqJJY8hoH5Sza93kOZX0oDFyuEJ7LS9kPrLIqEkdp
Myc690q5GqNLdSWZqONjAp1S3dezQoKRV/YC6PqMr+1Dq/oRIz83NYWan0vpnHFC
gRlK5Rb37ueI+Pe+d6Wg9JSwdo0mFJ5hGfT5Ler4AoA9HMss1k9lJ18iFoSyBCcn
wIg5gcxJe6P7DKXnOknt1Sa0Us/li8ux5J8bVgqImkqx2nagDugcW0BfQYcoFilH
pgulZBZZCO3S
-----END CERTIFICATE-----
+18
View File
@@ -0,0 +1,18 @@
-----BEGIN CERTIFICATE REQUEST-----
MIIC6zCCAdMCAQAwSzELMAkGA1UEBhMCQ04xEDAOBgNVBAcMB0JlaWppbmcxEjAQ
BgNVBAoMCXR1cmJvbGluazEWMBQGA1UEAwwNdHVyYm9saW5rLmRldjCCASIwDQYJ
KoZIhvcNAQEBBQADggEPADCCAQoCggEBAK/L3W7F7S1jhFqMoEpbkdwbWCXKftZ2
w8K8ra+1l13J80gda0NJbd8kJkOQSpugi21HirUHe3yFE9SUZ9yif3Uh10+KhFlj
tFySyXqACBV6ay1qJW6wQPEAgLPB3G5vBf3nx6YSlOGtdB4Q+hDWuGKmD53fPb32
IEjxkv1JhaI1onFo5pk+zaeTwaPNZs6W8oRk5TnmY+iy6e+8PO+9jEQQ2U5+Hg1w
7gnX27NhzGBSuDkNkEI64di0ggOlUIIvIBml7adpPAsFZV0KThVpmF9Bcl1/+Kr5
L15fKxtO0wL1+4gmht6MAGKw3kFC+zam07wDB4qorwsKxc04Tavl0pECAwEAAaBb
MFkGCSqGSIb3DQEJDjFMMEowSAYDVR0RBEEwP4IPKi50dXJib2xpbmsuZGV2ghAq
LnRoZWNvZGV3YXkuY29tgg8qLmxleW91dGVjaC5uZXSCCWxvY2FsaG9zdDANBgkq
hkiG9w0BAQsFAAOCAQEAF4Ed0iL0NO3rHjBDn1Nbo0HGIuUBRsEN8hgdsCybZUue
4fEoyP83Zky8r6caUdnfY6RaBCMRICroRWHK3XxbWnVjzb0Si2erIE9V61cFNzcZ
qB4d2H8jR+I+rrgRLKYMQfJ+6qA7MTSTTG1pD80VlKQdWFacoXIwXo8PfbQzbiA2
OOJRTsw6pQdbo+l0tH4qkT1QIOD9AB54wWrP49sZ6o1ULizhnZTPd/LtwSO7REVj
xBJkAjreNLQwvv36WLDvfIQba8COZQSnuIw8TdZjCKl+kmnGpLJdGUv/GABJcGwO
U8vJG0lJoAIZs0RCX3I6s47pDW3jpdYpHP5DUjQu8Q==
-----END CERTIFICATE REQUEST-----
+27
View File
@@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAr8vdbsXtLWOEWoygSluR3BtYJcp+1nbDwrytr7WXXcnzSB1r
Q0lt3yQmQ5BKm6CLbUeKtQd7fIUT1JRn3KJ/dSHXT4qEWWO0XJLJeoAIFXprLWol
brBA8QCAs8Hcbm8F/efHphKU4a10HhD6ENa4YqYPnd89vfYgSPGS/UmFojWicWjm
mT7Np5PBo81mzpbyhGTlOeZj6LLp77w8772MRBDZTn4eDXDuCdfbs2HMYFK4OQ2Q
Qjrh2LSCA6VQgi8gGaXtp2k8CwVlXQpOFWmYX0FyXX/4qvkvXl8rG07TAvX7iCaG
3owAYrDeQUL7NqbTvAMHiqivCwrFzThNq+XSkQIDAQABAoIBAQCqrwa0+elZi2lD
PYyYBaZuDgKc1qol8rQJTIZatrZbsqvKFf5CG3ZZFFEugldeGRemp7KuJ7Cm6tKh
MOJS31dfU9cofHYaEGtbAo4qqUqwB+ct9gSYHvs+w90yKwSqGJO5vaQjw6DYKUA3
vQX++WuXJGK/RrQ8z07zY9HyqMLeBRcnZVvqRa/neowa3luBfl9bqbfZY4Sac1X/
1HD2+ffE6Y3nnf3OD6PFeHfqBqIZuQebwIOj2myLSL6nyCoWJJQCinlRzOnH4Dkk
Jb6kVwmAGoB/8qD84sKa5XlW+TqiH4HpRoxiGoHj2HeawTv2QAxsVfOV/s4pmjEO
Sg710xGNAoGBANrqb8rFNiicndZX+agxCGhMvYLJqCOUC7cBEd3JOVYELiaopyTb
LdbjTR8lwXK8JyJ+lagbi+sYyIHNc7KF8xnwd5DFpLaT0DwqqENcd83dUeqadnUf
WgzHBcO030CP0JpaJEAtemK6rvq+U4xE+4XuFeXDsCOyCqA+Xw5qF3qbAoGBAM2T
f87euZmqH97kGWaUmgXQWZT3IJzIqo9/UFE5eFIDnNwjaorla9eRSM+WyPStgOhR
Q+zx/cv68vUJg08ESk5IwuEyGAdLiCW3Gsq7sIoaih18wWPor+0MQUSOtbKtnltj
HwwhpXXVUK9rEPnUsrU6Jx1T6fe4BuxTe1xcf/RDAoGAcvia28B1MCEI2BB+IrIV
u0lKYkzsTDstZ+Bc9MEApsctQcpjdfzSd0ALOeeHUG22k+wtRwuokUED1QAE2mZ1
BVOAR/01A1pgC6lPk4kVtn2czvxuaBaeIYXI5j6w3WRqZxYeYcJAu2dWDIQ2tr1n
56/hujjq4eRYpk37eEOJry8CgYBxSQ4OXvhicLi9aG+C8vLpr0YebAzhuUccaqlF
CWl/sJP5T97/iavjECHSm6JEC3TVEStgYH5esPzAAa0FlzSnbTtPQ/6vznTJa9zs
yX9gq31fAIfF2c1Q0QcKk6YXP8vbSoUqd0Qp6hJbiKHDOu38Jn61j6+IHjZadyqs
3CB65wKBgH9PKZ2CZ86qCLwlZ3Uj/hFR9CQCsTuns/lbzjVszw057vny57kf6fma
3+a0oV4pOyEkDip46ObgBaOQDdRt0XuUpUFVNuohmpxdkf0qoqPF6paqhDA5dRvi
F90g0bTXJRO5hKpKMn7L9HAE54aXJWzFem2UgwYAfIuxyhEv6q8j
-----END RSA PRIVATE KEY-----
+32
View File
@@ -0,0 +1,32 @@
@echo off
:: Install golang protoc plugin with follow command first
::
:: go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
:: go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
::
set CURRENT_DIR=%CD%
pushd ..\..\Client\Plugins\TurboLink
set TL_UE_PLUGIN_PATH=%CD%
popd
set PROTOC_EXE_PATH=%TL_UE_PLUGIN_PATH%\ThirdParty\protobuf\bin\protoc.exe
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: generate client code
set CLIENT_OUTPUT_DIR=%CURRENT_DIR%\output\client
if not exist %CLIENT_OUTPUT_DIR% mkdir %CLIENT_OUTPUT_DIR%
call "%TL_UE_PLUGIN_PATH%\Tools\generate_code.cmd" hello.proto Greeter %CLIENT_OUTPUT_DIR%
call "%TL_UE_PLUGIN_PATH%\Tools\generate_code.cmd" user.proto User %CLIENT_OUTPUT_DIR%
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: generate server code
set SERVER_OUTPUT_DIR=%CURRENT_DIR%\output\server
if not exist %SERVER_OUTPUT_DIR% mkdir %SERVER_OUTPUT_DIR%
"%PROTOC_EXE_PATH%" --go_out="%SERVER_OUTPUT_DIR%" --go-grpc_out=%SERVER_OUTPUT_DIR% hello.proto
"%PROTOC_EXE_PATH%" --go_out="%SERVER_OUTPUT_DIR%" --go-grpc_out=%SERVER_OUTPUT_DIR% user.proto
+39
View File
@@ -0,0 +1,39 @@
syntax = "proto3";
package Greeter;
option go_package = "./Greeter";
message HelloRequest {
string name = 1;
}
message HelloResponse {
string reply_message = 1;
}
service GreeterService {
rpc Hello (HelloRequest) returns (HelloResponse);
}
message Nothing {
}
message TicktokRequest {
int32 counts = 1;
}
message WatchRequest {
}
message NowResponse {
uint64 now = 1;
int32 counts=2;
}
service TimeService {
rpc Now (Nothing) returns (NowResponse);
rpc Ticktok (TicktokRequest) returns (stream NowResponse);
rpc Watch (stream WatchRequest) returns (stream NowResponse);
}
+42
View File
@@ -0,0 +1,42 @@
syntax = "proto3";
package User;
option go_package = "./User";
message Address {
string address = 1;
string postal_code = 2;
}
enum GENDER_ENUM {
GE_MALE=0;
GE_FEMALE=1;
}
message RegisterRequest {
string name = 1;
GENDER_ENUM gender = 2;
repeated Address address = 3;
}
message RegisterResponse {
uint64 id = 1;
string msg = 2;
}
message QueryRequest {
uint64 id = 1;
}
message QueryResponse {
string name = 1;
GENDER_ENUM gender = 2;
repeated Address address = 3;
}
service UserService {
rpc Register (RegisterRequest) returns (RegisterResponse);
rpc Query(QueryRequest) returns(QueryResponse);
}
+21
View File
@@ -0,0 +1,21 @@
-----BEGIN CERTIFICATE-----
MIIDaTCCAlGgAwIBAgIJALg9FEgTMGPaMA0GCSqGSIb3DQEBCwUAMEsxCzAJBgNV
BAYTAkNOMRAwDgYDVQQHDAdCZWlqaW5nMRIwEAYDVQQKDAlUdXJib0xpbmsxFjAU
BgNVBAMMDXR1cmJvbGluay5kZXYwHhcNMjIxMTMwMDI1NTE2WhcNMzIxMTI3MDI1
NTE2WjBLMQswCQYDVQQGEwJDTjEQMA4GA1UEBwwHQmVpamluZzESMBAGA1UECgwJ
VHVyYm9MaW5rMRYwFAYDVQQDDA10dXJib2xpbmsuZGV2MIIBIjANBgkqhkiG9w0B
AQEFAAOCAQ8AMIIBCgKCAQEAqLjDp7Xh4TVyMZnajYTm73U0I0k7WRkR0TqxHeyO
sUQ/yKk9Bv6XNxAEsJj7ofIwMDG7VWI6uuzCWdRD11HIf/fuEDOYqK46LFf+yQXf
+P6Y0I2t2vvMS/FntSzzkuz1veRWfFa0ssGV3Iv8jEgSvAfV1xU5rvnlULhVcevz
CMOvmesu5DSeEo9EIeugaUasiS2RR+TRJb4gflCPLZu0rL0+/mDNhsd3BXuRp/jE
h63F47/eFv3Us9jZ0D/hzmXnmJVzkVbyRwMYKZ8BnDuVhdBzT1yPjbL2A0Q9OIh6
IuGlHnbo907ZZgheGxyqSpDq794J5lWhHn5KY/fmpMPZiwIDAQABo1AwTjAdBgNV
HQ4EFgQUeRpYmEkuEnGbhwF66uNSmjVzgRkwHwYDVR0jBBgwFoAUeRpYmEkuEnGb
hwF66uNSmjVzgRkwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAeOuJ
nKz5/Ez1CiwMT4FwZoJPtjJw4ONSzbxMsekb/aubzNYY0T3w693DqZwVFmM573yq
d96ghHBfvVanPMJyHOJFRayZNgrDRKHHW75Jth03cAbQ6MahgVyys0VUrCsAFdAj
Zo2q504vVxBtq2pHzYetNDTF6SVjZp/XrMtgepggEtU6Zf1sDpk0Si694rksrO2p
3C+zkPtgVFd5cT2fihZ5imjUNqu/iRP95mjoKwtPRRGBUhJjN8UOuRyS08L/eUSf
IbN7ogcp6Y+WL6rmNvSVoXBl7wIWhGEWTscyzm66bWisZxGUFTicezL56CpkHdbo
NzR3/aU8S0eIDHSaiQ==
-----END CERTIFICATE-----
+21
View File
@@ -0,0 +1,21 @@
-----BEGIN CERTIFICATE-----
MIIDZTCCAk2gAwIBAgIJAOFO3+DpMNlLMA0GCSqGSIb3DQEBCwUAMEsxCzAJBgNV
BAYTAkNOMRAwDgYDVQQHDAdCZWlqaW5nMRIwEAYDVQQKDAlUdXJib0xpbmsxFjAU
BgNVBAMMDXR1cmJvbGluay5kZXYwHhcNMjIxMjA5MTQwNjI4WhcNMzIxMjA2MTQw
NjI4WjBLMQswCQYDVQQGEwJDTjEQMA4GA1UEBwwHQmVpamluZzESMBAGA1UECgwJ
dHVyYm9saW5rMRYwFAYDVQQDDA10dXJib2xpbmsuZGV2MIIBIjANBgkqhkiG9w0B
AQEFAAOCAQ8AMIIBCgKCAQEAr8vdbsXtLWOEWoygSluR3BtYJcp+1nbDwrytr7WX
XcnzSB1rQ0lt3yQmQ5BKm6CLbUeKtQd7fIUT1JRn3KJ/dSHXT4qEWWO0XJLJeoAI
FXprLWolbrBA8QCAs8Hcbm8F/efHphKU4a10HhD6ENa4YqYPnd89vfYgSPGS/UmF
ojWicWjmmT7Np5PBo81mzpbyhGTlOeZj6LLp77w8772MRBDZTn4eDXDuCdfbs2HM
YFK4OQ2QQjrh2LSCA6VQgi8gGaXtp2k8CwVlXQpOFWmYX0FyXX/4qvkvXl8rG07T
AvX7iCaG3owAYrDeQUL7NqbTvAMHiqivCwrFzThNq+XSkQIDAQABo0wwSjBIBgNV
HREEQTA/gg8qLnR1cmJvbGluay5kZXaCECoudGhlY29kZXdheS5jb22CDyoubGV5
b3V0ZWNoLm5ldIIJbG9jYWxob3N0MA0GCSqGSIb3DQEBCwUAA4IBAQCUlziOgdSF
+GrN2PxrZmRP9bhbLEc1GAWGzStN4xsZFcPIesrDbf74tua65idKvSL4vyx6lpPb
ino6mwIgP8ZUV3jdkgKTUMzeqJJY8hoH5Sza93kOZX0oDFyuEJ7LS9kPrLIqEkdp
Myc690q5GqNLdSWZqONjAp1S3dezQoKRV/YC6PqMr+1Dq/oRIz83NYWan0vpnHFC
gRlK5Rb37ueI+Pe+d6Wg9JSwdo0mFJ5hGfT5Ler4AoA9HMss1k9lJ18iFoSyBCcn
wIg5gcxJe6P7DKXnOknt1Sa0Us/li8ux5J8bVgqImkqx2nagDugcW0BfQYcoFilH
pgulZBZZCO3S
-----END CERTIFICATE-----
+27
View File
@@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAr8vdbsXtLWOEWoygSluR3BtYJcp+1nbDwrytr7WXXcnzSB1r
Q0lt3yQmQ5BKm6CLbUeKtQd7fIUT1JRn3KJ/dSHXT4qEWWO0XJLJeoAIFXprLWol
brBA8QCAs8Hcbm8F/efHphKU4a10HhD6ENa4YqYPnd89vfYgSPGS/UmFojWicWjm
mT7Np5PBo81mzpbyhGTlOeZj6LLp77w8772MRBDZTn4eDXDuCdfbs2HMYFK4OQ2Q
Qjrh2LSCA6VQgi8gGaXtp2k8CwVlXQpOFWmYX0FyXX/4qvkvXl8rG07TAvX7iCaG
3owAYrDeQUL7NqbTvAMHiqivCwrFzThNq+XSkQIDAQABAoIBAQCqrwa0+elZi2lD
PYyYBaZuDgKc1qol8rQJTIZatrZbsqvKFf5CG3ZZFFEugldeGRemp7KuJ7Cm6tKh
MOJS31dfU9cofHYaEGtbAo4qqUqwB+ct9gSYHvs+w90yKwSqGJO5vaQjw6DYKUA3
vQX++WuXJGK/RrQ8z07zY9HyqMLeBRcnZVvqRa/neowa3luBfl9bqbfZY4Sac1X/
1HD2+ffE6Y3nnf3OD6PFeHfqBqIZuQebwIOj2myLSL6nyCoWJJQCinlRzOnH4Dkk
Jb6kVwmAGoB/8qD84sKa5XlW+TqiH4HpRoxiGoHj2HeawTv2QAxsVfOV/s4pmjEO
Sg710xGNAoGBANrqb8rFNiicndZX+agxCGhMvYLJqCOUC7cBEd3JOVYELiaopyTb
LdbjTR8lwXK8JyJ+lagbi+sYyIHNc7KF8xnwd5DFpLaT0DwqqENcd83dUeqadnUf
WgzHBcO030CP0JpaJEAtemK6rvq+U4xE+4XuFeXDsCOyCqA+Xw5qF3qbAoGBAM2T
f87euZmqH97kGWaUmgXQWZT3IJzIqo9/UFE5eFIDnNwjaorla9eRSM+WyPStgOhR
Q+zx/cv68vUJg08ESk5IwuEyGAdLiCW3Gsq7sIoaih18wWPor+0MQUSOtbKtnltj
HwwhpXXVUK9rEPnUsrU6Jx1T6fe4BuxTe1xcf/RDAoGAcvia28B1MCEI2BB+IrIV
u0lKYkzsTDstZ+Bc9MEApsctQcpjdfzSd0ALOeeHUG22k+wtRwuokUED1QAE2mZ1
BVOAR/01A1pgC6lPk4kVtn2czvxuaBaeIYXI5j6w3WRqZxYeYcJAu2dWDIQ2tr1n
56/hujjq4eRYpk37eEOJry8CgYBxSQ4OXvhicLi9aG+C8vLpr0YebAzhuUccaqlF
CWl/sJP5T97/iavjECHSm6JEC3TVEStgYH5esPzAAa0FlzSnbTtPQ/6vznTJa9zs
yX9gq31fAIfF2c1Q0QcKk6YXP8vbSoUqd0Qp6hJbiKHDOu38Jn61j6+IHjZadyqs
3CB65wKBgH9PKZ2CZ86qCLwlZ3Uj/hFR9CQCsTuns/lbzjVszw057vny57kf6fma
3+a0oV4pOyEkDip46ObgBaOQDdRt0XuUpUFVNuohmpxdkf0qoqPF6paqhDA5dRvi
F90g0bTXJRO5hKpKMn7L9HAE54aXJWzFem2UgwYAfIuxyhEv6q8j
-----END RSA PRIVATE KEY-----
+16
View File
@@ -0,0 +1,16 @@
module tldemo
go 1.19
require (
google.golang.org/grpc v1.50.1
google.golang.org/protobuf v1.28.1
)
require (
github.com/golang/protobuf v1.5.2 // indirect
golang.org/x/net v0.0.0-20201021035429-f5854403a974 // indirect
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4 // indirect
golang.org/x/text v0.3.3 // indirect
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 // indirect
)
+83
View File
@@ -0,0 +1,83 @@
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20201021035429-f5854403a974 h1:IX6qOQeG5uLjB/hjjwjedwfjND0hgjPMMyO1RoIXQNI=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4 h1:myAQVi0cGEoqQVR5POX+8RR2mrocKqNN1hmeMqhX27k=
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY=
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.50.1 h1:DS/BukOZWp8s6p4Dt/tOaJaTQyPyOoCcrjroHuCeLzY=
google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w=
google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+59
View File
@@ -0,0 +1,59 @@
package main
import (
"fmt"
"flag"
"log"
"net"
"os"
"google.golang.org/grpc"
"google.golang.org/grpc/reflection"
"google.golang.org/grpc/credentials"
"tldemo/services"
)
var (
port = flag.Int("port", 50051, "The server port")
crt_file = "certs/server.crt"
key_file = "certs/server.key"
)
func main() {
fmt.Println("==== TurboLink Test Server =====")
logFileName := "./log/services.log"
logFile, err := os.OpenFile(logFileName, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0766)
if err != nil {
log.Fatalf("could not load TLS keys: %s", err)
return
}
log.SetOutput(logFile)
log.SetFlags(log.LstdFlags | log.Lshortfile | log.Ltime)
flag.Parse()
lis, err := net.Listen("tcp",":5050")
if err != nil {
log.Fatalf("failed to listen: %v", err)
}
// server-side tls
// Create the TLS credentials
creds, err := credentials.NewServerTLSFromFile(crt_file, key_file)
if err != nil {
log.Fatalf("could not load TLS keys: %s", err)
}
s := grpc.NewServer(grpc.Creds(creds))
//register all server
services.RegisterGreeterServer(s)
services.RegisterUserServer(s)
reflection.Register(s)
log.Printf("server listening at %v", lis.Addr())
if err := s.Serve(lis); err != nil {
log.Fatalf("failed to serve: %v", err)
}
}
+109
View File
@@ -0,0 +1,109 @@
package services
import (
"fmt"
"context"
"log"
"time"
"google.golang.org/grpc"
pb "tldemo/services/Greeter"
)
type GreeterServer struct {
pb.UnimplementedGreeterServiceServer
}
func (s *GreeterServer) Hello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloResponse, error) {
currentTime := time.Now()
replyMessage := fmt.Sprintf("Hello %s, time is %s", in.Name, currentTime.Format("15:04:05"))
log.Printf("[Hello User] %s", in.Name)
result := &pb.HelloResponse{ReplyMessage: replyMessage}
return result, nil
}
type TimeServer struct {
pb.UnimplementedTimeServiceServer
}
func (s *TimeServer) Now(ctx context.Context, in *pb.Nothing) (*pb.NowResponse, error) {
currentTime := uint64(time.Now().UTC().UnixMilli())
log.Printf("[Now]send time: %d", currentTime)
result := &pb.NowResponse{Now: currentTime}
return result, nil
}
func (s *TimeServer) Ticktok(in *pb.TicktokRequest, stream pb.TimeService_TicktokServer) error {
ctx := stream.Context()
response := &pb.NowResponse{}
sendNow := func(counts int32) {
response.Now = uint64(time.Now().UTC().UnixMilli())
response.Counts = counts
log.Printf("[Ticktok]send time %d/%d", response.Now, counts)
if err := stream.Send(response); err != nil {
return
}
}
counts := int32(in.Counts)
if(counts < 0) {
counts=0
}
for {
sendNow(counts)
if(in.Counts>0) {
counts-=1
if(counts <= 0) {
return nil
}
}
select {
case <-ctx.Done():
return nil
default:
time.Sleep(1.0 * time.Second)
}
}
return nil
}
func (s *TimeServer) Watch(stream pb.TimeService_WatchServer) error {
ctx := stream.Context()
response := &pb.NowResponse{}
sendNow := func() error {
response.Now = uint64(time.Now().UTC().UnixMilli())
log.Printf("[Watch]send time %d", response.Now)
return stream.Send(response)
}
for {
select {
case <-ctx.Done():
return nil
default:
}
if _, err := stream.Recv(); err != nil {
return err
} else if err := sendNow(); err != nil {
return err
}
}
}
func RegisterGreeterServer(s *grpc.Server) {
greeterServer := &GreeterServer{}
pb.RegisterGreeterServiceServer(s, greeterServer)
timeServer := &TimeServer{}
pb.RegisterTimeServiceServer(s, timeServer)
}
+74
View File
@@ -0,0 +1,74 @@
package services
import (
"fmt"
"context"
"log"
"errors"
"google.golang.org/grpc"
pb "tldemo/services/User"
)
type UserAddress struct {
Address string
PostalCode string
}
type UserData struct {
Id int
Name string
Gender pb.GENDER_ENUM
Addresses [] *UserAddress
}
type UserServer struct {
pb.UnimplementedUserServiceServer
UserArray []*UserData
}
func (s *UserServer) Register(ctx context.Context, in *pb.RegisterRequest) (*pb.RegisterResponse, error) {
userData := &UserData{Id:len(s.UserArray), Name:in.Name, Gender:in.Gender}
userData.Addresses = make([]*UserAddress, 0)
for i:=0; i<len(in.Address); i++ {
userData.Addresses = append(userData.Addresses, &UserAddress{Address : in.Address[i].Address, PostalCode: in.Address[i].PostalCode})
}
s.UserArray = append(s.UserArray, userData)
replyMessage := fmt.Sprintf("Hello %s, Your Id is %v", userData.Name, userData.Id)
log.Printf("[Register User] %s", replyMessage)
result := &pb.RegisterResponse{Id: uint64(userData.Id), Msg: replyMessage}
return result, nil
}
func (s *UserServer) Query(ctx context.Context, in *pb.QueryRequest) (*pb.QueryResponse, error) {
log.Printf("[Query User] %d", in.Id)
if(in.Id<0 || int(in.Id)>=len(s.UserArray)) {
return nil, errors.New("Out of range!")
}
var userData = s.UserArray[int(in.Id)]
address := make([]*pb.Address, 0)
for i:=0; i<len(userData.Addresses); i++ {
address = append(address, &pb.Address{ Address: userData.Addresses[i].Address, PostalCode: userData.Addresses[i].PostalCode})
}
//address[0] = &pb.Address{ Address: "xxxx", PostalCode: "1234"}
result := &pb.QueryResponse{
Name: userData.Name,
Gender: userData.Gender,
Address : address,
}
return result, nil
}
func RegisterUserServer(s *grpc.Server) {
userServer := &UserServer{}
userServer.UserArray = make([]*UserData, 0)
pb.RegisterUserServiceServer(s, userServer)
}