diff --git a/pkg/api/api.go b/pkg/api/api.go index 9dfdabdf..89d0628a 100644 --- a/pkg/api/api.go +++ b/pkg/api/api.go @@ -70,9 +70,7 @@ const ( CheckLatency PT = 3 InitSession PT = 4 InitWebrtcStream PT = 100 - WebrtcOffer PT = 101 - WebrtcAnswer PT = 102 - WebrtcIce PT = 103 + WebrtcSignal PT = 101 StartGame PT = 104 QuitGame PT = 105 SaveGame PT = 106 @@ -84,7 +82,6 @@ const ( ResetGame PT = 113 RegisterRoom PT = 201 CloseRoom PT = 202 - IceCandidate = WebrtcIce TerminateSession PT = 204 AppVideoChange PT = 150 LibNewGameList PT = 205 @@ -99,12 +96,8 @@ func (p PT) String() string { return "InitSession" case InitWebrtcStream: return "InitWebrtcStream" - case WebrtcOffer: - return "WebrtcOffer" - case WebrtcAnswer: - return "WebrtcAnswer" - case WebrtcIce: - return "WebrtcIce" + case WebrtcSignal: + return "WebrtcSignal" case StartGame: return "StartGame" case ChangePlayer: diff --git a/pkg/api/user.go b/pkg/api/user.go index bccecbe3..e487b93c 100644 --- a/pkg/api/user.go +++ b/pkg/api/user.go @@ -31,9 +31,10 @@ type ( Title string `json:"title"` System string `json:"system"` } - WebrtcAnswerUserRequest string - WebrtcUserIceCandidate string - + WebrtcSignalUser struct { + Ice *string `json:"ice,omitempty"` + Sdp *string `json:"sdp,omitempty"` + } InitUserWebrtcStreamRequest struct { Initiator bool `json:"initiator"` Sdp string `json:"sdp,omitempty"` diff --git a/pkg/api/worker.go b/pkg/api/worker.go index a187e78a..d933c8ea 100644 --- a/pkg/api/worker.go +++ b/pkg/api/worker.go @@ -41,13 +41,10 @@ type ( } RecordGameResponse string TerminateSessionRequest Stateful - WebrtcAnswerRequest struct { + WebrtcSignalRequest struct { Stateful - Sdp string `json:"sdp"` - } - WebrtcIceCandidateRequest struct { - Stateful - Candidate string `json:"candidate"` + Sdp *string `json:"sdp,omitempty"` + Ice *string `json:"ice,omitempty"` } InitWebrtcStreamRequest struct { // Stateful diff --git a/pkg/coordinator/user.go b/pkg/coordinator/user.go index 3d630faa..923aeff3 100644 --- a/pkg/coordinator/user.go +++ b/pkg/coordinator/user.go @@ -48,10 +48,8 @@ func (u *User) HandleRequests(info HasServerInfo, conf config.CoordinatorConfig) switch x.T { case api.InitWebrtcStream: err = api.Do(x, u.HandleInitWebrtcStream) - case api.WebrtcAnswer: - err = api.Do(x, u.HandleWebrtcAnswer) - case api.WebrtcIce: - err = api.Do(x, u.HandleWebrtcIceCandidate) + case api.WebrtcSignal: + err = api.Do(x, u.HandleWebrtcSignal) case api.StartGame: err = api.Do(x, func(d api.GameStartUserRequest) { u.HandleStartGame(d, conf) }) case api.QuitGame: diff --git a/pkg/coordinator/userapi.go b/pkg/coordinator/userapi.go index fd8b7235..6da571b5 100644 --- a/pkg/coordinator/userapi.go +++ b/pkg/coordinator/userapi.go @@ -27,10 +27,14 @@ func (u *User) InitSession(wid string, ice []config.IceServer, games []api.AppMe } // SendWebrtcOffer sends SDP offer back to the user. -func (u *User) SendWebrtcOffer(sdp string) { u.Notify(api.WebrtcOffer, sdp) } +func (u *User) SendWebrtcOffer(sdp string) { + u.Notify(api.WebrtcSignal, api.WebrtcSignalUser{Sdp: &sdp}) +} // SendWebrtcIceCandidate sends remote ICE candidate back to the user. -func (u *User) SendWebrtcIceCandidate(candidate string) { u.Notify(api.WebrtcIce, candidate) } +func (u *User) SendWebrtcIceCandidate(candidate string) { + u.Notify(api.WebrtcSignal, api.WebrtcSignalUser{Ice: &candidate}) +} // StartGame signals the user that everything is ready to start a game. func (u *User) StartGame(av *api.AppVideoInfo, kbMouse bool) { diff --git a/pkg/coordinator/userhandlers.go b/pkg/coordinator/userhandlers.go index 7bab2217..f8ba4d61 100644 --- a/pkg/coordinator/userhandlers.go +++ b/pkg/coordinator/userhandlers.go @@ -21,12 +21,8 @@ func (u *User) HandleInitWebrtcStream(rq api.InitUserWebrtcStreamRequest) { u.SendWebrtcOffer(string(*resp)) } -func (u *User) HandleWebrtcAnswer(rq api.WebrtcAnswerUserRequest) { - u.w.WebrtcAnswer(u.Id().String(), string(rq)) -} - -func (u *User) HandleWebrtcIceCandidate(rq api.WebrtcUserIceCandidate) { - u.w.WebrtcIceCandidate(u.Id().String(), string(rq)) +func (u *User) HandleWebrtcSignal(rq api.WebrtcSignalUser) { + u.w.WebrtcSignal(u.Id().String(), rq.Sdp, rq.Ice) } func (u *User) HandleStartGame(rq api.GameStartUserRequest, conf config.CoordinatorConfig) { diff --git a/pkg/coordinator/worker.go b/pkg/coordinator/worker.go index 137d7777..6770af3a 100644 --- a/pkg/coordinator/worker.go +++ b/pkg/coordinator/worker.go @@ -85,9 +85,12 @@ func (w *Worker) HandleRequests(users HasUserRegistry) chan struct{} { }) case api.CloseRoom: err = api.Do(p, w.HandleCloseRoom) - case api.IceCandidate: - err = api.DoE(p, func(d api.WebrtcIceCandidateRequest) error { - return w.HandleIceCandidate(d, users) + case api.WebrtcSignal: + err = api.DoE(p, func(rq api.WebrtcSignalRequest) error { + if rq.Ice == nil { + return fmt.Errorf("ice candidate is missing") + } + return w.HandleIceCandidate(rq, users) }) case api.LibNewGameList: err = api.DoE(p, w.HandleLibGameList) diff --git a/pkg/coordinator/workerapi.go b/pkg/coordinator/workerapi.go index 09bd9f3b..dbceaed4 100644 --- a/pkg/coordinator/workerapi.go +++ b/pkg/coordinator/workerapi.go @@ -7,14 +7,10 @@ func (w *Worker) InitWebrtcStream(id string, initiator bool, sdp string) (*api.I w.Send(api.InitWebrtcStream, api.InitWebrtcStreamRequest{Id: id, Initiator: initiator, Sdp: sdp})) } -func (w *Worker) WebrtcAnswer(id string, sdp string) { - w.Notify(api.WebrtcAnswer, - api.WebrtcAnswerRequest{Stateful: api.Stateful{Id: id}, Sdp: sdp}) -} - -func (w *Worker) WebrtcIceCandidate(id string, candidate string) { - w.Notify(api.WebrtcIce, - api.WebrtcIceCandidateRequest{Stateful: api.Stateful{Id: id}, Candidate: candidate}) +func (w *Worker) WebrtcSignal(id string, sdp, ice *string) { + w.Notify(api.WebrtcSignal, api.WebrtcSignalRequest{ + Stateful: api.Stateful{Id: id}, Ice: ice, Sdp: sdp, + }) } func (w *Worker) StartGame(id string, req api.GameStartUserRequest) (*api.StartGameResponse, error) { diff --git a/pkg/coordinator/workerhandlers.go b/pkg/coordinator/workerhandlers.go index 35609e06..84dd0ee1 100644 --- a/pkg/coordinator/workerhandlers.go +++ b/pkg/coordinator/workerhandlers.go @@ -11,9 +11,9 @@ func (w *Worker) HandleCloseRoom(rq api.CloseRoomRequest) { } } -func (w *Worker) HandleIceCandidate(rq api.WebrtcIceCandidateRequest, users HasUserRegistry) error { +func (w *Worker) HandleIceCandidate(rq api.WebrtcSignalRequest, users HasUserRegistry) error { if usr := users.Find(rq.Id); usr != nil { - usr.SendWebrtcIceCandidate(rq.Candidate) + usr.SendWebrtcIceCandidate(*rq.Ice) } else { w.log.Warn().Str("id", rq.Id).Msg("unknown session") } diff --git a/pkg/worker/coordinator.go b/pkg/worker/coordinator.go index 547cbf51..2840a0e4 100644 --- a/pkg/worker/coordinator.go +++ b/pkg/worker/coordinator.go @@ -84,10 +84,8 @@ func (c *coordinator) HandleRequests(w *Worker) chan struct{} { err = api.Do(x, func(d api.ChangePlayerRequest) { out = c.HandleChangePlayer(d, w) }) case api.RecordGame: err = api.Do(x, func(d api.RecordGameRequest) { out = c.HandleRecordGame(d, w) }) - case api.WebrtcAnswer: - err = api.Do(x, func(d api.WebrtcAnswerRequest) { c.HandleWebrtcAnswer(d, w) }) - case api.WebrtcIce: - err = api.Do(x, func(d api.WebrtcIceCandidateRequest) { c.HandleWebrtcIceCandidate(d, w) }) + case api.WebrtcSignal: + err = api.Do(x, func(d api.WebrtcSignalRequest) { c.HandleWebrtcSignal(d, w) }) case api.TerminateSession: err = api.Do(x, func(d api.TerminateSessionRequest) { c.HandleTerminateSession(d, w) }) case api.QuitGame: @@ -110,9 +108,9 @@ func (c *coordinator) RegisterRoom(id string) { c.Notify(api.RegisterRoom, id) } // CloseRoom sends a signal to coordinator which will remove that room from its list. func (c *coordinator) CloseRoom(id string) { c.Notify(api.CloseRoom, id) } func (c *coordinator) IceCandidate(candidate string, sessionId string) { - c.Notify(api.WebrtcIce, api.WebrtcIceCandidateRequest{ - Stateful: api.Stateful{Id: sessionId}, - Candidate: candidate, + c.Notify(api.WebrtcSignal, api.WebrtcSignalRequest{ + Stateful: api.Stateful{Id: sessionId}, + Ice: &candidate, }) } diff --git a/pkg/worker/coordinatorhandlers.go b/pkg/worker/coordinatorhandlers.go index c00fd3d6..8699203d 100644 --- a/pkg/worker/coordinatorhandlers.go +++ b/pkg/worker/coordinatorhandlers.go @@ -72,18 +72,22 @@ func (c *coordinator) HandleInitWebrtcStream(rq api.InitWebrtcStreamRequest, w * return api.Out{Payload: sdp} } -func (c *coordinator) HandleWebrtcAnswer(rq api.WebrtcAnswerRequest, w *Worker) { - if user := w.router.FindUser(rq.Id); user != nil { - if err := room.WithWebRTC(user.Session).SetRemoteSDP(rq.Sdp, fromJson); err != nil { +func (c *coordinator) HandleWebrtcSignal(rq api.WebrtcSignalRequest, w *Worker) { + user := w.router.FindUser(rq.Id) + + if user == nil { + return + } + + if rq.Sdp != nil { + if err := room.WithWebRTC(user.Session).SetRemoteSDP(*rq.Sdp, fromJson); err != nil { c.log.Error().Err(err).Msgf("cannot set remote SDP of client [%v]", rq.Id) } } -} -func (c *coordinator) HandleWebrtcIceCandidate(rs api.WebrtcIceCandidateRequest, w *Worker) { - if user := w.router.FindUser(rs.Id); user != nil { - if err := room.WithWebRTC(user.Session).AddCandidate(rs.Candidate, fromJson); err != nil { - c.log.Error().Err(err).Msgf("cannot add ICE candidate of the client [%v]", rs.Id) + if rq.Ice != nil { + if err := room.WithWebRTC(user.Session).AddCandidate(*rq.Ice, fromJson); err != nil { + c.log.Error().Err(err).Msgf("cannot add ICE candidate of the client [%v]", rq.Id) } } } diff --git a/web/js/api.js b/web/js/api.js index 018b4d1e..6b4ec06d 100755 --- a/web/js/api.js +++ b/web/js/api.js @@ -4,9 +4,7 @@ const endpoints = { LATENCY_CHECK: 3, INIT: 4, INIT_WEBRTC_STREAM: 100, - OFFER: 101, - ANSWER: 102, - ICE_CANDIDATE: 103, + WEBRTC_SIGNAL: 101, GAME_START: 104, GAME_QUIT: 105, GAME_SAVE: 106, @@ -347,8 +345,8 @@ export const api = { ...(sdpOffer && { sdp: toJson(sdpOffer) }), }), sendIceCandidate: (candidate) => - packet(endpoints.ICE_CANDIDATE, toJson(candidate)), - sendSdp: (sdp) => packet(endpoints.ANSWER, toJson(sdp)), + packet(endpoints.WEBRTC_SIGNAL, { ice: toJson(candidate) }), + sendSdp: (sdp) => packet(endpoints.WEBRTC_SIGNAL, { sdp: toJson(sdp) }), latencyCheck: (id, list) => packet(endpoints.LATENCY_CHECK, list, id), getWorkerList: () => packet(endpoints.GET_WORKER_LIST), }, diff --git a/web/js/app.js b/web/js/app.js index 5f684f9b..f5cc9029 100755 --- a/web/js/app.js +++ b/web/js/app.js @@ -184,11 +184,17 @@ const onMessage = (m) => { const initiator = !options.webrtcWaitOffer; handleWebrtcStart({ data: payload, initiator }); break; - case api.endpoint.OFFER: - webrtc.answer(api.fromJson(payload)); - break; - case api.endpoint.ICE_CANDIDATE: - webrtc.candidate(payload ? api.fromJson(payload) : ""); + case api.endpoint.WEBRTC_SIGNAL: + const data = payload; + // it is eaither sdp or ice + if (Object.hasOwn(data, "ice")) { + webrtc.candidate(data.ice ? api.fromJson(data.ice) : ""); + return; + } + if (Object.hasOwn(data, "sdp")) { + webrtc.answer(api.fromJson(data.sdp)); + return; + } break; case api.endpoint.GAME_START: if (payload.av) pub(APP_VIDEO_CHANGED, payload.av);