15 connIdIssued time.Time
16 Dispatcher *Dispatcher
20 func (cl *Client) Announce(
21 ctx context.Context, req AnnounceRequest, peers AnnounceResponsePeers, opts Options,
23 respHdr AnnounceResponseHeader, err error,
25 body, err := marshal(req)
29 respBody, err := cl.request(ctx, ActionAnnounce, append(body, opts.Encode()...))
33 r := bytes.NewBuffer(respBody)
34 err = Read(r, &respHdr)
36 err = fmt.Errorf("reading response header: %w", err)
39 err = peers.UnmarshalBinary(r.Bytes())
41 err = fmt.Errorf("reading response peers: %w", err)
46 func (cl *Client) connect(ctx context.Context) (err error) {
47 if time.Since(cl.connIdIssued) < time.Minute {
50 respBody, err := cl.request(ctx, ActionConnect, nil)
54 var connResp ConnectionResponse
55 err = binary.Read(bytes.NewReader(respBody), binary.BigEndian, &connResp)
59 cl.connId = connResp.ConnectionId
60 cl.connIdIssued = time.Now()
64 func (cl *Client) connIdForRequest(ctx context.Context, action Action) (id ConnectionId, err error) {
65 if action == ActionConnect {
66 id = ConnectRequestConnectionId
77 func (cl *Client) requestWriter(ctx context.Context, action Action, body []byte, tId TransactionId) (err error) {
80 var connId ConnectionId
81 connId, err = cl.connIdForRequest(ctx, action)
86 err = binary.Write(&buf, binary.BigEndian, RequestHeader{
95 _, err = cl.Writer.Write(buf.Bytes())
102 case <-time.After(timeout(n)):
107 func (cl *Client) request(ctx context.Context, action Action, body []byte) (respBody []byte, err error) {
108 respChan := make(chan DispatchedResponse, 1)
109 t := cl.Dispatcher.NewTransaction(func(dr DispatchedResponse) {
113 ctx, cancel := context.WithCancel(ctx)
115 writeErr := make(chan error, 1)
117 writeErr <- cl.requestWriter(ctx, action, body, t.Id())
120 case dr := <-respChan:
121 if dr.Header.Action == action {
123 } else if dr.Header.Action == ActionError {
124 err = errors.New(string(dr.Body))
126 err = fmt.Errorf("unexpected response action %v", dr.Header.Action)
128 case err = <-writeErr:
129 err = fmt.Errorf("write error: %w", err)