mirror of
https://github.com/Monibuca/plugin-webtransport.git
synced 2025-12-24 11:51:00 +08:00
121 lines
2.7 KiB
Go
121 lines
2.7 KiB
Go
package webtransport
|
||
|
||
import (
|
||
"net/http"
|
||
"strconv"
|
||
|
||
"github.com/quic-go/quic-go"
|
||
. "m7s.live/engine/v4"
|
||
"m7s.live/engine/v4/config"
|
||
)
|
||
|
||
type WebTransportConfig struct {
|
||
ListenAddr string `default:":4433" desc:"监听地址端口(IP:PORT)IP可省略"`
|
||
CertFile string `desc:"证书文件"`
|
||
KeyFile string `desc:"密钥文件"`
|
||
}
|
||
|
||
func (c *WebTransportConfig) OnEvent(event any) {
|
||
switch event.(type) {
|
||
case FirstConfig:
|
||
// if c.CertFile != "" {
|
||
// _, err := os.Stat(c.CertFile)
|
||
// if err != nil {
|
||
// plugin.Error("need certfile", zap.Error(err))
|
||
// plugin.Disabled = true
|
||
// return
|
||
// }
|
||
// }
|
||
// if c.KeyFile != "" {
|
||
// _, err := os.Stat(c.KeyFile)
|
||
// if err != nil {
|
||
// plugin.Error("need keyfile", zap.Error(err))
|
||
// plugin.Disabled = true
|
||
// return
|
||
// }
|
||
// }
|
||
mux := http.NewServeMux()
|
||
mux.HandleFunc("/play/", func(w http.ResponseWriter, r *http.Request) {
|
||
streamPath := r.URL.Path[len("/play/"):]
|
||
session := r.Body.(*Session)
|
||
session.AcceptSession()
|
||
defer session.CloseSession()
|
||
// TODO: 多路
|
||
s, err := session.AcceptStream()
|
||
if err != nil {
|
||
return
|
||
}
|
||
// buf := make([]byte, 1024)
|
||
// n, err := s.Read(buf)
|
||
// if err != nil {
|
||
// return
|
||
// }
|
||
sub := &WebTransportSubscriber{}
|
||
sub.RemoteAddr = r.RemoteAddr
|
||
sub.SetIO(s)
|
||
sub.ID = strconv.FormatInt(int64(s.StreamID()), 10)
|
||
plugin.SubscribeBlock(streamPath, sub, SUBTYPE_FLV)
|
||
})
|
||
mux.HandleFunc("/push/", func(w http.ResponseWriter, r *http.Request) {
|
||
streamPath := r.URL.Path[len("/push/"):]
|
||
session := r.Body.(*Session)
|
||
session.AcceptSession()
|
||
defer session.CloseSession()
|
||
// TODO: 多路
|
||
s, err := session.AcceptStream()
|
||
if err != nil {
|
||
return
|
||
}
|
||
// buf := make([]byte, 1024)
|
||
// n, err := s.Read(buf)
|
||
// if err != nil {
|
||
// return
|
||
// }
|
||
pub := &WebTransportPublisher{}
|
||
pub.SetIO(s)
|
||
pub.ID = strconv.FormatInt(int64(s.StreamID()), 10)
|
||
if plugin.Publish(streamPath, pub) == nil {
|
||
|
||
}
|
||
})
|
||
c.Run(mux)
|
||
}
|
||
}
|
||
|
||
func (c *WebTransportConfig) Run(mux http.Handler) {
|
||
s := &Server{
|
||
Handler: mux,
|
||
ListenAddr: c.ListenAddr,
|
||
TLSCert: CertFile{Path: c.CertFile, Data: config.LocalCert},
|
||
TLSKey: CertFile{Path: c.KeyFile, Data: config.LocalKey},
|
||
}
|
||
|
||
if s.QuicConfig == nil {
|
||
s.QuicConfig = &QuicConfig{}
|
||
}
|
||
s.QuicConfig.EnableDatagrams = true
|
||
|
||
listener, err := quic.ListenAddr(c.ListenAddr, s.generateTLSConfig(), (*quic.Config)(s.QuicConfig))
|
||
if err != nil {
|
||
plugin.Disabled = true
|
||
return
|
||
}
|
||
|
||
go func() {
|
||
<-plugin.Done()
|
||
listener.Close()
|
||
}()
|
||
|
||
go func() {
|
||
for {
|
||
sess, err := listener.Accept(plugin)
|
||
if err != nil {
|
||
return
|
||
}
|
||
go s.handleSession(plugin, sess)
|
||
}
|
||
}()
|
||
}
|
||
|
||
var plugin = InstallPlugin(&WebTransportConfig{})
|