Listen and handle different AGS events
Overview
This guide provides information on how to modify the Extend Event Handler app template to listen and handle different events from AccelByte Gaming Services (AGS).
Prerequisites
Clone an Extend Event Handler app template.
- Go
- C#
- Java
- Python
git clone https://github.com/AccelByte/extend-event-handler-go.git
git clone https://github.com/AccelByte/extend-event-handler-csharp.git
git clone https://github.com/AccelByte/extend-event-handler-java.git
git clone https://github.com/AccelByte/extend-event-handler-python.git
Identify and download specific event descriptors
Here is how you can get the protobuf event descriptor for the AGS event you are looking for.
Identify your AGS event: Go to the API Events page and find the AGS event you are looking for.
Locate the Protobuf event descriptor: After finding the AGS event, get the URL to the protobuf (*.proto) file on the same page.
Download the protobuf event descriptor: As an example for this guide, we need the userLoggedIn event. Therefore, we need to download the IAM directory which contains the userLoggedIn event.
Generate stub from event descriptor
- Go
- C#
- Java
- Python
Put the iam
directory you have downloaded in pkg/proto/accelbyte-asyncapi
directory in your Extend Event Handler project.
...
|__ main.go
|__ pkg
...
├── proto
│ └── accelbyte-asyncapi
│ └── iam # Directory structure containing protobuf files
├── pb
...
...
Next, in the top-level directory of your Extend Event Handler project, run the following command.
make proto
You will see your stub generated at pkg/pb/accelbyte-asyncapi
.
...
|__ main.go
|__ pkg
...
├── proto
│ └── accelbyte-asyncapi
│ └── iam # Directory containing protobuf files
├── pb
│ └── accelbyte-asyncapi
│ └── iam # Directory containing "stub" generated code
...
...
Put the iam
directory you have downloaded in src/AccelByte.PluginArch.EventHandler.Demo.Server/Protos
directory in your Extend Event Handler project.
Then, you need to include the specific protobuf file to be generated by .NET gRPC Tool. Modify src/AccelByte.PluginArch.EventHandler.Demo.Server/AccelByte.PluginArch.EventHandler.Demo.Server.csproj
file and add or update the following section.
<ItemGroup>
<Protobuf Include="Protos\iam\account\v1\account.proto" GrpcServices="Server" />
</ItemGroup>
You can include more than one protobuf
file. Just add more <Protobuf>
lines inside <ItemGroup>
.
Next, use the following command to generate code from the included protobuf files.
dotnet build
Put the iam
directory you have downloaded in src/main/proto/accelbyte-asyncapi
directory in your Extend Event Handler project.
...
├── src
│ ├── main
│ │ ├── proto
│ │ │ └── accelbyte-asyncapi
| | │ └── iam # Directory containing protobuf files
...
Next, use the following command to generate code from the included protobuf files.
make build
Put the iam
directory structure you have downloaded in src/app/proto
directory in your Extend Event Handler project.
...
├── src
│ ├── app
│ │ ├── proto
Next, use the following command to generate code from the included protobuf files.
make build
Creating your callback implementation
- Go
- C#
- Java
- Python
Create a New Go File: Go to directory
pkg/service
and create a new Go file. For exampleloginHandler.go
.Embed the Generated Stub: In the new Go file, define a struct type that embeds the stub type. For example, if your event is
userLoggedIn
you will seeUnimplementedUserAuthenticationUserLoggedInServiceServer
stub and your struct declaration might look something like the following.import pb "extend-event-handler/pkg/pb/accelbyte-asyncapi/iam/account/v1"
type LoginHandler struct {
pb.UnimplementedUserAuthenticationUserLoggedInServiceServer
// your fields here
}Define
OnMessage
Methods: Define a method on your new struct namedOnMessage
. This method should have the same signature as theOnMessage
method in the stub, but with your own implementation. This is the method that will be invoked when the AGS event is received.import pb "extend-event-handler/pkg/pb/accelbyte-asyncapi/iam/account/v1"
func (o *LoginHandler) OnMessage(ctxt context.Context, msg *pb.UserLoggedIn) (*emptypb.Empty, error) {
// your event handling code here
return &emptypb.Empty{}, nil
}
Create a New C# File: Go to directory
src/AccelByte.PluginArch.EventHandler.Demo.Server/Services
and create a new C# file. For exampleUserLoggedInService.cs
.Embed the Generated Stub: In the new C# file, create a new class which inherits
UserAuthenticationUserLoggedInService.UserAuthenticationUserLoggedInServiceBase
. For example,UserLoggedInService
.namespace AccelByte.PluginArch.EventHandler.Demo.Server.Services
{
public class UserLoggedInService : UserAuthenticationUserLoggedInService.UserAuthenticationUserLoggedInServiceBase
{
...
}
}Define
OnMessage
Methods: Override theOnMessage
method and implement the logic which will be executed when the AGS event is received.public override Task<Empty> OnMessage(UserLoggedIn request, ServerCallContext context)
{
...
}
Create a New Java File: Go to directory
src/main/java/net/accelbyte/service
and create a new Java file. For exampleLoginHandler.java
.Embed the Generated Stub: In the new Java file, create a new class which inherits
UserAuthenticationUserLoggedInServiceGrpc.UserAuthenticationUserLoggedInServiceImplBase
. For example,LoginHandler
.public class LoginHandler extends UserAuthenticationUserLoggedInServiceGrpc.UserAuthenticationUserLoggedInServiceImplBase {
...
}Define
OnMessage
Methods: Override theonMessage
method and implement the logic which will be executed when the AGS event is received.
@Override
public void onMessage(UserLoggedIn request, StreamObserver<Empty> responseObserver) {
...
}
Create a New Python File: Go to directory
src/app/services
and create a new Python file. For examplelogin_handler.py
.Embed the Generated Stub: In the new Python file, create a new class which inherits
UserAuthenticationUserLoggedInServiceServicer
. For example,AsyncLoginHandlerService
.from app.proto.account_pb2_grpc import UserAuthenticationUserLoggedInServiceServicer
class AsyncLoginHandlerService(UserAuthenticationUserLoggedInServiceServicer):
...Define
OnMessage
Methods: Override theOnMessage
method and implement the logic which will be executed when the AGS event is received.async def OnMessage(self, request: UserLoggedIn, context):
...
Registering the event handler struct into the service
- Go
- C#
- Java
- Python
Go to main.go
in the Event Handler project and register the gRPC service we have created as follows.
import "extend-event-handler/pkg/service"
// gRPC server that you already initialized in the service
s := grpc.NewServer(...)
// Register IAM Handler
loginHandler := service.LoginHandler{} // or service.NewLoginHandler() if you created the constructor method
pb.RegisterUserAuthenticationUserLoggedInServiceServer(s, loginHandler)
Go to src/AccelByte.PluginArch.EventHandler.Demo.Server/Program.cs
in the Event Handler project and register the gRPC service we have created as follows.
app.MapGrpcService<UserLoggedInService>();
Go to src/main/java/net/accelbyte/serviceLoginHandler.java
in the Event Handler project and register the gRPC service we have created by adding @GRpcService
annotation.
@GRpcService
public class LoginHandler extends UserAuthenticationUserLoggedInServiceGrpc.UserAuthenticationUserLoggedInServiceImplBase {
...
Go to src/app/__main__.py
in the Event Handler project and register the gRPC service we have created as follows.
opts.append(
AppGRPCServiceOpt(
AsyncLoginHandlerService(
logger=logger,
namespace=namespace
),
AsyncLoginHandlerService.full_name,
add_UserAuthenticationUserLoggedInServiceServicer_to_server,
)
)