Skip to content

Commit

Permalink
feat: Add Go coffee machine client implementation with streaming support
Browse files Browse the repository at this point in the history
  • Loading branch information
pojntfx committed Feb 23, 2024
1 parent 42c9fe3 commit cc3dc62
Show file tree
Hide file tree
Showing 2 changed files with 185 additions and 4 deletions.
184 changes: 184 additions & 0 deletions go/cmd/panrpc-example-websocket-coffee-client-cli/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
package main

import (
"bufio"
"context"
"encoding/json"
"flag"
"log"
"os"

"github.com/pojntfx/panrpc/go/pkg/rpc"
"nhooyr.io/websocket"
)

type remoteControl struct{}

func (s *remoteControl) SetCoffeeMachineBrewing(ctx context.Context, brewing bool) error {
if brewing {
log.Println("Coffee machine is now brewing")
} else {
log.Println("Coffee machine has stopped brewing")
}

return nil
}

type coffeeMachine struct {
BrewCoffee func(
ctx context.Context,
variant string,
size int,
onProgress func(ctx context.Context, percentage int) error,
) (int, error)
}

func main() {
flag.Parse()

ctx, cancel := context.WithCancel(context.Background())
defer cancel()

clients := 0

registry := rpc.NewRegistry[coffeeMachine, json.RawMessage](
&remoteControl{},

ctx,

&rpc.Options{
OnClientConnect: func(remoteID string) {
clients++

log.Printf("%v coffee machines connected", clients)
},
OnClientDisconnect: func(remoteID string) {
clients--

log.Printf("%v coffee machines connected", clients)
},
},
)

go func() {
log.Println(`Enter one of the following numbers followed by <ENTER> to brew a coffee:
- 1: Brew small Cafè Latte
- 2: Brew large Cafè Latte
- 3: Brew small Americano
- 4: Brew large Americano`)

stdin := bufio.NewReader(os.Stdin)

for {
line, err := stdin.ReadString('\n')
if err != nil {
panic(err)
}

if err := registry.ForRemotes(func(remoteID string, remote coffeeMachine) error {
switch line {
case "1\n":
fallthrough
case "2\n":
res, err := remote.BrewCoffee(
ctx,
"latte",
func() int {
if line == "1" {
return 100
} else {
return 200
}
}(),
func(ctx context.Context, percentage int) error {
log.Printf(`Brewing Cafè Latte ... %v%% done`, percentage)

return nil
},
)
if err != nil {
log.Println("Couldn't brew Cafè Latte:", err)

return nil
}

log.Println("Remaining water:", res, "ml")

case "3\n":
fallthrough
case "4\n":
res, err := remote.BrewCoffee(
ctx,
"americano",
func() int {
if line == "1" {
return 100
} else {
return 200
}
}(),
func(ctx context.Context, percentage int) error {
log.Printf(`Brewing Americano ... %v%% done`, percentage)

return nil
},
)
if err != nil {
log.Println("Couldn't brew Americano:", err)

return nil
}

log.Println("Remaining water:", res, "ml")

default:
log.Printf("Unknown letter %v, ignoring input", line)

return nil
}

return nil
}); err != nil {
panic(err)
}
}
}()

c, _, err := websocket.Dial(ctx, "ws://127.0.0.1:1337", nil)
if err != nil {
panic(err)
}

conn := websocket.NetConn(ctx, c, websocket.MessageText)
defer conn.Close()

log.Println("Connected to localhost:1337")

encoder := json.NewEncoder(conn)
decoder := json.NewDecoder(conn)

if err := registry.LinkStream(
func(v rpc.Message[json.RawMessage]) error {
return encoder.Encode(v)
},
func(v *rpc.Message[json.RawMessage]) error {
return decoder.Decode(v)
},

func(v any) (json.RawMessage, error) {
b, err := json.Marshal(v)
if err != nil {
return nil, err
}

return json.RawMessage(b), nil
},
func(data json.RawMessage, v any) error {
return json.Unmarshal([]byte(data), v)
},
); err != nil {
panic(err)
}
}
5 changes: 1 addition & 4 deletions go/cmd/panrpc-example-websocket-coffee-server-cli/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"context"
"encoding/json"
"errors"
"flag"
"log"
"net"
"net/http"
Expand Down Expand Up @@ -70,8 +69,6 @@ type remoteControl struct {
}

func main() {
flag.Parse()

ctx, cancel := context.WithCancel(context.Background())
defer cancel()

Expand Down Expand Up @@ -99,7 +96,7 @@ func main() {
},
)

lis, err := net.Listen("tcp", "localhost:1337")
lis, err := net.Listen("tcp", "127.0.0.1:1337")
if err != nil {
panic(err)
}
Expand Down

0 comments on commit cc3dc62

Please sign in to comment.