package main import ( "encoding/binary" "fmt" "net" "time" ) type CartClient struct { *CartTCPClient } func CartDial(address string) (*CartClient, error) { mux, err := NewCartTCPClient(address) if err != nil { return nil, err } client := &CartClient{ CartTCPClient: mux, } return client, nil } func (c *Client) Close() { c.Conn.Close() } type CartTCPClient struct { net.Conn ErrorCount int address string *CartPacketQueue } func NewCartTCPClient(address string) (*CartTCPClient, error) { connection, err := net.Dial("tcp", address) if err != nil { return nil, err } return &CartTCPClient{ ErrorCount: 0, Conn: connection, address: address, CartPacketQueue: NewCartPacketQueue(connection), }, nil } func (m *CartTCPClient) Connect() error { if m.Conn == nil { connection, err := net.Dial("tcp", m.address) if err != nil { m.ErrorCount++ return err } m.ErrorCount = 0 m.Conn = connection } return nil } func (m *CartTCPClient) SendPacket(messageType uint32, id CartId, data []byte) error { err := m.Connect() if err != nil { return err } err = binary.Write(m.Conn, binary.LittleEndian, CartPacket{ Version: CurrentPacketVersion, MessageType: messageType, DataLength: uint32(len(data)), Id: id, }) if err != nil { return err } _, err = m.Conn.Write(data) return err } // func (m *CartTCPClient) SendPacketFn(messageType uint16, id CartId, datafn func(w io.Writer) error) error { // data, err := GetData(datafn) // if err != nil { // return err // } // return m.SendPacket(messageType, id, data) // } func (m *CartTCPClient) Call(messageType uint32, id CartId, responseType uint32, data []byte) (*CallResult, error) { packetChan := m.Expect(responseType, id) err := m.SendPacket(messageType, id, data) if err != nil { return nil, err } select { case ret := <-packetChan: return &ret, nil case <-time.After(time.Second): return nil, fmt.Errorf("timeout") } }