All Projects → Octops → agones-event-broadcaster

Octops / agones-event-broadcaster

Licence: Apache-2.0 license
Broadcast Agones GameServers and Fleets states to the external world

Programming Languages

go
31211 projects - #10 most used programming language
Makefile
30231 projects
shell
77523 projects
Dockerfile
14818 projects

Projects that are alternatives of or similar to agones-event-broadcaster

Swissarmylib
Collection of helpful utilities we use in our Unity projects.
Stars: ✭ 154 (+600%)
Mutual labels:  gamedev, events
awesome-playdate
A list of awesome resources for Playdate (https://play.date) game development and the Playdate SDK (https://play.date/dev/)
Stars: ✭ 149 (+577.27%)
Mutual labels:  gamedev
hierarchical-pathfinding
Implementation of Near-Optimal Hierarchical Pathfinding (HPA*) algorithm in Unity, tested with maps from Dragon Age: Origins
Stars: ✭ 90 (+309.09%)
Mutual labels:  gamedev
moon-cheeser
Moon Cheeser is an infinite runner where the player plays as a mouse gathering cheese pieces and avoiding craters and other astronomical objects, such as comets and planets, on a moon made of cheese.
Stars: ✭ 32 (+45.45%)
Mutual labels:  gamedev
Codebot
Free and open source (MIT license) web-based IDE focused on game development.
Stars: ✭ 86 (+290.91%)
Mutual labels:  gamedev
ggrs
GGRS is a reimagination of GGPO, enabling P2P rollback networking in Rust. Rollback to the future!
Stars: ✭ 209 (+850%)
Mutual labels:  gamedev
ngx-event-modifiers
Event Modifiers for Angular Applications https://netbasal.com/implementing-event-modifiers-in-angular-87e1a07969ce
Stars: ✭ 14 (-36.36%)
Mutual labels:  events
dom-locky
🙈🙉🙊 - the best way to scope a scroll, or literally any other event.
Stars: ✭ 18 (-18.18%)
Mutual labels:  events
godot-shotgun-party
An evolving multiplayer project for Godot Engine 3.
Stars: ✭ 171 (+677.27%)
Mutual labels:  gamedev
cog
Macro powered ECS Framework written in Haxe
Stars: ✭ 29 (+31.82%)
Mutual labels:  gamedev
PSEventViewer
PSEventViewer (Get-Events) is really useful PowerShell wrapper around Get-WinEvent. One of the features you may be interested in is a simple way of getting “hidden” events data
Stars: ✭ 74 (+236.36%)
Mutual labels:  events
watermill-amqp
AMQP Pub/Sub for the Watermill project.
Stars: ✭ 27 (+22.73%)
Mutual labels:  events
susse
super ültra sweet sprite editor
Stars: ✭ 22 (+0%)
Mutual labels:  gamedev
bevy verlet
Verlet physics plugin for bevy.
Stars: ✭ 29 (+31.82%)
Mutual labels:  gamedev
MedievalWar
A simple turn-based strategy game using Phaser 3
Stars: ✭ 22 (+0%)
Mutual labels:  gamedev
build
Build system scripts based on GENie (https://github.com/bkaradzic/genie) project generator
Stars: ✭ 30 (+36.36%)
Mutual labels:  gamedev
VLCTechHub-site
VLCTechHub site
Stars: ✭ 23 (+4.55%)
Mutual labels:  events
SEPA
Get notifications about changes in your SPARQL endpoint.
Stars: ✭ 21 (-4.55%)
Mutual labels:  events
deffx
A collection of useful shader effects made ready to be used with the Defold game engine
Stars: ✭ 33 (+50%)
Mutual labels:  gamedev
UnityHFSM
A simple yet powerful class based hierarchical finite state machine for Unity3D
Stars: ✭ 243 (+1004.55%)
Mutual labels:  gamedev

Build Status

[Beta] Agones Event Broadcaster

Broadcast Agones GameServers or Fleets states using a message queueing service (or any other implementation of the Broker). The broadcaster will watch for changes happening to both types of resources and will publish those changes using the provided Broker.

Possible scenarios:

  • Tracking of how many players have joined a particular GameServer
  • Find out what is the current state of a Fleet in terms of Ready and Allocated replicas
  • Notify a third-party service when a GameServer starts or when a fleet runs out of capacity
  • Create external cloud resources such as DNS records, firewall rules or proxy directives when a GameServer is Ready
  • Publish information extracted from GameServers or Fleets to Kafka topics to be processed by a data analytics pipeline

Agones

An open source, batteries-included, multiplayer dedicated game server scaling and orchestration platform that can run anywhere Kubernetes can run.

You can find great documentation on https://agones.dev/site/

Important

The Agones Event Broadcaster project is currently in the Alpha stage and subject to change. Pull requests and issues are more than welcome and appreciated.

Use Cases

The most common use case is for folks who want to extract information about their Agones resources running within Kubernetes. Using the broadcaster, you can have one single point of extraction and publish it to different destinations.

Currently, the project supports Google Cloud Pub/Sub. However, this can be extended to any kind of backend. Your implementation of the broker can publish the event to databases, message queueing services, request REST APIs, communicate with gRPC services, etc. There are virtually no restrictions.

You don't need/use/require a message queuing service? We got you covered. Implement your broker and plug it to the broadcaster. Possible, but not limited, ideas for brokers are:

  • MongoDB
  • Elasticsearch
  • MySQL
  • Kafka
  • Cassandra
  • CockroachDB
  • REST Endpoint
  • Remote storage (GCS, S3)
  • Logging systems
  • RabbitMQ
  • gRPC Endpoint
  • BigData
  • Google Cloud Datastore
  • Game server backend
  • Matchmaker
  • ...

FAQ

What does Agones event mean?

For the broadcaster, an event is some sort of information that reflects the state of an Agones resource deployed on the Kubernetes cluster in a particular moment in time. Events can be triggered when a resource has been Added, Updated or Deleted. Currently supported resources are v1.GameServer and v1.Fleet.

How/Where events can be emitted?

The source of events can vary depending on the action which triggered those. For instance, when a GameServer is deployed it might get its state changed many times. From the port allocation to the ready state, the information will be added and updated. I.e.: Address and port, status and labels. For resources of type Fleet, the source of the event can be a change on the number of replicas.

Who is responsible for watching events from the Kubernetes API?

The broadcaster implements the Kubernetes Controller Pattern. It tracks events for resources of type GameServer.

For every single time the state of a resource of type GameServer or Fleet changes, the broadcaster will be notified. Therefore, it will handle the event and publish a message using a Broker. Currently, the controller watches GameServers and Fleets deployed on any namespace. It may change in the future if that becomes a performance issue.

What kind of events will be tracked?

The broadcaster watches for Add, Update and Delete events.

  • Add: When a new GameServer or Fleet has been deployed
  • Update: When the state of the resource changes. It could be a change against the Status field or any other fields part of the spec.
  • Delete: When the resource has been deleted from the Kubernetes cluster

What does the event message content look like?

The current version of the broadcaster sends the entire Agones resource state representation as an encoded json. Additionally, some headers containing information about event type (Add, Update or Delete) and custom attributes added by the broker. In the future, there may be an event middleware/parser that could extract pieces of information and generate custom messages.

As an example, the Pub/Sub broker builds a header that contains information about the destination topic, the type of the event and the projectID. That information wil be used by the broker when performing the SendMessage operation.

 {
  "header": {
    "headers": {
      "event_type": "gameserver.events.added",
      "pubsub_topic_id": "us-central1.gameserver.events.added",
      "pubsub_project_id": "calm-weather-12345"
    }
  },
  "message": {
    ... 
    // Agones GameServer state representation
    ...
  }
}

Examples of messages published to different Pub/Sub:

Supported Brokers

Below you can find a list of supported brokers that can be used for publishing messages.

Logging - Stdout [Development purpose]

Only outputs the content of the message to the application stdout.

It can be used for local development of when another type of broker is not available

Output:

{"message":"{\"header\":{\"headers\":{\"event_type\":\"gameserver.events.added\"}},\"message\":{\"kind\":\"GameServer\",\"apiVersion\":\"agones.dev/v1\",\"metadata\":{\"name\":\"simple-udp-agones\",\"namespace\":\"default\",\"selfLink\":\"/apis/agones.dev/v1/namespaces/default/gameservers/simple-udp-agones\",\"uid\":\"2762bdb9-9387-11ea-ab97-0242ac110002\",\"resourceVersion\":\"827719\",\"generation\":6,\"creationTimestamp\":\"2020-05-11T12:58:47Z\",\"annotations\":{\"agones.dev/ready-container-id\":\"containerd://ca32c651fa5f34efbd263145a9423123616e39ab3e3ddc83358e594cce442236\",\"agones.dev/sdk-version\":\"1.5.0\",\"kubectl.kubernetes.io/last-applied-configuration\":\"{\\\"apiVersion\\\":\\\"agones.dev/v1\\\",\\\"kind\\\":\\\"GameServer\\\",\\\"metadata\\\":{\\\"annotations\\\":{},\\\"name\\\":\\\"simple-udp-agones\\\",\\\"namespace\\\":\\\"default\\\"},\\\"spec\\\":{\\\"ports\\\":[{\\\"containerPort\\\":7654,\\\"name\\\":\\\"default\\\",\\\"portPolicy\\\":\\\"Dynamic\\\"}],\\\"template\\\":{\\\"spec\\\":{\\\"containers\\\":[{\\\"image\\\":\\\"gcr.io/agones-images/udp-server:0.18\\\",\\\"name\\\":\\\"simple-udp\\\",\\\"resources\\\":{\\\"limits\\\":{\\\"cpu\\\":\\\"20m\\\",\\\"memory\\\":\\\"32Mi\\\"},\\\"requests\\\":{\\\"cpu\\\":\\\"20m\\\",\\\"memory\\\":\\\"32Mi\\\"}}}]}}}}\\n\"},\"finalizers\":[\"agones.dev\"]},\"spec\":{\"container\":\"simple-udp\",\"ports\":[{\"name\":\"default\",\"portPolicy\":\"Dynamic\",\"containerPort\":7654,\"hostPort\":7100,\"protocol\":\"UDP\"}],\"health\":{\"periodSeconds\":5,\"failureThreshold\":3,\"initialDelaySeconds\":5},\"scheduling\":\"Packed\",\"sdkServer\":{\"logLevel\":\"Info\",\"grpcPort\":9357,\"httpPort\":9358},\"template\":{\"metadata\":{\"creationTimestamp\":null},\"spec\":{\"containers\":[{\"name\":\"simple-udp\",\"image\":\"gcr.io/agones-images/udp-server:0.18\",\"resources\":{\"limits\":{\"cpu\":\"20m\",\"memory\":\"32Mi\"},\"requests\":{\"cpu\":\"20m\",\"memory\":\"32Mi\"}}}]}}},\"status\":{\"state\":\"Ready\",\"ports\":[{\"name\":\"default\",\"port\":7100}],\"address\":\"172.17.0.2\",\"nodeName\":\"agones-cluster-control-plane\",\"reservedUntil\":null,\"players\":null}}}","severity":"info","time":"2020-05-11T19:40:23.941715+02:00"}

Google Cloud Pub/Sub

Publishes messages to Google Cloud Pub/Sub topics.

Be aware that using the service may cost you some money. Check https://cloud.google.com/pubsub/pricing for detailed information. If you are just experimenting with the project locally, you can use the Google Cloud Pub/Sub emulator https://cloud.google.com/pubsub/docs/emulator.

When publishing a message to Pub/Sub the broker will output the information below.

Output:

{"broker":"pubsub","message":"message published to topicID:\"gameserver.events.added\" messageID:\"20\"","severity":"info","time":"2020-05-11T19:41:57.607351+02:00"}

Requirements:

  • Service Account Credentials with PubSub Editor role assigned to it. Required for checking if the topic exists before publishing.
  • Topics created beforehand. Use those topics when creating the broker config.
  • Environment variable PUBSUB_CREDENTIALS: Json key file path (if running outside of the cluster)

Creating the broker

The topics can be customised by event source (Add, Update, Delete) or be unique for all types of events.

opts := option.WithCredentialsFile(os.Getenv("PUBSUB_CREDENTIALS"))
broker, err := pubsub.NewPubSubBroker(&pubsub.Config{
    ProjectID:       os.Getenv("PUBSUB_PROJECT_ID"),
    // Alternatively, set one topic to publish all types of events.
    // GenericTopicID: "gameserver.events"  
    OnAddTopicID:    "gameserver.events.added", // Use any available topic you you want 
    OnUpdateTopicID: "gameserver.events.updated", // Use any available topic you you want
    OnDeleteTopicID: "gameserver.events.deleted", // Use any available topic you you want
}, opts)

Check the examples/pubsub/main.go file for a complete example.

$ go run examples/pubsub/main.go 

How to run the Agones Event Broadcaster?

Requirements

  • Linux or OSX
  • Kubernetes Cluster 1.14 (Supported by Agones 1.15)
  • Agones 1.15
  • Kubeconfig

The default broker is the stdout. That means messages showing up from the application output.

From Source

$ git clone https://github.com/Octops/agones-event-broadcaster.git
$ go run main.go --kubeconfig=${KUBECONFIG}

Docker

# Building the docker image locally
$ make docker

OR

# Using an image from Docker Hub
1. Make sure your $KUBECONFIG points to the right cluster
2. The Kubernetes API must be reachable by the container. That means 127.0.0.1 will not work unless you run the docker container using the host network
$ docker run -it --rm --name broadcaster \
    -v ${KUBECONFIG}:/app/config \
    -e KUBECONFIG=/app/config \
    octops/agones-event-broadcaster:v0.1-alpha --kubeconfig=/app/config

Deploying

[Optional] Build docker image

This step is only required if you are not using the public image hosted on DockerHub.

$ export DOCKER_IMAGE_TAG=YOUR_REPO_NAME/IMAGE_NAME:TAG
$ make docker
$ docker push ${DOCKER_IMAGE_TAG}

Deploy the Broadcaster

# If required, change the image name from the manifest before applying it
$ kubectl apply -f install/broadcaster-install.yaml

# Manifest that uses the Pub/Sub broker. Check the manifest content and provide the right information about ProjectID.
# The cluster where the broadcaster is going to be deployed requires the proper IAM that has Pub/Sub Editor role assigned to it.
$ kubectl apply -f install/broadcaster-install-pubsub.yaml


# Check logs
$ kubectl logs -f [POD_NAME]

Deploy the GameServer

# Triggers Add and Update events
$ kubectl apply -f examples/agones-udp.yaml

# Triggers a Delete event
$ kubectl delete -f examples/agones-udp.yaml

Destroy

$ kubectl delete -f install/broadcaster-install.yaml

Development

The steps below provide the instructions for running the broadcaster on your local laptop. We will be using the stdout broker. That means messages will not be published to any remote service.

Requirements:

  • Kubernetes Cluster 1.14+
  • Agones 1.6+
  • Kubeconfig

Running

$ go run main.go --kubeconfig=$KUBECONFIG

On another terminal session, push the GameServers manifest to the Kubernetes API. You can use examples/gameservers/agones-udp.yaml for a simple game server.

Apply the manifest and check the broadcaster output for details.

# Triggers Add and Update events
$ kubectl apply -f examples/agones-udp.yaml

# Triggers a Delete event
$ kubectl delete -f examples/agones-udp.yaml

Tests

$ make test

Implementing your own broker

As previously mentioned, you can implement your broker and plug it to the broadcaster. The broker interface is minimal and can be used for different purposes.

The Broker interface:

// Broker is the service used by the Broadcaster for publishing events
type Broker interface {
   BuildEnvelope(event events.Event) (*events.Envelope, error)
   SendMessage(envelope *events.Envelope) error
}

Identifying the source and type of the event:

When implementing brokers this information may help on the implementation of the broker's logic. Being able to differentiate between types of events can define for example to which topic the message should be published. The same logic applies to brokers that use a different type of backend.

type Event interface {
    EventSource() EventSource // the controller event name: OnAdd, OnUpdate, OnDelete
    EventType() EventType // the resource event type (GameServer): gameserver.events.added, gameserver.events.updated, gameserver.events.deleted
}

// Values: OnAdd, OnUpdate, OnDelete
eventSource := event.EventSource() 

// Values: gameserver.events.added, gameserver.events.updated, gameserver.events.deleted
eventType := event.EventType().String()

Example:

// Create an instance of the broker and give it to the broadcaster

// Kafka Broker
import broker ..../brokers/kafka

...

broker := broker.NewKafkaBroker(&broker.Config{})
gsBroadcaster := broadcaster.New(cfg, broker, 15*time.Second)
gsBroadcaster.WithWatcherFor(&v1.GameServer{})

if err := gsBroadcaster.Build(); err != nil {
    logrus.WithError(err).Fatal("error creating broadcaster")
}

...

ctx, stop := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
defer stop()
if err := gsBroadcaster.Start(ctx); err != nil {
    logrus.WithError(err).Fatal("error starting broadcaster")
}

// MongoDB Broker
import broker ..../brokers/mongodb

...

broker := mongodb.NewMongoDBBroker(&mongodb.Config{})
gsBroadcaster := broadcaster.New(cfg, broker, 15*time.Second)
gsBroadcaster.WithWatcherFor(&v1.GameServer{})
if err := gsBroadcaster.Build(); err != nil {
    logrus.WithError(err).Fatal("error creating broadcaster")
}

...

ctx, stop := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
defer stop()
if err := gsBroadcaster.Start(ctx); err != nil {
    logrus.WithError(err).Fatal("error starting broadcaster")
}

Contributions

The Agones Event Broadcaster is currently in Alpha stage. We would love to hear some feedback and use cases that could help improve this project.

Feel free to open an issue if you see mistakes, errors and problems with the documentation.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].