mirror of
https://github.com/giongto35/cloud-game.git
synced 2026-07-18 00:55:40 +00:00
Unify all WebRTC signaling in the API
Users, workers, and the coordinator will now send WebRTC signaling
information through a single API endpoint with a unified structure. The
payload should contain either an sdp or ice field for further processing
by the designated handlers.
Replaced API endpoints:
- (101) WebrtcOffer -> WebrtcSignal
Removed API endpoints:
- WebrtcAnswer (102)
- WebrtcIce (103)
This commit is contained in:
parent
f72202684f
commit
a4b4e0458f
13 changed files with 63 additions and 69 deletions
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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"`
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
},
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue