8 "github.com/anacrolix/log"
9 "github.com/anacrolix/torrent/tracker/http"
10 "github.com/gorilla/websocket"
12 "github.com/anacrolix/torrent/tracker"
13 "github.com/anacrolix/torrent/webtorrent"
14 "github.com/pion/datachannel"
17 type websocketTrackerStatus struct {
19 tc *webtorrent.TrackerClient
22 func (me websocketTrackerStatus) statusLine() string {
23 return fmt.Sprintf("%+v", me.tc.Stats())
26 func (me websocketTrackerStatus) URL() *url.URL {
30 type refCountedWebtorrentTrackerClient struct {
31 webtorrent.TrackerClient
35 type websocketTrackers struct {
38 GetAnnounceRequest func(event tracker.AnnounceEvent, infoHash [20]byte) (tracker.AnnounceRequest, error)
39 OnConn func(datachannel.ReadWriteCloser, webtorrent.DataChannelContext)
41 clients map[string]*refCountedWebtorrentTrackerClient
45 func (me *websocketTrackers) Get(url string, infoHash [20]byte) (*webtorrent.TrackerClient, func()) {
48 value, ok := me.clients[url]
50 dialer := &websocket.Dialer{Proxy: me.Proxy, HandshakeTimeout: websocket.DefaultDialer.HandshakeTimeout}
51 value = &refCountedWebtorrentTrackerClient{
52 TrackerClient: webtorrent.TrackerClient{
55 GetAnnounceRequest: me.GetAnnounceRequest,
58 Logger: me.Logger.WithText(func(m log.Msg) string {
59 return fmt.Sprintf("tracker client for %q: %v", url, m)
63 value.TrackerClient.Start(func(err error) {
65 me.Logger.Printf("error running tracker client for %q: %v", url, err)
68 if me.clients == nil {
69 me.clients = make(map[string]*refCountedWebtorrentTrackerClient)
71 me.clients[url] = value
74 return &value.TrackerClient, func() {
77 value.TrackerClient.CloseOffersForInfohash(infoHash)
79 if value.refCount == 0 {
80 value.TrackerClient.Close()
81 delete(me.clients, url)