package api import ( "context" "github.com/smallnest/rpcxlite/client" "github.com/smallnest/rpcxlite/protocol" "github.com/vmihailenco/msgpack/v5" "go.arsenm.dev/infinitime" ) const DefaultAddr = "/tmp/itd/socket" type Client struct { itdClient client.XClient itdCh chan *protocol.Message fsClient client.XClient fsCh chan *protocol.Message srvVals map[string]chan interface{} } func New(sockPath string) (*Client, error) { d, err := client.NewPeer2PeerDiscovery("unix@"+sockPath, "") if err != nil { return nil, err } out := &Client{} out.itdCh = make(chan *protocol.Message, 5) out.itdClient = client.NewBidirectionalXClient( "ITD", client.Failtry, client.RandomSelect, d, client.DefaultOption, out.itdCh, ) out.fsCh = make(chan *protocol.Message, 5) out.fsClient = client.NewBidirectionalXClient( "FS", client.Failtry, client.RandomSelect, d, client.DefaultOption, out.fsCh, ) out.srvVals = map[string]chan interface{}{} go out.handleMessages(out.itdCh) go out.handleMessages(out.fsCh) return out, nil } func (c *Client) handleMessages(msgCh chan *protocol.Message) { for msg := range msgCh { _, ok := c.srvVals[msg.ServicePath] if !ok { c.srvVals[msg.ServicePath] = make(chan interface{}, 5) } //fmt.Printf("%+v\n", msg) ch := c.srvVals[msg.ServicePath] switch msg.ServiceMethod { case "FSProgress": var progress FSTransferProgress msgpack.Unmarshal(msg.Payload, &progress) ch <- progress case "DFUProgress": var progress infinitime.DFUProgress msgpack.Unmarshal(msg.Payload, &progress) ch <- progress case "MotionSample": var motionVals infinitime.MotionValues msgpack.Unmarshal(msg.Payload, &motionVals) ch <- motionVals case "Done": close(c.srvVals[msg.ServicePath]) delete(c.srvVals, msg.ServicePath) default: var value interface{} msgpack.Unmarshal(msg.Payload, &value) ch <- value } } } func (c *Client) done(id string) error { return c.itdClient.Call( context.Background(), "Done", id, nil, ) } func (c *Client) Close() error { err := c.itdClient.Close() if err != nil { return err } err = c.fsClient.Close() if err != nil { return err } close(c.itdCh) close(c.fsCh) return nil }