mirror of
https://github.com/AlexxIT/go2rtc.git
synced 2026-04-22 15:47:06 +08:00
109 lines
2.4 KiB
Go
109 lines
2.4 KiB
Go
package webtorrent
|
|
|
|
import (
|
|
"fmt"
|
|
"net/http"
|
|
|
|
"github.com/AlexxIT/go2rtc/pkg/webtorrent"
|
|
"github.com/gorilla/websocket"
|
|
)
|
|
|
|
var upgrader *websocket.Upgrader
|
|
var hashes map[string]map[string]*websocket.Conn
|
|
|
|
func tracker(w http.ResponseWriter, r *http.Request) {
|
|
if upgrader == nil {
|
|
upgrader = &websocket.Upgrader{
|
|
ReadBufferSize: 1024,
|
|
WriteBufferSize: 2028,
|
|
}
|
|
upgrader.CheckOrigin = func(r *http.Request) bool {
|
|
return true
|
|
}
|
|
}
|
|
|
|
ws, err := upgrader.Upgrade(w, r, nil)
|
|
if err != nil {
|
|
log.Warn().Err(err).Send()
|
|
return
|
|
}
|
|
|
|
defer ws.Close()
|
|
|
|
for {
|
|
var msg webtorrent.Message
|
|
if err = ws.ReadJSON(&msg); err != nil {
|
|
return
|
|
}
|
|
|
|
//log.Trace().Msgf("[webtorrent] message=%v", msg)
|
|
|
|
if msg.InfoHash == "" || msg.PeerId == "" {
|
|
continue
|
|
}
|
|
|
|
if hashes == nil {
|
|
hashes = map[string]map[string]*websocket.Conn{}
|
|
}
|
|
|
|
// new or old client with offers
|
|
clients := hashes[msg.InfoHash]
|
|
if clients == nil {
|
|
clients = map[string]*websocket.Conn{
|
|
msg.PeerId: ws,
|
|
}
|
|
hashes[msg.InfoHash] = clients
|
|
} else {
|
|
clients[msg.PeerId] = ws
|
|
}
|
|
|
|
switch {
|
|
case msg.Offers != nil:
|
|
// ask for ping
|
|
raw := fmt.Sprintf(
|
|
`{"action":"announce","interval":120,"info_hash":"%s","complete":0,"incomplete":1}`,
|
|
msg.InfoHash,
|
|
)
|
|
if err = ws.WriteMessage(websocket.TextMessage, []byte(raw)); err != nil {
|
|
log.Warn().Err(err).Send()
|
|
return
|
|
}
|
|
|
|
// skip if no offers (server)
|
|
if len(msg.Offers) == 0 {
|
|
continue
|
|
}
|
|
|
|
// get and check only first offer
|
|
offer := msg.Offers[0]
|
|
if offer.OfferId == "" || offer.Offer.Type != "offer" || offer.Offer.SDP == "" {
|
|
continue
|
|
}
|
|
|
|
// send offer to all clients (one of them - server)
|
|
raw = fmt.Sprintf(
|
|
`{"action":"announce","info_hash":"%s","peer_id":"%s","offer_id":"%s","offer":{"type":"offer","sdp":"%s"}}`,
|
|
msg.InfoHash, msg.PeerId, offer.OfferId, offer.Offer.SDP,
|
|
)
|
|
|
|
for _, server := range clients {
|
|
if server != ws {
|
|
_ = server.WriteMessage(websocket.TextMessage, []byte(raw))
|
|
}
|
|
}
|
|
|
|
case msg.OfferId != "" && msg.ToPeerId != "" && msg.Answer != nil:
|
|
ws1, ok := clients[msg.ToPeerId]
|
|
if !ok {
|
|
continue
|
|
}
|
|
|
|
raw := fmt.Sprintf(
|
|
`{"action":"announce","info_hash":"%s","peer_id":"%s","offer_id":"%s","answer":{"type":"answer","sdp":"%s"}}`,
|
|
msg.InfoHash, msg.PeerId, msg.OfferId, msg.Answer.SDP,
|
|
)
|
|
_ = ws1.WriteMessage(websocket.TextMessage, []byte(raw))
|
|
}
|
|
}
|
|
}
|