tags |
---|
Golang |
Implement a Simon Says game with gRPC streaming and create a deploy script for Kibernetes
You must have an access to a Kubernetes cluster with a working kubecli
client. The cluster can be in the Cloud or running on your machine, e.g.: minikube. Up to you.
Install protobuf-compiler - You can download precompiled binaries of protoc for all platforms right on the ProtoBuf GitHub releases page. https://github.com/protocolbuffers/protobuf/releases/
Golang packages: go get -u github.com/golang/protobuf/protoc-gen-go go get -u github.com/golang/protobuf/proto go get -u google.golang.org/grpc
The following .proto specification is fix anything else is up to your imagination.
syntax = "proto3";
package simonsays;
option go_package = "symonsayspb"
/*
The Simon Says service.
Allows you to actually play the game.
*/
service SimonSays {
/*
Game process is the following:
A Join Request should be sent to the game. This tells it
to join a game (or start a new one if one isn't already waiting on a game).
The Response stream will send through a BEGIN Response.State to let you know that
the Game has been started.
When the player recieves a START_TURN response, the server can take your input for the turn.
When the player recieves a STOP_TURN response, the serer is no longer taking input for the turn.
A WIN state says you won the game. A LOSE state means that you got an input wrong, and have lost.
To send input, send a Request with an event type of Color.
When you recieve a Response of type Color, then light up that colour.
*/
rpc Game(stream Request) returns (stream Response) {}
}
message Request {
//A Player of the Simon says game.
message Player {
string id = 1;
}
oneof event {
Player join = 1;
Color press = 2;
}
}
message Response {
enum State {
BEGIN = 0;
START_TURN = 1;
STOP_TURN = 2;
WIN = 3;
LOSE = 4;
}
oneof event {
State turn = 1;
Color lightup = 2;
}
}
enum Color {
RED = 0;
GREEN = 1;
YELLOW = 2;
BLUE = 3;
}
Init a git repo under the same path you will use for github.com
Eg.:
~$ cd ~/go/src/github.com/olivernadj
olivernadj$ mkdir -p simonsays/simonsays_client
olivernadj$ cd simonsays
simonsays$ mkdir simonsays_server
simonsays$ mkdir simonsayspb
simonsays$ touch simonsayspb/simonsays.proto
simonsays$ tree
.
├── simonsays_client
├── simonsayspb
│ └── simonsays.proto
└── simonsays_server
Generate your gRPC code
simonsays$ protoc -I simonsayspb/ simonsayspb/simonsays.proto --go_out=plugins=grpc:simonsayspb
If all good you should have a new file simonsays.pb.go
file under simonsayspb/
simonsays_client/client.go
code
simonsays_server/server.go
package main
import (
"fmt"
symonsayspb "github.com/olivernadj/simonsays/simonsayspb"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"log"
"net"
)
type server struct{}
func main() {
fmt.Println("Simon says hello")
lis, err := net.Listen("tcp", "0.0.0.0:50051")
if err != nil {
log.Fatalf("Failed to listen: %v", err)
}
s := grpc.NewServer()
symonsayspb.RegisterSimonSaysServer(s, &server{})
if err := s.Serve(lis); err != nil {
log.Fatalf("failed to serve: %v", err)
}
}
func (s *server) Game(stream symonsayspb.SimonSays_GameServer) error {
return status.Errorf(codes.Unimplemented, "method Game not implemented")
}
Start the server in a separate console
simonsays$ go run simonsays_server/server.go
Simon says hello server
# this message appear only if a client request has inicialised
Game function was invoked with a streaming request
Start the clien in a separate console
simonsays$ go run simonsays_client/client.go
Simon says hello client
Starting to do a BiDi Streaming RPC...
Sending message: join:<id:"John" >
Received: turn:BEGIN, light:UNSPECIFIED
Sending message: join:<id:"Jane" >
Received: turn:BEGIN, light:UNSPECIFIED
Sending message: press:BLUE
Received: turn:UNSPECIFIED, light:BLUE
Sending message: press:GREEN
Received: turn:UNSPECIFIED, light:GREEN
https://github.com/olivernadj/simonsays
Implement business logic requested in .proto and create Kubernetes deployment configs and script.
The force be with you!!!