fix: accept low-latency desktop move channel
This commit is contained in:
parent
4859396051
commit
3dd2359ca3
@ -471,12 +471,14 @@ WebRTC RTP stats: packets=... packetDelta=1100 byteDelta=950000 writeErrors=0
|
||||
- `mouse_move` / hover 约 16ms 最多发送一次
|
||||
- 同一归一化坐标重复移动不发送
|
||||
- `mouse_down` 前强制发送最新坐标,保证点击命中
|
||||
- data channel `bufferedAmount` 过高时只丢弃 `mouse_move`
|
||||
- `mouse_move` 走独立 `input-move` data channel,配置为 unordered + 短 packet lifetime
|
||||
- 点击、键盘、滚轮走可靠有序 `input` data channel
|
||||
- `input-move` channel `bufferedAmount` 过高时只丢弃 `mouse_move`
|
||||
- `mouse_down`、`mouse_up`、`key_down`、`key_up`、`scroll` 不因背压丢弃
|
||||
|
||||
判读:
|
||||
|
||||
- 鼠标轨迹延迟但点击最终准确,通常是旧 `mouse_move` 事件排队。
|
||||
- 鼠标轨迹延迟但点击最终准确,通常是 `input-move` 背压或 Bridge 侧 mouse move coalescing 积压。
|
||||
- 点击也延迟或丢失,要查 data channel 状态、Bridge input injector、xdotool 写入。
|
||||
|
||||
### 3. 再看 Bridge input injector
|
||||
@ -484,13 +486,14 @@ WebRTC RTP stats: packets=... packetDelta=1100 byteDelta=950000 writeErrors=0
|
||||
Bridge 侧输入链路是:
|
||||
|
||||
```text
|
||||
APP Pointer/Key event -> WebRTC data channel -> Bridge OnDataChannel -> XdotoolInjector.Inject -> persistent xdotool stdin -> X11
|
||||
APP Pointer/Key event -> WebRTC input/input-move data channel -> Bridge OnDataChannel -> XdotoolInjector.Inject -> persistent xdotool stdin -> X11
|
||||
```
|
||||
|
||||
重点日志:
|
||||
|
||||
```text
|
||||
Data channel 'input'-'...' opened
|
||||
Data channel 'input-move'-'...' opened
|
||||
xdotool write error: ...
|
||||
xdotool mousemove write error: ...
|
||||
```
|
||||
|
||||
@ -13,6 +13,11 @@ import (
|
||||
"github.com/pion/webrtc/v4"
|
||||
)
|
||||
|
||||
const (
|
||||
desktopReliableInputChannelLabel = "input"
|
||||
desktopMoveInputChannelLabel = "input-move"
|
||||
)
|
||||
|
||||
type WebRTCServer struct {
|
||||
peerConnection *webrtc.PeerConnection
|
||||
videoTrack *webrtc.TrackLocalStaticRTP
|
||||
@ -88,18 +93,24 @@ func (w *WebRTCServer) InitPeerConnection(iceServers []string) error {
|
||||
// Handle Data Channel for inputs
|
||||
pc.OnDataChannel(func(d *webrtc.DataChannel) {
|
||||
log.Printf("Data channel '%s'-'%d' opened", d.Label(), d.ID())
|
||||
if d.Label() == "input" {
|
||||
d.OnMessage(func(msg webrtc.DataChannelMessage) {
|
||||
var event InputEvent
|
||||
if err := json.Unmarshal(msg.Data, &event); err != nil {
|
||||
log.Printf("Failed to unmarshal input event: %v", err)
|
||||
return
|
||||
}
|
||||
if err := w.inputInjector.Inject(event); err != nil {
|
||||
log.Printf("Failed to inject input event: %v", err)
|
||||
}
|
||||
})
|
||||
label := d.Label()
|
||||
if !isDesktopInputDataChannelLabel(label) {
|
||||
return
|
||||
}
|
||||
d.OnMessage(func(msg webrtc.DataChannelMessage) {
|
||||
var event InputEvent
|
||||
if err := json.Unmarshal(msg.Data, &event); err != nil {
|
||||
log.Printf("Failed to unmarshal input event: %v", err)
|
||||
return
|
||||
}
|
||||
if label == desktopMoveInputChannelLabel && event.Type != "mouse_move" {
|
||||
log.Printf("Ignoring non-mouse_move input event on %s channel: %s", label, event.Type)
|
||||
return
|
||||
}
|
||||
if err := w.inputInjector.Inject(event); err != nil {
|
||||
log.Printf("Failed to inject input event: %v", err)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
w.peerConnection = pc
|
||||
@ -108,6 +119,10 @@ func (w *WebRTCServer) InitPeerConnection(iceServers []string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func isDesktopInputDataChannelLabel(label string) bool {
|
||||
return label == desktopReliableInputChannelLabel || label == desktopMoveInputChannelLabel
|
||||
}
|
||||
|
||||
// StartRTPReceiver listens on local UDP port for GStreamer RTP stream and forwards to WebRTC video track
|
||||
func (w *WebRTCServer) StartRTPReceiver(port int) error {
|
||||
addr := fmt.Sprintf("127.0.0.1:%d", port)
|
||||
|
||||
15
internal/desktop/webrtc_test.go
Normal file
15
internal/desktop/webrtc_test.go
Normal file
@ -0,0 +1,15 @@
|
||||
package desktop
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestIsDesktopInputDataChannelLabelAllowsReliableAndMoveChannels(t *testing.T) {
|
||||
if !isDesktopInputDataChannelLabel(desktopReliableInputChannelLabel) {
|
||||
t.Fatalf("expected reliable input channel label to be accepted")
|
||||
}
|
||||
if !isDesktopInputDataChannelLabel(desktopMoveInputChannelLabel) {
|
||||
t.Fatalf("expected mouse move input channel label to be accepted")
|
||||
}
|
||||
if isDesktopInputDataChannelLabel("debug") {
|
||||
t.Fatalf("expected unrelated data channel label to be ignored")
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user