client.go 1.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. package client
  2. import (
  3. "bufio"
  4. "fmt"
  5. "github.com/ftrvxmtrx/fd"
  6. "github.com/pkg/errors"
  7. "io"
  8. "log"
  9. "net"
  10. "sync/atomic"
  11. )
  12. type Client struct {
  13. reqs uint32
  14. conn *net.UnixConn
  15. }
  16. func NewClient(path string) (*Client, error) {
  17. laddr, err := net.ResolveUnixAddr("unix", "")
  18. if err != nil {
  19. return nil, err
  20. }
  21. raddr, err := net.ResolveUnixAddr("unix", path)
  22. if err != nil {
  23. return nil, err
  24. }
  25. conn, err := net.DialUnix("unix", laddr, raddr)
  26. if err != nil {
  27. return nil, err
  28. }
  29. c := &Client{conn: conn}
  30. go c.readIncomming()
  31. return c, nil
  32. }
  33. func (c *Client) Close() error {
  34. // close open requests
  35. return c.conn.Close()
  36. }
  37. func (c *Client) readIncomming() {
  38. sc := bufio.NewScanner(c.conn)
  39. for sc.Scan() {
  40. txt := sc.Text()
  41. log.Println(txt)
  42. // handle response
  43. }
  44. }
  45. func (c *Client) OpenChannel(name string, args interface{}) (io.ReadWriteCloser, error) {
  46. fmt.Fprintf(c.conn, "%d:%s:%+v\n", c.reqs, name, args)
  47. atomic.AddUint32(&c.reqs, 1)
  48. files, err := fd.Get(c.conn, 2, []string{name + ":r", name + ":w"})
  49. if err != nil {
  50. return nil, err
  51. }
  52. if n := len(files); n != 2 {
  53. return nil, errors.Errorf("not enough files?! %d", n)
  54. }
  55. return rwc{files[0], files[1]}, nil
  56. }
  57. type rwc struct {
  58. io.Reader
  59. io.WriteCloser
  60. }