delete moq, create transport rooms
All checks were successful
Create and publish a Docker image 🚀 / build-and-push-image (push) Successful in 1m48s
All checks were successful
Create and publish a Docker image 🚀 / build-and-push-image (push) Successful in 1m48s
This commit is contained in:
57
cmd/main.go
57
cmd/main.go
@@ -1,57 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"log/slog"
|
||||
"strings"
|
||||
|
||||
"github.com/caddyserver/certmagic"
|
||||
"github.com/okdaichi/gomoqt/moqt"
|
||||
|
||||
"qgo/internal/relay"
|
||||
)
|
||||
|
||||
func main() {
|
||||
domain := "qgo-server.quizer.space"
|
||||
email := "serverussnap@outlook.com"
|
||||
|
||||
certmagic.DefaultACME.Email = email
|
||||
certmagic.DefaultACME.Agreed = true
|
||||
certmagic.Default.Storage = &certmagic.FileStorage{
|
||||
Path: "/root/.local/share/certmagic",
|
||||
}
|
||||
|
||||
tlsConf, err := certmagic.TLS([]string{domain})
|
||||
if err != nil {
|
||||
slog.Error("TLS failed", "err", err)
|
||||
return
|
||||
}
|
||||
|
||||
tlsConf.NextProtos = []string{"h3"}
|
||||
tlsConf.MinVersion = tls.VersionTLS13
|
||||
|
||||
relayServer := relay.New()
|
||||
|
||||
moqt.HandleFunc("/relay/", func(w moqt.SetupResponseWriter, r *moqt.SetupRequest) {
|
||||
|
||||
room := strings.TrimPrefix(r.Path, "/relay/")
|
||||
mux := relayServer.GetMux(room)
|
||||
|
||||
_, err := moqt.Accept(w, r, mux)
|
||||
if err != nil {
|
||||
slog.Error("accept failed", "err", err)
|
||||
w.Reject(moqt.InternalSessionErrorCode)
|
||||
return
|
||||
}
|
||||
|
||||
slog.Info("session connected", "room", room)
|
||||
})
|
||||
|
||||
slog.Info("Mini-SFU running",
|
||||
"url", "https://"+domain+"/relay/{room}",
|
||||
)
|
||||
|
||||
if err := moqt.ListenAndServe(":443", tlsConf); err != nil {
|
||||
slog.Error("server failed", "err", err)
|
||||
}
|
||||
}
|
||||
10
go.mod
10
go.mod
@@ -4,23 +4,18 @@ go 1.25.0
|
||||
|
||||
require (
|
||||
github.com/caddyserver/certmagic v0.25.2
|
||||
github.com/okdaichi/gomoqt v0.10.7
|
||||
github.com/quic-go/quic-go v0.59.0
|
||||
github.com/quic-go/webtransport-go v0.10.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/caddyserver/zerossl v0.1.5 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/dunglas/httpsfv v1.1.0 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.3.0 // indirect
|
||||
github.com/libdns/libdns v1.1.1 // indirect
|
||||
github.com/mholt/acmez/v3 v3.1.6 // indirect
|
||||
github.com/miekg/dns v1.1.72 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/quic-go/qpack v0.6.0 // indirect
|
||||
github.com/quic-go/quic-go v0.59.0 // indirect
|
||||
github.com/quic-go/webtransport-go v0.10.0 // indirect
|
||||
github.com/stretchr/objx v0.5.3 // indirect
|
||||
github.com/stretchr/testify v1.11.1 // indirect
|
||||
github.com/zeebo/blake3 v0.2.4 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
go.uber.org/zap v1.27.1 // indirect
|
||||
@@ -32,5 +27,4 @@ require (
|
||||
golang.org/x/sys v0.41.0 // indirect
|
||||
golang.org/x/text v0.34.0 // indirect
|
||||
golang.org/x/tools v0.42.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
||||
13
go.sum
13
go.sum
@@ -14,10 +14,6 @@ github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y=
|
||||
github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/letsencrypt/challtestsrv v1.4.2 h1:0ON3ldMhZyWlfVNYYpFuWRTmZNnyfiL9Hh5YzC3JVwU=
|
||||
github.com/letsencrypt/challtestsrv v1.4.2/go.mod h1:GhqMqcSoeGpYd5zX5TgwA6er/1MbWzx/o7yuuVya+Wk=
|
||||
github.com/letsencrypt/pebble/v2 v2.10.0 h1:Wq6gYXlsY6ubqI3hhxsTzdyotvfdjFBxuwYqCLCnj/U=
|
||||
@@ -28,8 +24,6 @@ github.com/mholt/acmez/v3 v3.1.6 h1:eGVQNObP0pBN4sxqrXeg7MYqTOWyoiYpQqITVWlrevk=
|
||||
github.com/mholt/acmez/v3 v3.1.6/go.mod h1:5nTPosTGosLxF3+LU4ygbgMRFDhbAVpqMI4+a4aHLBY=
|
||||
github.com/miekg/dns v1.1.72 h1:vhmr+TF2A3tuoGNkLDFK9zi36F2LS+hKTRW0Uf8kbzI=
|
||||
github.com/miekg/dns v1.1.72/go.mod h1:+EuEPhdHOsfk6Wk5TT2CzssZdqkmFhf8r+aVyDEToIs=
|
||||
github.com/okdaichi/gomoqt v0.10.7 h1:+2fEG8BgBkPPvUorwpaWd9k4IZrtUx+Nr4EDuz8BpYc=
|
||||
github.com/okdaichi/gomoqt v0.10.7/go.mod h1:a85xgBn+vYbsWTn+cH7YQlnmvSE5m8XptIbP1wEz9v0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/quic-go/qpack v0.6.0 h1:g7W+BMYynC1LbYLSqRt8PBg5Tgwxn214ZZR34VIOjz8=
|
||||
@@ -38,10 +32,6 @@ github.com/quic-go/quic-go v0.59.0 h1:OLJkp1Mlm/aS7dpKgTc6cnpynnD2Xg7C1pwL6vy/SA
|
||||
github.com/quic-go/quic-go v0.59.0/go.mod h1:upnsH4Ju1YkqpLXC305eW3yDZ4NfnNbmQRCMWS58IKU=
|
||||
github.com/quic-go/webtransport-go v0.10.0 h1:LqXXPOXuETY5Xe8ITdGisBzTYmUOy5eSj+9n4hLTjHI=
|
||||
github.com/quic-go/webtransport-go v0.10.0/go.mod h1:LeGIXr5BQKE3UsynwVBeQrU1TPrbh73MGoC6jd+V7ow=
|
||||
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
|
||||
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
|
||||
github.com/stretchr/objx v0.5.3 h1:jmXUvGomnU1o3W/V5h2VEradbpJDwGrzugQQvL0POH4=
|
||||
github.com/stretchr/objx v0.5.3/go.mod h1:rDQraq+vQZU7Fde9LOZLr8Tax6zZvy4kuNKF+QYS+U0=
|
||||
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
|
||||
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
|
||||
github.com/zeebo/assert v1.1.0 h1:hU1L1vLTHsnO8x8c9KAR5GmM5QscxHg5RNU5z5qbUWY=
|
||||
@@ -74,8 +64,5 @@ golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk=
|
||||
golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA=
|
||||
golang.org/x/tools v0.42.0 h1:uNgphsn75Tdz5Ji2q36v/nsFSfR/9BRFvqhGBaJGd5k=
|
||||
golang.org/x/tools v0.42.0/go.mod h1:Ma6lCIwGZvHK6XtgbswSoWroEkhugApmsXyrUmBhfr0=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
package relay
|
||||
|
||||
import (
|
||||
"sync"
|
||||
|
||||
"github.com/okdaichi/gomoqt/moqt"
|
||||
)
|
||||
|
||||
type Relay struct {
|
||||
mu sync.RWMutex
|
||||
rooms map[string]*moqt.TrackMux
|
||||
}
|
||||
|
||||
func New() *Relay {
|
||||
return &Relay{
|
||||
rooms: make(map[string]*moqt.TrackMux),
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Relay) GetMux(room string) *moqt.TrackMux {
|
||||
r.mu.Lock()
|
||||
defer r.mu.Unlock()
|
||||
|
||||
if mux, ok := r.rooms[room]; ok {
|
||||
return mux
|
||||
}
|
||||
|
||||
mux := moqt.NewTrackMux()
|
||||
r.rooms[room] = mux
|
||||
return mux
|
||||
}
|
||||
146
main.go
Normal file
146
main.go
Normal file
@@ -0,0 +1,146 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"log"
|
||||
"net/http"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/caddyserver/certmagic"
|
||||
"github.com/quic-go/quic-go/http3"
|
||||
"github.com/quic-go/webtransport-go"
|
||||
)
|
||||
|
||||
type Room struct {
|
||||
conns map[*webtransport.Session]bool
|
||||
mu sync.Mutex
|
||||
}
|
||||
|
||||
type Server struct {
|
||||
rooms map[string]*Room
|
||||
mu sync.Mutex
|
||||
}
|
||||
|
||||
func NewServer() *Server {
|
||||
return &Server{
|
||||
rooms: make(map[string]*Room),
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Server) getRoom(name string) *Room {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
|
||||
if room, ok := s.rooms[name]; ok {
|
||||
return room
|
||||
}
|
||||
|
||||
room := &Room{
|
||||
conns: make(map[*webtransport.Session]bool),
|
||||
}
|
||||
s.rooms[name] = room
|
||||
return room
|
||||
}
|
||||
|
||||
func (s *Server) handleSession(roomName string, sess *webtransport.Session) {
|
||||
room := s.getRoom(roomName)
|
||||
|
||||
room.mu.Lock()
|
||||
room.conns[sess] = true
|
||||
room.mu.Unlock()
|
||||
|
||||
log.Println("joined room:", roomName)
|
||||
|
||||
defer func() {
|
||||
room.mu.Lock()
|
||||
delete(room.conns, sess)
|
||||
room.mu.Unlock()
|
||||
log.Println("left room:", roomName)
|
||||
}()
|
||||
|
||||
for {
|
||||
stream, err := sess.AcceptStream(context.Background())
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
go s.handleStream(room, sess, stream)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Server) handleStream(room *Room, sender *webtransport.Session, stream *webtransport.Stream) {
|
||||
buf := make([]byte, 4096)
|
||||
|
||||
for {
|
||||
n, err := stream.Read(buf)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
room.mu.Lock()
|
||||
for conn := range room.conns {
|
||||
if conn == sender {
|
||||
continue
|
||||
}
|
||||
go func(c *webtransport.Session) {
|
||||
out, err := c.OpenStream()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer out.Close()
|
||||
out.Write(buf[:n])
|
||||
}(conn)
|
||||
}
|
||||
room.mu.Unlock()
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
domain := "qgo-server.quizer.space"
|
||||
email := "serverussnap@outlook.com"
|
||||
|
||||
certmagic.DefaultACME.Email = email
|
||||
certmagic.DefaultACME.Agreed = true
|
||||
certmagic.Default.Storage = &certmagic.FileStorage{
|
||||
Path: "/root/.local/share/certmagic",
|
||||
}
|
||||
|
||||
tlsConf, err := certmagic.TLS([]string{domain})
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
tlsConf.NextProtos = []string{"h3"}
|
||||
tlsConf.MinVersion = tls.VersionTLS13
|
||||
|
||||
server := NewServer()
|
||||
|
||||
mux := http.NewServeMux()
|
||||
|
||||
wtServer := &webtransport.Server{
|
||||
H3: &http3.Server{
|
||||
Addr: ":443",
|
||||
TLSConfig: tlsConf,
|
||||
},
|
||||
}
|
||||
|
||||
mux.HandleFunc("/room/", func(w http.ResponseWriter, r *http.Request) {
|
||||
roomName := strings.TrimPrefix(r.URL.Path, "/room/")
|
||||
|
||||
sess, err := wtServer.Upgrade(w, r)
|
||||
if err != nil {
|
||||
log.Println("upgrade error:", err)
|
||||
return
|
||||
}
|
||||
|
||||
go server.handleSession(roomName, sess)
|
||||
})
|
||||
|
||||
wtServer.H3.Handler = mux
|
||||
|
||||
log.Println("Relay running on https://" + domain + "/room/{room}")
|
||||
|
||||
log.Fatal(wtServer.ListenAndServe())
|
||||
}
|
||||
@@ -1,85 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
|
||||
"github.com/caddyserver/certmagic"
|
||||
"github.com/okdaichi/gomoqt/moqt"
|
||||
"github.com/okdaichi/gomoqt/quic"
|
||||
)
|
||||
|
||||
func main() {
|
||||
domain := "qgo-server.quizer.space"
|
||||
email := "serverussnap@outlook.com"
|
||||
|
||||
// 1. Настройка CertMagic
|
||||
certmagic.DefaultACME.Email = email
|
||||
certmagic.DefaultACME.Agreed = true
|
||||
certmagic.Default.Storage = &certmagic.FileStorage{Path: "/root/.local/share/certmagic"}
|
||||
|
||||
// Создаем TLS конфигурацию
|
||||
tlsConfig, err := certmagic.TLS([]string{domain})
|
||||
if err != nil {
|
||||
slog.Error("failed to setup TLS", "error", err)
|
||||
return
|
||||
}
|
||||
|
||||
// Поддержка протоколов для браузера и MoQ
|
||||
tlsConfig.NextProtos = []string{"h3"}
|
||||
tlsConfig.MinVersion = tls.VersionTLS13
|
||||
|
||||
// 2. Инициализация MoQ сервера
|
||||
moqServer := moqt.Server{
|
||||
Addr: ":443",
|
||||
TLSConfig: tlsConfig,
|
||||
QUICConfig: &quic.Config{
|
||||
Allow0RTT: true,
|
||||
EnableDatagrams: true,
|
||||
},
|
||||
}
|
||||
|
||||
path := "/relay"
|
||||
|
||||
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Alt-Svc", `h3=":443"; ma=2592000`)
|
||||
|
||||
if r.URL.Path == path {
|
||||
err := moqServer.HandleWebTransport(w, r)
|
||||
if err != nil {
|
||||
slog.Error("WebTransport error", "error", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
fmt.Fprintf(w, "MoQ Server is active at %s", path)
|
||||
})
|
||||
|
||||
moqt.HandleFunc(path, func(w moqt.SetupResponseWriter, r *moqt.SetupRequest) {
|
||||
sess, err := moqt.Accept(w, r, nil)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
go handleSession(sess)
|
||||
})
|
||||
|
||||
slog.Info("Starting MoQ server", "url", "https://"+domain)
|
||||
|
||||
go func() {
|
||||
err := certmagic.HTTPS([]string{domain}, http.DefaultServeMux)
|
||||
if err != nil {
|
||||
slog.Error("TCP/HTTPS Server failed", "error", err)
|
||||
}
|
||||
}()
|
||||
|
||||
if err := moqServer.ListenAndServe(); err != nil {
|
||||
slog.Error("MoQ UDP Server failed", "error", err)
|
||||
}
|
||||
}
|
||||
|
||||
func handleSession(sess *moqt.Session) {
|
||||
slog.Info("MoQ session established", "remote", sess.RemoteAddr())
|
||||
<-sess.Context().Done()
|
||||
slog.Info("MoQ session closed")
|
||||
}
|
||||
Reference in New Issue
Block a user