mirror of
https://github.com/m1k1o/neko.git
synced 2026-11-03 00:11:48 -06:00
refactor: standardize constant names and improve goroutine handling across multiple files.
This commit is contained in:
@@ -61,7 +61,7 @@ func (h *RoomHandler) clipboardGetImage(w http.ResponseWriter, r *http.Request)
|
|||||||
|
|
||||||
/* TODO: Unused now.
|
/* TODO: Unused now.
|
||||||
func (h *RoomHandler) clipboardSetImage(w http.ResponseWriter, r *http.Request) error {
|
func (h *RoomHandler) clipboardSetImage(w http.ResponseWriter, r *http.Request) error {
|
||||||
err := r.ParseMultipartForm(MAX_UPLOAD_SIZE)
|
err := r.ParseMultipartForm(multipartFormMaxMemory)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return utils.HttpBadRequest("failed to parse multipart form").WithInternalErr(err)
|
return utils.HttpBadRequest("failed to parse multipart form").WithInternalErr(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,14 +13,14 @@ import (
|
|||||||
// TODO: Extract file uploading to custom utility.
|
// TODO: Extract file uploading to custom utility.
|
||||||
|
|
||||||
// maximum upload size of 32 MB
|
// maximum upload size of 32 MB
|
||||||
const maxUploadSize = 32 << 20
|
const multipartFormMaxMemory = 32 << 20
|
||||||
|
|
||||||
func (h *RoomHandler) uploadDrop(w http.ResponseWriter, r *http.Request) error {
|
func (h *RoomHandler) uploadDrop(w http.ResponseWriter, r *http.Request) error {
|
||||||
if !h.desktop.IsUploadDropEnabled() {
|
if !h.desktop.IsUploadDropEnabled() {
|
||||||
return utils.HttpBadRequest("upload drop is disabled")
|
return utils.HttpBadRequest("upload drop is disabled")
|
||||||
}
|
}
|
||||||
|
|
||||||
err := r.ParseMultipartForm(maxUploadSize)
|
err := r.ParseMultipartForm(multipartFormMaxMemory)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return utils.HttpBadRequest("failed to parse multipart form").WithInternalErr(err)
|
return utils.HttpBadRequest("failed to parse multipart form").WithInternalErr(err)
|
||||||
}
|
}
|
||||||
@@ -95,7 +95,7 @@ func (h *RoomHandler) uploadDialogPost(w http.ResponseWriter, r *http.Request) e
|
|||||||
return utils.HttpBadRequest("file chooser dialog is disabled")
|
return utils.HttpBadRequest("file chooser dialog is disabled")
|
||||||
}
|
}
|
||||||
|
|
||||||
err := r.ParseMultipartForm(maxUploadSize)
|
err := r.ParseMultipartForm(multipartFormMaxMemory)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return utils.HttpBadRequest("failed to parse multipart form").WithInternalErr(err)
|
return utils.HttpBadRequest("failed to parse multipart form").WithInternalErr(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -87,11 +87,7 @@ func screencastNew(enabled bool, pipelineStr string) *ScreencastManagerCtx {
|
|||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
|
|
||||||
manager.wg.Add(1)
|
manager.wg.Go(func() {
|
||||||
|
|
||||||
go func() {
|
|
||||||
defer manager.wg.Done()
|
|
||||||
|
|
||||||
ticker := time.NewTicker(screencastTimeout)
|
ticker := time.NewTicker(screencastTimeout)
|
||||||
defer ticker.Stop()
|
defer ticker.Stop()
|
||||||
|
|
||||||
@@ -105,7 +101,7 @@ func screencastNew(enabled bool, pipelineStr string) *ScreencastManagerCtx {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}()
|
})
|
||||||
|
|
||||||
return manager
|
return manager
|
||||||
}
|
}
|
||||||
@@ -212,12 +208,9 @@ func (manager *ScreencastManagerCtx) createPipeline() error {
|
|||||||
return errors.New("timeouted while waiting for first image")
|
return errors.New("timeouted while waiting for first image")
|
||||||
}
|
}
|
||||||
|
|
||||||
manager.wg.Add(1)
|
|
||||||
pipeline := manager.pipeline
|
pipeline := manager.pipeline
|
||||||
|
manager.wg.Go(func() {
|
||||||
go func() {
|
|
||||||
manager.logger.Debug().Msg("started receiving images")
|
manager.logger.Debug().Msg("started receiving images")
|
||||||
defer manager.wg.Done()
|
|
||||||
|
|
||||||
for {
|
for {
|
||||||
image, ok := <-pipeline.Sample()
|
image, ok := <-pipeline.Sample()
|
||||||
@@ -228,7 +221,7 @@ func (manager *ScreencastManagerCtx) createPipeline() error {
|
|||||||
|
|
||||||
manager.setImage(image)
|
manager.setImage(image)
|
||||||
}
|
}
|
||||||
}()
|
})
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -325,12 +325,9 @@ func (manager *StreamSinkManagerCtx) CreatePipeline() error {
|
|||||||
manager.pipeline.AttachAppsink("appsink")
|
manager.pipeline.AttachAppsink("appsink")
|
||||||
manager.pipeline.Play()
|
manager.pipeline.Play()
|
||||||
|
|
||||||
manager.wg.Add(1)
|
|
||||||
pipeline := manager.pipeline
|
pipeline := manager.pipeline
|
||||||
|
manager.wg.Go(func() {
|
||||||
go func() {
|
|
||||||
manager.logger.Debug().Msg("started emitting samples")
|
manager.logger.Debug().Msg("started emitting samples")
|
||||||
defer manager.wg.Done()
|
|
||||||
|
|
||||||
for {
|
for {
|
||||||
sample, ok := <-pipeline.Sample()
|
sample, ok := <-pipeline.Sample()
|
||||||
@@ -341,7 +338,7 @@ func (manager *StreamSinkManagerCtx) CreatePipeline() error {
|
|||||||
|
|
||||||
manager.onSample(sample)
|
manager.onSample(sample)
|
||||||
}
|
}
|
||||||
}()
|
})
|
||||||
|
|
||||||
manager.pipelinesCounter.Inc()
|
manager.pipelinesCounter.Inc()
|
||||||
manager.pipelinesActive.Set(1)
|
manager.pipelinesActive.Set(1)
|
||||||
|
|||||||
@@ -150,19 +150,20 @@ func NewVideoPipeline(rtpCodec codec.RTPCodec, display string, pipelineSrc strin
|
|||||||
vbvbuf = bitrate
|
vbvbuf = bitrate
|
||||||
}
|
}
|
||||||
|
|
||||||
if hwenc == HwEncVAAPI {
|
switch hwenc {
|
||||||
|
case HwEncVAAPI:
|
||||||
if err := gst.CheckPlugins([]string{"vaapi"}); err != nil {
|
if err := gst.CheckPlugins([]string{"vaapi"}); err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
pipelineStr = fmt.Sprintf(videoSrc+"video/x-raw,format=NV12 ! vaapih264enc rate-control=vbr bitrate=%d keyframe-period=180 quality-level=7 ! video/x-h264,stream-format=byte-stream,profile=constrained-baseline"+pipelineStr, display, fps, bitrate)
|
pipelineStr = fmt.Sprintf(videoSrc+"video/x-raw,format=NV12 ! vaapih264enc rate-control=vbr bitrate=%d keyframe-period=180 quality-level=7 ! video/x-h264,stream-format=byte-stream,profile=constrained-baseline"+pipelineStr, display, fps, bitrate)
|
||||||
} else if hwenc == HwEncNVENC {
|
case HwEncNVENC:
|
||||||
if err := gst.CheckPlugins([]string{"nvcodec"}); err != nil {
|
if err := gst.CheckPlugins([]string{"nvcodec"}); err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
pipelineStr = fmt.Sprintf(videoSrc+"video/x-raw,format=NV12 ! nvh264enc name=encoder preset=2 gop-size=25 spatial-aq=true temporal-aq=true bitrate=%d vbv-buffer-size=%d rc-mode=6 ! h264parse config-interval=-1 ! video/x-h264,stream-format=byte-stream,profile=constrained-baseline"+pipelineStr, display, fps, bitrate, vbvbuf)
|
pipelineStr = fmt.Sprintf(videoSrc+"video/x-raw,format=NV12 ! nvh264enc name=encoder preset=2 gop-size=25 spatial-aq=true temporal-aq=true bitrate=%d vbv-buffer-size=%d rc-mode=6 ! h264parse config-interval=-1 ! video/x-h264,stream-format=byte-stream,profile=constrained-baseline"+pipelineStr, display, fps, bitrate, vbvbuf)
|
||||||
} else {
|
default:
|
||||||
// https://gstreamer.freedesktop.org/documentation/openh264/openh264enc.html?gi-language=c#openh264enc
|
// https://gstreamer.freedesktop.org/documentation/openh264/openh264enc.html?gi-language=c#openh264enc
|
||||||
// gstreamer1.0-plugins-bad
|
// gstreamer1.0-plugins-bad
|
||||||
// openh264enc multi-thread=4 complexity=high bitrate=3072000 max-bitrate=4096000
|
// openh264enc multi-thread=4 complexity=high bitrate=3072000 max-bitrate=4096000
|
||||||
|
|||||||
@@ -11,18 +11,21 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
ClipboardTextPlainTarget = "UTF8_STRING"
|
// MIME type for plain text in clipboard
|
||||||
ClipboardTextHtmlTarget = "text/html"
|
clipboardTextPlainTarget = "UTF8_STRING"
|
||||||
|
|
||||||
|
// MIME type for HTML in clipboard
|
||||||
|
clipboardTextHtmlTarget = "text/html"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (manager *DesktopManagerCtx) ClipboardGetText() (*types.ClipboardText, error) {
|
func (manager *DesktopManagerCtx) ClipboardGetText() (*types.ClipboardText, error) {
|
||||||
text, err := manager.ClipboardGetBinary(ClipboardTextPlainTarget)
|
text, err := manager.ClipboardGetBinary(clipboardTextPlainTarget)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rich text must not always be available, can fail silently.
|
// Rich text must not always be available, can fail silently.
|
||||||
html, _ := manager.ClipboardGetBinary(ClipboardTextHtmlTarget)
|
html, _ := manager.ClipboardGetBinary(clipboardTextHtmlTarget)
|
||||||
|
|
||||||
return &types.ClipboardText{
|
return &types.ClipboardText{
|
||||||
Text: string(text),
|
Text: string(text),
|
||||||
@@ -36,10 +39,10 @@ func (manager *DesktopManagerCtx) ClipboardSetText(data types.ClipboardText) err
|
|||||||
// is set, if available. Otherwise plain text.
|
// is set, if available. Otherwise plain text.
|
||||||
|
|
||||||
if data.HTML != "" {
|
if data.HTML != "" {
|
||||||
return manager.ClipboardSetBinary(ClipboardTextHtmlTarget, []byte(data.HTML))
|
return manager.ClipboardSetBinary(clipboardTextHtmlTarget, []byte(data.HTML))
|
||||||
}
|
}
|
||||||
|
|
||||||
return manager.ClipboardSetBinary(ClipboardTextPlainTarget, []byte(data.Text))
|
return manager.ClipboardSetBinary(clipboardTextPlainTarget, []byte(data.Text))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (manager *DesktopManagerCtx) ClipboardGetBinary(mime string) ([]byte, error) {
|
func (manager *DesktopManagerCtx) ClipboardGetBinary(mime string) ([]byte, error) {
|
||||||
@@ -114,17 +117,14 @@ func (manager *DesktopManagerCtx) ClipboardSetBinary(mime string, data []byte) e
|
|||||||
case <-wait:
|
case <-wait:
|
||||||
}
|
}
|
||||||
|
|
||||||
manager.wg.Add(1)
|
manager.wg.Go(func() {
|
||||||
go func() {
|
|
||||||
defer manager.wg.Done()
|
|
||||||
|
|
||||||
if err := cmd.Wait(); err != nil {
|
if err := cmd.Wait(); err != nil {
|
||||||
msg := strings.TrimSpace(stderr.String())
|
msg := strings.TrimSpace(stderr.String())
|
||||||
manager.logger.Err(err).Msgf("clipboard command finished with error: %s", msg)
|
manager.logger.Err(err).Msgf("clipboard command finished with error: %s", msg)
|
||||||
} else {
|
} else {
|
||||||
manager.logger.Debug().Msg("clipboard command finished successfully")
|
manager.logger.Debug().Msg("clipboard command finished successfully")
|
||||||
}
|
}
|
||||||
}()
|
})
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,11 +6,16 @@ import (
|
|||||||
"github.com/m1k1o/neko/server/pkg/drop"
|
"github.com/m1k1o/neko/server/pkg/drop"
|
||||||
)
|
)
|
||||||
|
|
||||||
// repeat move event multiple times
|
const (
|
||||||
const dropMoveRepeat = 4
|
// repeat move event multiple times
|
||||||
|
dropMoveRepeat = 4
|
||||||
|
|
||||||
// wait after each repeated move event
|
// wait after each repeated move event
|
||||||
const dropMoveDelay = 100 * time.Millisecond
|
dropMoveDelay = 100 * time.Millisecond
|
||||||
|
|
||||||
|
// wait for drop to finish before giving up
|
||||||
|
dropFinishTimeout = 1 * time.Second
|
||||||
|
)
|
||||||
|
|
||||||
func (manager *DesktopManagerCtx) DropFiles(x int, y int, files []string) bool {
|
func (manager *DesktopManagerCtx) DropFiles(x int, y int, files []string) bool {
|
||||||
mu.Lock()
|
mu.Lock()
|
||||||
@@ -32,7 +37,7 @@ func (manager *DesktopManagerCtx) DropFiles(x int, y int, files []string) bool {
|
|||||||
})
|
})
|
||||||
|
|
||||||
drop.Emmiter.Once("begin", func(payload ...any) {
|
drop.Emmiter.Once("begin", func(payload ...any) {
|
||||||
for i := 0; i < dropMoveRepeat; i++ {
|
for range dropMoveRepeat {
|
||||||
manager.Move(x, y)
|
manager.Move(x, y)
|
||||||
time.Sleep(dropMoveDelay)
|
time.Sleep(dropMoveDelay)
|
||||||
}
|
}
|
||||||
@@ -57,7 +62,7 @@ func (manager *DesktopManagerCtx) DropFiles(x int, y int, files []string) bool {
|
|||||||
select {
|
select {
|
||||||
case succeeded := <-finished:
|
case succeeded := <-finished:
|
||||||
return succeeded
|
return succeeded
|
||||||
case <-time.After(1 * time.Second):
|
case <-time.After(dropFinishTimeout):
|
||||||
drop.CloseWindow()
|
drop.CloseWindow()
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,14 +7,19 @@ import (
|
|||||||
"github.com/m1k1o/neko/server/pkg/xorg"
|
"github.com/m1k1o/neko/server/pkg/xorg"
|
||||||
)
|
)
|
||||||
|
|
||||||
// name of the window that is being controlled
|
const (
|
||||||
const fileChooserDialogName = "Open File"
|
// name of the window that is being controlled
|
||||||
|
fileChooserDialogName = "Open File"
|
||||||
|
|
||||||
// short sleep value between fake user interactions
|
// short sleep value between fake user interactions
|
||||||
const fileChooserDialogShortSleep = "0.2"
|
fileChooserDialogShortSleep = "0.2"
|
||||||
|
|
||||||
// long sleep value between fake user interactions
|
// long sleep value between fake user interactions
|
||||||
const fileChooserDialogLongSleep = "0.4"
|
fileChooserDialogLongSleep = "0.4"
|
||||||
|
|
||||||
|
// number of attempts to close the dialog
|
||||||
|
fileChooserDialogCloseAttempts = 5
|
||||||
|
)
|
||||||
|
|
||||||
func (manager *DesktopManagerCtx) HandleFileChooserDialog(uri string) error {
|
func (manager *DesktopManagerCtx) HandleFileChooserDialog(uri string) error {
|
||||||
mu.Lock()
|
mu.Lock()
|
||||||
@@ -57,7 +62,7 @@ func (manager *DesktopManagerCtx) HandleFileChooserDialog(uri string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (manager *DesktopManagerCtx) CloseFileChooserDialog() {
|
func (manager *DesktopManagerCtx) CloseFileChooserDialog() {
|
||||||
for i := 0; i < 5; i++ {
|
for range fileChooserDialogCloseAttempts {
|
||||||
mu.Lock()
|
mu.Lock()
|
||||||
|
|
||||||
manager.logger.Debug().Msg("attempting to close file chooser dialog")
|
manager.logger.Debug().Msg("attempting to close file chooser dialog")
|
||||||
|
|||||||
@@ -17,6 +17,14 @@ import (
|
|||||||
"github.com/m1k1o/neko/server/pkg/xorg"
|
"github.com/m1k1o/neko/server/pkg/xorg"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// debounce frequency for key events
|
||||||
|
debounceFrequency = 1 * time.Second
|
||||||
|
|
||||||
|
// debounce duration for key events
|
||||||
|
debounceDuration = 10 * time.Second
|
||||||
|
)
|
||||||
|
|
||||||
var mu = sync.Mutex{}
|
var mu = sync.Mutex{}
|
||||||
|
|
||||||
type DesktopManagerCtx struct {
|
type DesktopManagerCtx struct {
|
||||||
@@ -100,16 +108,10 @@ func (manager *DesktopManagerCtx) Start() {
|
|||||||
Msg("X event error occured")
|
Msg("X event error occured")
|
||||||
})
|
})
|
||||||
|
|
||||||
manager.wg.Add(1)
|
manager.wg.Go(func() {
|
||||||
|
ticker := time.NewTicker(debounceFrequency)
|
||||||
go func() {
|
|
||||||
defer manager.wg.Done()
|
|
||||||
|
|
||||||
ticker := time.NewTicker(1 * time.Second)
|
|
||||||
defer ticker.Stop()
|
defer ticker.Stop()
|
||||||
|
|
||||||
const debounceDuration = 10 * time.Second
|
|
||||||
|
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-manager.shutdown:
|
case <-manager.shutdown:
|
||||||
@@ -119,7 +121,7 @@ func (manager *DesktopManagerCtx) Start() {
|
|||||||
manager.input.Debounce(debounceDuration)
|
manager.input.Debounce(debounceDuration)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}()
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (manager *DesktopManagerCtx) OnBeforeScreenSizeChange(listener func()) {
|
func (manager *DesktopManagerCtx) OnBeforeScreenSizeChange(listener func()) {
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ import (
|
|||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
const MULTIPART_FORM_MAX_MEMORY = 32 << 20
|
const multipartFormMaxMemory = 32 << 20
|
||||||
|
|
||||||
func NewManager(
|
func NewManager(
|
||||||
sessions types.SessionManager,
|
sessions types.SessionManager,
|
||||||
@@ -285,7 +285,7 @@ func (m *Manager) uploadFileHandler(w http.ResponseWriter, r *http.Request) erro
|
|||||||
return utils.HttpForbidden("file transfer is disabled")
|
return utils.HttpForbidden("file transfer is disabled")
|
||||||
}
|
}
|
||||||
|
|
||||||
err = r.ParseMultipartForm(MULTIPART_FORM_MAX_MEMORY)
|
err = r.ParseMultipartForm(multipartFormMaxMemory)
|
||||||
if err != nil || r.MultipartForm == nil {
|
if err != nil || r.MultipartForm == nil {
|
||||||
return utils.HttpBadRequest().
|
return utils.HttpBadRequest().
|
||||||
WithInternalErr(err).
|
WithInternalErr(err).
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import (
|
|||||||
|
|
||||||
// client is expected to reconnect within 5 second
|
// client is expected to reconnect within 5 second
|
||||||
// if some unexpected websocket disconnect happens
|
// if some unexpected websocket disconnect happens
|
||||||
const WS_DELAYED_DURATION = 5 * time.Second
|
const wsDelayedDuration = 5 * time.Second
|
||||||
|
|
||||||
type SessionCtx struct {
|
type SessionCtx struct {
|
||||||
id string
|
id string
|
||||||
@@ -165,7 +165,7 @@ func (session *SessionCtx) DisconnectWebSocketPeer(websocketPeer types.WebSocket
|
|||||||
var wsDelayedTimer *time.Timer
|
var wsDelayedTimer *time.Timer
|
||||||
|
|
||||||
if delayed {
|
if delayed {
|
||||||
wsDelayedTimer = time.AfterFunc(WS_DELAYED_DURATION, func() {
|
wsDelayedTimer = time.AfterFunc(wsDelayedDuration, func() {
|
||||||
session.DisconnectWebSocketPeer(websocketPeer, false)
|
session.DisconnectWebSocketPeer(websocketPeer, false)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -284,9 +284,10 @@ func (met *metrics) NewICECandidate(candidate webrtc.ICECandidateStats) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
met.iceCandidates[candidate.ID] = struct{}{}
|
met.iceCandidates[candidate.ID] = struct{}{}
|
||||||
if candidate.Protocol == "udp" {
|
switch candidate.Protocol {
|
||||||
|
case "udp":
|
||||||
met.iceCandidatesUdpCount.Add(1)
|
met.iceCandidatesUdpCount.Add(1)
|
||||||
} else if candidate.Protocol == "tcp" {
|
case "tcp":
|
||||||
met.iceCandidatesTcpCount.Add(1)
|
met.iceCandidatesTcpCount.Add(1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -294,9 +295,10 @@ func (met *metrics) NewICECandidate(candidate webrtc.ICECandidateStats) {
|
|||||||
func (met *metrics) SetICECandidatesUsed(candidates []webrtc.ICECandidateStats) {
|
func (met *metrics) SetICECandidatesUsed(candidates []webrtc.ICECandidateStats) {
|
||||||
udp, tcp := 0, 0
|
udp, tcp := 0, 0
|
||||||
for _, candidate := range candidates {
|
for _, candidate := range candidates {
|
||||||
if candidate.Protocol == "udp" {
|
switch candidate.Protocol {
|
||||||
|
case "udp":
|
||||||
udp++
|
udp++
|
||||||
} else if candidate.Protocol == "tcp" {
|
case "tcp":
|
||||||
tcp++
|
tcp++
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -401,10 +401,8 @@ func (peer *WebRTCPeerCtx) SetVideo(r types.PeerVideoRequest) error {
|
|||||||
|
|
||||||
// send video signal if modified
|
// send video signal if modified
|
||||||
if modified {
|
if modified {
|
||||||
go func() {
|
// in goroutine because of mutex and we don't want to block
|
||||||
// in goroutine because of mutex and we don't want to block
|
go peer.session.Send(event.SIGNAL_VIDEO, peer.Video())
|
||||||
peer.session.Send(event.SIGNAL_VIDEO, peer.Video())
|
|
||||||
}()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@@ -455,10 +453,8 @@ func (peer *WebRTCPeerCtx) SetAudio(r types.PeerAudioRequest) error {
|
|||||||
|
|
||||||
// send video signal if modified
|
// send video signal if modified
|
||||||
if modified {
|
if modified {
|
||||||
go func() {
|
// in goroutine because of mutex and we don't want to block
|
||||||
// in goroutine because of mutex and we don't want to block
|
go peer.session.Send(event.SIGNAL_AUDIO, peer.Audio())
|
||||||
peer.session.Send(event.SIGNAL_AUDIO, peer.Audio())
|
|
||||||
}()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@@ -18,14 +18,16 @@ import (
|
|||||||
"github.com/m1k1o/neko/server/pkg/utils"
|
"github.com/m1k1o/neko/server/pkg/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
// send pings to peer with this period - must be less than pongWait
|
const (
|
||||||
const pingPeriod = 10 * time.Second
|
// send pings to peer with this period - must be less than pongWait
|
||||||
|
pingPeriod = 10 * time.Second
|
||||||
|
|
||||||
// period for sending inactive cursor messages
|
// period for sending inactive cursor messages
|
||||||
const inactiveCursorsPeriod = 750 * time.Millisecond
|
inactiveCursorsPeriod = 750 * time.Millisecond
|
||||||
|
|
||||||
// maximum payload length for logging
|
// maximum payload length for logging
|
||||||
const maxPayloadLogLength = 10_000
|
maxPayloadLogLength = 10_000
|
||||||
|
)
|
||||||
|
|
||||||
// events that are not logged in debug mode
|
// events that are not logged in debug mode
|
||||||
var nologEvents = []string{
|
var nologEvents = []string{
|
||||||
@@ -309,10 +311,7 @@ func (manager *WebSocketManagerCtx) handle(connection *websocket.Conn, peer type
|
|||||||
ticker := time.NewTicker(pingPeriod)
|
ticker := time.NewTicker(pingPeriod)
|
||||||
defer ticker.Stop()
|
defer ticker.Stop()
|
||||||
|
|
||||||
manager.wg.Add(1)
|
manager.wg.Go(func() {
|
||||||
go func() {
|
|
||||||
defer manager.wg.Done()
|
|
||||||
|
|
||||||
for {
|
for {
|
||||||
_, raw, err := connection.ReadMessage()
|
_, raw, err := connection.ReadMessage()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -322,7 +321,7 @@ func (manager *WebSocketManagerCtx) handle(connection *websocket.Conn, peer type
|
|||||||
|
|
||||||
bytes <- raw
|
bytes <- raw
|
||||||
}
|
}
|
||||||
}()
|
})
|
||||||
|
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
@@ -381,10 +380,7 @@ func (manager *WebSocketManagerCtx) startInactiveCursors() {
|
|||||||
manager.logger.Info().Msg("starting inactive cursors handler")
|
manager.logger.Info().Msg("starting inactive cursors handler")
|
||||||
manager.shutdownInactiveCursors = make(chan struct{})
|
manager.shutdownInactiveCursors = make(chan struct{})
|
||||||
|
|
||||||
manager.wg.Add(1)
|
manager.wg.Go(func() {
|
||||||
go func() {
|
|
||||||
defer manager.wg.Done()
|
|
||||||
|
|
||||||
ticker := time.NewTicker(inactiveCursorsPeriod)
|
ticker := time.NewTicker(inactiveCursorsPeriod)
|
||||||
defer ticker.Stop()
|
defer ticker.Stop()
|
||||||
|
|
||||||
@@ -424,7 +420,7 @@ func (manager *WebSocketManagerCtx) startInactiveCursors() {
|
|||||||
manager.sessions.InactiveCursorsBroadcast(event.SESSION_CURSORS, sessionCursors)
|
manager.sessions.InactiveCursorsBroadcast(event.SESSION_CURSORS, sessionCursors)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}()
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (manager *WebSocketManagerCtx) stopInactiveCursors() {
|
func (manager *WebSocketManagerCtx) stopInactiveCursors() {
|
||||||
|
|||||||
Reference in New Issue
Block a user