alkee-allm / k2proto Goto Github PK
View Code? Open in Web Editor NEWgrpc service sample
grpc service sample
game server(UE4 dedicated server)에서도 gRPC backend 가 필요(#25 및 client 로 event 전달에 사용)하기 때문에, 이를 위한 서비스가 추가되어야 할 것.
updatebackend
를 받아 SessionManager 의 정보 업데이트ServiceConfiguration(#3)이 구성되었지만, 이는 StartUp.Configure 함수실행 이후에만 사용 가능하다.
따라서, 이전에 설정되어야 하는 listeningUrl 정보는 사용할 수 없다. 예)
.ConfigureWebHostDefaults(webBuilder =>
{
var urls = new List<string>();
urls.Add(config.BackendListeningAddress);
urls.Add(config.FrontendListeningAddress);
// config 의 값은 기본생성자 값이다. appsettings 에서 설정되기 전 상태.
webBuilder
.UseKestrel()
.UseUrls(urls.ToArray()) // 따라서 appsetting 에 따라 이 값이 설정되지 않는다.
.UseStartup<Startup>();
});
현재는 commandline argument 로 server management service 에 연결될 주소(serverManagementBackendAddress
)를 입력받아 사용중.
Lines 26 to 30 in b35b11d
실제 서비스 상태에서는 이 값이 거의 고정되어 사용될 예정이고, container 추가에 따른 설정(ip, port, server id)들이 가장 빈번하게 바뀔 것. network 내에서 유일한 서비스들(unique backend service)의 경우 거의 고정된 설정을 유지할 것으로 보이며, game server 등의 frontend service 의 scale out 시에 변경될 설정들을 가장 간편하게 설정할 수 있어야 할 것.
working label을 이용해 해당 issue 가 진행중임을 표시하고, issue 가 close 될 때 workflow events를 통해 자동으로 이 label 이 제거되도록.
참고 : Github Action 사용법 정리
많은 파일들이 cp494 encoding으로 저장되어있어 utf-8 로의 변환이 필요하다.
c++ 의 경우 compiler 옵션까지 바꿔줘야하고 windows visual studio 가 c++ project 의 경우 새 파일 template 들이 ANSI 로 되어있으므로 번거로울 수 있겠지만,
적어도 c# project(K2svc
)내 파일들은 모두 UTF-8 로 바꿔야 할 것.
단일 파일 배포를 사용해 k2svc.exe
를 실행(publish
directory)했을 때,
./K2svc.exe
Unhandled exception. System.IO.FileNotFoundException: The configuration file 'appsettings.json' was not found and is not optional. The physical path is 'C:\Users\non-setting\AppData\Local\Temp\.net\K2svc\we50w3bn.4hb\appsettings.json'.
at Microsoft.Extensions.Configuration.FileConfigurationProvider.HandleException(ExceptionDispatchInfo info)
at Microsoft.Extensions.Configuration.FileConfigurationProvider.Load(Boolean reload)
at Microsoft.Extensions.Configuration.FileConfigurationProvider.Load()
at Microsoft.Extensions.Configuration.ConfigurationRoot..ctor(IList`1 providers)
at Microsoft.Extensions.Configuration.ConfigurationBuilder.Build()
at K2svc.Program.LoadConfig(String[] args)
at K2svc.Program.Main(String[] args)
와 같은 exception(crash) 발생
참고
서버쪽(K2svc
) 작업(#30)은 되어있지만, client project (K2client
, K2Unity
)에서도 재사용하는 방식으로 수정할 것
issue #2 완료후 테스트가 미진하여 아래와 같은 크래시(exception) 발생
예외 발생: 'System.ArgumentOutOfRangeException'(Microsoft.IdentityModel.Tokens.dll)
'System.ArgumentOutOfRangeException' 형식의 예외가 Microsoft.IdentityModel.Tokens.dll에서 발생했지만 사용자 코드에서 처리되지 않았습니다.
IDX10603: Decryption failed. Keys tried: '[PII is hidden. For more details, see https://aka.ms/IdentityModel/PII.]'.
Exceptions caught:
'[PII is hidden. For more details, see https://aka.ms/IdentityModel/PII.]'.
token: '[PII is hidden. For more details, see https://aka.ms/IdentityModel/PII.]'
> K2svc.dll!K2svc.Frontend.InitService.GenerateJwtToken(string id) 줄 69 C#
K2svc.dll!K2svc.Frontend.InitService.Login(K2.LoginRequest request,
Grpc.Core.ServerCallContext context) 줄 39 C#
EF Core 사용해, sample 에서는 local sqlite database 이용하는 것이 별도의 dependency 없이 sample 작성이 가능할 것.
현재까지는 google 문서에서 정리하고 별도의 processor 로 진행하게 될 확률이 높지만, 프로젝트 완성도 면에서는 uniprocessor(unreal client)로 진행하는 것이 좋기 때문에, 교려사항들을 최대한 확인하고 빠른 최종 결정이 필요.
github action을 이용해, 해당 issue 에 대한 pull request 가 만들어지면 자동으로 PR
or Pull requested
label 이 해당 issue 에 붙고, pull request 가 종료(merged or declined)되면 자동으로 이 label 이 제거되도록 구성.
참고
k2 의 game session 이 unreal dedicated server(이하 game server) 로 실행되는 환경임을 감안할 때,
lobby 에서 party/team 이 결정되고 in-game 에 진입할때 process 를 실행하거나, 이미 실행되고 비어있는 game server 를 찾아 접속정보를 알려 주어야 한다. 또한, 필요한 경우 사용되지 않는 game server 를 shutdown 할 수 있어야 한다.
일정시간동안 ping 이 없는 서버들의 경우 장애처리.
상황에 대한 함수를 별도로 만들어 추후에 정책적인 부분이 변경되더라도 해당 함수를 수정하는 것으로 반영되도록.
unique backend service 의 경우 별도 issue(#38) 에서 진행.
README 파일들이 현재 동작에 모두 맞는지 확인하고, 필요한 경우 수정.
C++ K2Client sample 참고해, unreal project(UE4)에서 gRPC client 적용이 필요.
.gitignore
알맞게 추가 또는 수정client sample 이 c++ 코드로 되어있으나, K2 lobby 가 분리되어 C#(unity?)으로 개발될 수 있기 때문에, 이를 위한 sample 작업이 필요.
Line 9 in 412c55e
server 의 main 함수에서 argument 를 통해 ServerManagement backend 를 호출해 이후 설정들(server id
, user session service backend address
, push backend address
, frontend listening port
등)을 받아와 설정하고 서비스가 시작되도록 해야 한다.
backend(서버들의 서버) server 가 장애가 발생한 경우, 그리고 다시 재 연결이 된 경우에 알맞은 동작(서비스 계속 진행)을 수행해야한다.
#37 작업진행이 선행 되어야 할 것.
관리자 웹 페이지 등을 통해 현재 연결되어있는 서버들의 상태를 조회하고, 명령할 수 있는 기능 추가
프로젝트 교육 목적의 메뉴얼 작성.
구조적인 설명, 실행 순서 설명 및 각 이벤트 발생상황에 대한 설명이 필요할 것.
또한, 가상 작업 시나리오(study-case)를 정해 작업하는 방식을 기술해 보는 것도 좋을 듯.
대량 연결-서비스 테스트를 위한 자동화 가능한 test client framework 준비.
client protobuf 파일의 경우 pre-build-event에 의해 project 에 포함되는 .cc
및 .h
파일이 생성된다.
따라서, 이 파일들은 version 관리 되지 않아야 한다.
k2proto/K2svc/Backend/ServerManagerBackend.cs
Lines 184 to 195 in 274705c
현재 broadcast 시에, 연결된 모든 server 에 PushRequest
를 전달하고있는데, 대상은 PushService
frontend 를 제공하고 있는 서버들에 한정되어야 한다. 다만, PushService 와 관련없는 서버 관리 목적의 경우 전체 서버에 메시지를 전달하는 방식은 유지 필요.
jwt 의 validation lifetime 기능을 활성화하고 이 시점이 되기 전에 재인증(jwt 갱신)받을 수 있는 기능을 추가
Lines 41 to 53 in 0aeb1da
Frontend server를 먼저 띄우고 ServerManager 를 띄우는 상황에 가끔씩 발생.
Console log:
warn: K2svc.Background.ServerManagementBackground[0]
ERROR on ping : Service is unimplemented.
info: Microsoft.AspNetCore.Hosting.Diagnostics[1]
Request starting HTTP/2 POST http://[::1]:9060/K2B.ServerHost/Stop application/grpc
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[0]
Executing endpoint 'gRPC - /K2B.ServerHost/Stop'
Debug output:
예외 발생: 'System.ApplicationException'(K2svc.dll)
'System.ApplicationException' 형식의 예외가 K2svc.dll에서 발생했지만 사용자 코드에서 처리되지 않았습니다.
invalid backend request of /K2B.ServerHost/Stop from ipv6:[::1]:65282
Call stack:
> K2svc.dll!K2svc.Filter.BackendValidator.UnaryServerHandler<K2B.StopRequest, K2B.Null>(K2B.StopRequest request, Grpc.Core.ServerCallContext context, Grpc.Core.UnaryServerMethod<K2B.StopRequest, K2B.Null> continuation) 줄 31 C#
[외부 코드]
K2svc.dll!K2svc.Startup.Configure.AnonymousMethod__0(Microsoft.AspNetCore.Http.HttpContext context, System.Func<System.Threading.Tasks.Task> next) 줄 79 C#
[외부 코드]
Detail:
$exception
| 이름 | 값 | 형식
-- | -- | -- | --
◢ | $exception | {"invalid backend request of /K2B.ServerHost/Stop from ipv6:[::1]:65282"} | System.ApplicationException
| ▶ Data | {System.Collections.ListDictionaryInternal} | System.Collections.IDictionary {System.Collections.ListDictionaryInternal}
| HResult | -2146232832 | int
| HelpLink | null | string
| ▶ InnerException | null | System.Exception
| Message | "invalid backend request of /K2B.ServerHost/Stop from ipv6:[::1]:65282" | string
| Source | "K2svc" | string
| StackTrace | " at K2svc.Filter.BackendValidator.UnaryServerHandler[TRequest,TResponse](TRequest request, ServerCallContext context, UnaryServerMethod`2 continuation) in C:\\work\\local\\K2\\K2svc\\Filter\\BackendValidator.cs:line 32\r\n at Grpc.Shared.Server.InterceptorPipelineBuilder`2.<>c__DisplayClass5_0.<<UnaryPipeline>b__1>d.MoveNext()" | string
| ▶ TargetSite | {System.Threading.Tasks.Task`1[TResponse] UnaryServerHandler[TRequest,TResponse](TRequest, Grpc.Core.ServerCallContext, Grpc.Core.UnaryServerMethod`2[TRequest,TResponse])} | System.Reflection.MethodBase {System.Reflection.RuntimeMethodInfo}
| ▶ Static members | |
| ▶ Non-Public members | |
ServerManagementBackground에서 Ping 이나 Register 할 때, timer 가 block 되는 방식으로 구현이되어있다보니, 이 timer 에서 await 응답을 늦게 받거나 멈추어버리면(debugging break point 등) 이 timer 가 멈추어 다른 연결된 요청도 함께 늦어지게되는 문제가 있다.
ServerManagementBackground 의 refactoring 이 필요해 보인다. ( OnTime 함수 이하 )
k2proto/K2svc/Background/ServerManagementBackground.cs
Lines 63 to 76 in e38c0cc
현재 구조에서는 별도의 server management backend 를 통해 서버의 configuration 을 가져와서 시작하게 되어있음.
테스트를 위해 하나의 instance 로 서버를 실행할 때 구조적인 제약(server management backend 필요)으로 서비스를 시작할 수 없다.
현재 테스트를 위해
Lines 31 to 34 in 0aeb1da
또한, 이 서버가 server management backend 로 사용되는지에 대한 설정도 필요하다.
push service 에 연결이 끊어진 상태에서 grpc 호출(request) 했을 때, 이를 거부할 수 있어야 한다.(보안)
jwt 에 포함되어있는 pushserivce 로 해당 user 가 접속해 있는지를 확인하는 과정을 거쳐 request 가 실행되도록 하면, 매 요청마다 추가적인 request(backend)가 발생하겠지만, 중앙 집중적(UserSessionBackend)이 되지는 않을 것.
현재 개발 편의를 위해 client 는 모두 동기 방식의 interface 만을 사용하고 있다.
이를 실제 사용을 위해 비동기 방식으로 전환해야할 것.
생성-삭제 overhead 가 있고, channel 과 stub 는 thread-safe 하므로 재사용이 가능. 가능하다면 재사용할 수 있도록
protobuf 와 grpc 의 소스코드에 TODO 및 Hack comment 가 너무 많아 Visual stduio 작업목록을 이용해 관리하기가 어렵다. 코드 내 TODO 를 issue 로 옮겨 tracking 하는것이 나을 것 같다. (file 에 filter 를 적용하면 그나마 보기 쉬워지긴 한다.)
현재 서버의 리소스 사용량이 너무 심각해 이를 상당히 줄여야 할 것.
Report | Graph |
---|---|
자세한 데이터 확인 방법 : SamplePerfmon.zip 파일을 다운로드해 .blg
파일을 열고 설정로드를 통해 sample.PerfmonCfg
파일을 로드.
현재 개발 편의를 위해 plain text http 를 이용하고 있으나, 보안 및 gRPC 의 원활한 사용(#15 Header 포함된 channel 사용 등)을 위해 https 로 프로토콜을 변경해야한다.
5b5b061 ssl 적용 sample 참고
Cannot Compose Insecure Credentials 참고
서비스의 동적인 확장(scale-out)과 모니터링을 위해 dockerize(linux host)가 가능해야할 것.
따라서 dedicated server 를 linux build 되는것을 확인하고, dockerize 해 실행이 가능하도록 구성
gRPC 나 다른 plugin 역시 올바르게 빌드-동작하는지 확인도 필요.
현재, 간단한 구성(#15)을 위해 BackendListeningAddress
(private IP + port) 와 FrontendListeningAddress
(public IP + port)를 설정(환경변수 또는 appsettings.json
)으로부터 입력받고 있음.
k2proto/K2svc/ServiceConfiguration.cs
Lines 15 to 16 in b35b11d
host 에서 docker run
실행 전 script 등을 통해 ip 및 port 정보를 얻어와 실행해줄 수 있을 것이라 생각했지만, AWS ECS를 사용하는 경우 이와같은 동작이 불가능(정적인 설정만 가능)하다는 @indralight 의견.
UE4 dedicated server 의 경우 1개의 dedicated server process 로는 1개의 game session(room) 만을 처리할 수 있는 듯 하기 때문에, 하나의 port 를 고정해서 사용하는 것(하나의 host 에 하나의 instance 만 사용 가능)은 상당히 비효율적일 수 있다.
ECS 사용하는 경우 실행 전에 instance 의 ip 를 알아올 수 없기 때문에 환경변수로도 설정할 수 없고, 오직 port 지정만 가능. 따라서, container 내에서 동적으로 ip 를 얻어오는 장치는 필요하다.
diagram에서는
와 같이 PushService에 요청을 하고 있지만, mermaid 툴의 한계로 인한 것. 실제로는 push 의 singleton(호출하는 위치는 해당 backend)을 이용하는 것.
이를 좀 더 잘 나타낼 수 있으면 좋겠다.
backend 장애처리(#38)작업을 위해 일부 instance 를 분리해 실행(각 서비스별로 process 를 별도로 실행)해보았을 때 다양한 문제가 발생했음.
따라서, 분리된 instance 에서 테스트할 수 있는 환경을 구성하고, 발생하는 문제를 수정해야할 것.
현재 사용하고있는 SymmetricSecurityKey 가 서버가 하나의 instance 일때에만 올바르게 동작하도록 되어있다.
k2proto/K2svc/Frontend/InitService.cs
Line 15 in 412c55e
이를 모든 서버(instances)가 공유하고 동시에 업데이트 할 수 있는 방법이 필요하다.
k2proto/K2svc/Backend/ServerManagementService.cs
Lines 27 to 37 in 8185bce
현재 임시코드 부분을 실제 동작하도록 서버-관리 기능을 추가한다
RequestStream.WriteAsync
함수가 thread-safe 하지 않기 때문에, backend 로부터 전달받은 push request 가 thread-safe 하지 않을 수 있다.
따라서, 이를 확인하고 수정이 필요하다.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.