package main
import (
"context"
"fmt"
"net"
"net/http"
_ "net/http/pprof"
"regexp"
"sync/atomic"
"time"
"github.com/joho/godotenv"
ssrpc "github.com/pancsta/asyncmachine-go/pkg/rpc/states"
ssam "github.com/pancsta/asyncmachine-go/pkg/states"
amrelay "github.com/pancsta/asyncmachine-go/tools/relay"
amrelayt "github.com/pancsta/asyncmachine-go/tools/relay/types"
example "github.com/pancsta/asyncmachine-go/examples/wasm"
"github.com/pancsta/asyncmachine-go/examples/wasm/states"
amhelp "github.com/pancsta/asyncmachine-go/pkg/helpers"
am "github.com/pancsta/asyncmachine-go/pkg/machine"
arpc "github.com/pancsta/asyncmachine-go/pkg/rpc"
)
var ssF = states .FooStates
var ssB = states .BarStates
var PassRpc = example .PassRpc
type ARpc = example .ARpc
func init() {
_ = godotenv .Load ()
}
func main() {
ctx := context .Background ()
go func () {
http .ListenAndServe ("localhost:6060" , nil )
}()
handlers := &HandlersFoo {
lastMsg : time .Now (),
}
fooMach , err := am .NewCommon (ctx , "server-foo" , states .FooSchema , ssF .Names (), handlers , nil , nil )
if err != nil {
panic (err )
}
amhelp .MachDebugEnv (fooMach )
fooMach .SemLogger ().SetArgsMapper (example .LogArgs )
handlers .machFoo = fooMach
arpc .MachRepl (fooMach , example .EnvFooReplAddr , &arpc .ReplOpts {
AddrDir : "tmp" ,
Args : ARpc {},
ParseRpc : example .ParseRpc ,
})
fooMach .Add1 (ssF .Start , nil )
s , err := arpc .NewServer (ctx , example .EnvFooWsAddr , "server-foo" , fooMach , &arpc .ServerOpts {
WebSocket : true ,
Parent : fooMach ,
})
if err != nil {
panic (err )
}
s .Start (nil )
handlers .s = s
newClient := func (ctx context .Context , id string , conn net .Conn ) (*arpc .Client , error ) {
bar , err := arpc .NewClient (ctx , "localhost:0" , "server-bar" , states .BarSchema , &arpc .ClientOpts {
Parent : fooMach ,
})
if err != nil {
panic (err )
}
bar .Conn .Store (&conn )
handlers .rpcBar .Store (bar )
bar .Start (nil )
go func () {
<-bar .Mach .When1 (ssrpc .ClientStates .Ready , nil )
fmt .Printf ("aRPC connected via WebSocket\n" )
}()
return bar , nil
}
relay , err := amrelay .New (ctx , amrelayt .Args {
Name : "wasm-demo" ,
Debug : true ,
Parent : fooMach ,
Wasm : &amrelayt .ArgsWasm {
ListenAddr : example .EnvRelayHttpAddr ,
StaticDir : "./client" ,
ReplAddrDir : "tmp" ,
ClientMatchers : []amrelayt .ClientMatcher {{
Id : regexp .MustCompile ("^browser-bar-" ),
NewClient : newClient ,
}},
},
})
if err != nil {
panic (err )
}
relay .Start (nil )
select {}
}
type HandlersFoo struct {
machFoo *am .Machine
rpcBar atomic .Pointer [arpc .Client ]
s *arpc .Server
lastMsg time .Time
lastHello time .Time
}
func (h *HandlersFoo ) StartState (e *am .Event ) {
ctx := h .machFoo .NewStateCtx (ssF .Start )
h .machFoo .Fork (ctx , e , func () {
ticker := time .NewTicker (time .Second )
defer ticker .Stop ()
for {
select {
case <- ctx .Done ():
return
case <- ticker .C :
if time .Since (h .lastMsg ) > 15 *time .Second && h .machFoo .Not1 (ssF .Bored ) {
h .machFoo .Add1 (ssF .Bored , nil )
}
bar := h .rpcBar .Load ()
if bar != nil && time .Since (h .lastHello ) > 10 *time .Second &&
bar .Mach .Is1 (ssam .BasicStates .Ready ) &&
bar .NetMach .Tick (ssB .Msg ) < 20 {
args := PassRpc (&ARpc {
Msg : "hello" ,
})
bar .NetMach .EvAdd1 (e , ssF .Msg , args )
h .machFoo .EvAdd1 (e , ssF .Msg , args )
h .lastHello = time .Now ()
}
}
}
})
}
func (h *HandlersFoo ) MsgEnter (e *am .Event ) bool {
return example .ParseArgs (e .Args ).Msg != ""
}
func (h *HandlersFoo ) MsgState (e *am .Event ) {
h .machFoo .Remove1 (ssF .Msg , nil )
args := example .ParseArgs (e .Args )
author := "bar"
if e .Mutation ().Source != nil {
author = e .Mutation ().Source .MachId
}
msg := fmt .Sprintf ("[%s] %s\n" , author , args .Msg )
fmt .Print (msg )
h .lastMsg = time .Now ()
}
func (h *HandlersFoo ) BoredState (e *am .Event ) {
fmt .Println ("foo is bored..." )
}
The pages are generated with Golds v0.8.2 . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds .