From 65996587343089bf7e688f71bd337df301121671 Mon Sep 17 00:00:00 2001 From: exel Date: Fri, 5 Apr 2019 14:08:06 +0800 Subject: [PATCH 1/9] multi game session --- index.html | 111 +++++++++++++++++++++++++---------------------- main.go | 39 ++++++++++++----- ui/director.go | 10 ++++- ui/run.go | 5 ++- webrtc/webrtc.go | 7 +++ 5 files changed, 107 insertions(+), 65 deletions(-) diff --git a/index.html b/index.html index 582263fb..5440435a 100644 --- a/index.html +++ b/index.html @@ -10,9 +10,10 @@ textarea {

Use Up, Down, Left, Right to Move
- Space to jump
- Ctrl to sprint
- Enter to select in menu
+ Z to jump (A)
+ X to sprint (B)
+ C is start button
+ V is select button
Fullscreen media for better gaming experience
@@ -76,7 +77,6 @@ pc.ontrack = function (event) { document.getElementById('remoteVideos').appendChild(el) } -pc.oniceconnectionstatechange = e => log(pc.iceConnectionState) pc.onicecandidate = event => { if (event.candidate === null) { var session = btoa(JSON.stringify(pc.localDescription)); @@ -115,7 +115,7 @@ keyMap = { } INPUT_FPS = 100; -INPUT_STATE_PACKET = 10; +INPUT_STATE_PACKET = 5; stateUnchange = true; unchangePacket = INPUT_STATE_PACKET; @@ -137,7 +137,6 @@ document.body.onkeyup = function(e){ }; - window.startSession = () => { let sd = remoteSessionDescription if (sd === '') { @@ -145,55 +144,65 @@ window.startSession = () => { } try { - pc.setRemoteDescription(new RTCSessionDescription(JSON.parse(atob(sd))), - - // success - () => { - - setInterval(() => { - // prepare key - /* - const ( - ButtonA = iota - ButtonB - ButtonSelect - ButtonStart - ButtonUp - ButtonDown - ButtonLeft - ButtonRight - ) - */ - - if (stateUnchange || unchangePacket > 0) { - st = ""; - ["a", "b", "select", "start", "up", "down", "left", "right"].forEach(elem => { - st += keyState[elem]?1:0; - }); - ss = parseInt(st, 2); - console.log(`Key state string: ${st} ==> ${ss}`); - - // send - inputChannel.send(ss); - - stateUnchange = false; - unchangePacket--; - } - - }, 1000 / INPUT_FPS) - - - }, - - // error callback - (exp) => { - console.log("setRemoteDescription failed, we are doomed"); - console.log(exp); - }); + pc.setRemoteDescription(new RTCSessionDescription(JSON.parse(atob(sd)))); } catch (e) { alert(e); } } +var timer = null; +function sendInput() { + // prepare key + /* + const ( + ButtonA = iota + ButtonB + ButtonSelect + ButtonStart + ButtonUp + ButtonDown + ButtonLeft + ButtonRight + ) + */ + + if (stateUnchange || unchangePacket > 0) { + st = ""; + ["a", "b", "select", "start", "up", "down", "left", "right"].forEach(elem => { + st += keyState[elem]?1:0; + }); + ss = parseInt(st, 2); + console.log(`Key state string: ${st} ==> ${ss}`); + + // send + inputChannel.send(ss); + + stateUnchange = false; + unchangePacket--; + } +} + +function startInput() { + if (timer == null) { + timer = setInterval(sendInput, 1000 / INPUT_FPS) + } +} + +function endInput() { + clearInterval(timer); + timer = null; +} + +pc.oniceconnectionstatechange = e => { + log(pc.iceConnectionState); + if (pc.iceConnectionState === "connected") { + startInput(); + } + else if (pc.iceConnectionState === "disconnected") { + endInput(); + } + +} + diff --git a/main.go b/main.go index 51972086..ed71c53c 100644 --- a/main.go +++ b/main.go @@ -14,33 +14,36 @@ import ( "github.com/gorilla/mux" ) -var webRTC *webrtc.WebRTC +// var webRTC *webrtc.WebRTC var width = 256 var height = 240 var gameName = "supermariobros.rom" +var FPS = 60 func init() { } -func startGame(path string, imageChannel chan *image.RGBA, inputChannel chan int) { - ui.Run([]string{path}, imageChannel, inputChannel) +func startGame(path string, imageChannel chan *image.RGBA, inputChannel chan int, webRTC *webrtc.WebRTC) { + ui.Run([]string{path}, imageChannel, inputChannel, webRTC) } func main() { - imageChannel := make(chan *image.RGBA, 100) + // imageChannel := make(chan *image.RGBA, 100) fmt.Println("http://localhost:8000") - webRTC = webrtc.NewWebRTC() + // webRTC = webrtc.NewWebRTC() router := mux.NewRouter() router.HandleFunc("/", getWeb).Methods("GET") router.HandleFunc("/session", postSession).Methods("POST") - go http.ListenAndServe(":8000", router) + // go http.ListenAndServe(":8000", router) + http.ListenAndServe(":8000", router) // start screenshot loop, wait for connection - go screenshotLoop(imageChannel) - startGame("games/"+gameName, imageChannel, webRTC.InputChannel) - time.Sleep(time.Minute) + + // go screenshotLoop(imageChannel) + // startGame("games/"+gameName, imageChannel, webRTC.InputChannel) + // time.Sleep(time.Minute) } func getWeb(w http.ResponseWriter, r *http.Request) { @@ -58,20 +61,34 @@ func postSession(w http.ResponseWriter, r *http.Request) { } r.Body.Close() + webRTC := webrtc.NewWebRTC() + localSession, err := webRTC.StartClient(string(bs), width, height) if err != nil { log.Fatalln(err) } + imageChannel := make(chan *image.RGBA, FPS) + go screenshotLoop(imageChannel, webRTC) + go startGame("games/" + gameName, imageChannel, webRTC.InputChannel, webRTC) + w.Write([]byte(localSession)) } -func screenshotLoop(imageChannel chan *image.RGBA) { +// func screenshotLoop(imageChannel chan *image.RGBA) { +func screenshotLoop(imageChannel chan *image.RGBA, webRTC *webrtc.WebRTC) { for image := range imageChannel { + // Client stopped + if webRTC.IsClosed() { + break + } + + // encode frame if webRTC.IsConnected() { yuv := util.RgbaToYuv(image) webRTC.ImageChannel <- yuv } - time.Sleep(10 * time.Millisecond) + // time.Sleep(10 * time.Millisecond) + time.Sleep(time.Duration(1000 / FPS) * time.Millisecond) } } diff --git a/ui/director.go b/ui/director.go index a6feedb6..6afcd6f3 100644 --- a/ui/director.go +++ b/ui/director.go @@ -6,6 +6,7 @@ import ( "time" "github.com/giongto35/game-online/nes" + "github.com/giongto35/game-online/webrtc" ) type View interface { @@ -20,14 +21,16 @@ type Director struct { timestamp float64 imageChannel chan *image.RGBA inputChannel chan int + webRTC *webrtc.WebRTC } -func NewDirector(imageChannel chan *image.RGBA, inputChannel chan int) *Director { +func NewDirector(imageChannel chan *image.RGBA, inputChannel chan int, webRTC *webrtc.WebRTC) *Director { // func NewDirector(audio *Audio, imageChannel chan *image.RGBA, inputChannel chan int) *Director { director := Director{} // director.audio = audio director.imageChannel = imageChannel director.inputChannel = inputChannel + director.webRTC = webRTC return &director } @@ -61,6 +64,11 @@ func (d *Director) Start(paths []string) { func (d *Director) Run() { for { + // quit game + if d.webRTC.IsClosed() { + break + } + d.Step() } d.SetView(nil) diff --git a/ui/run.go b/ui/run.go index 5822bd28..87bea59b 100644 --- a/ui/run.go +++ b/ui/run.go @@ -6,6 +6,7 @@ import ( "runtime" // "github.com/gordonklaus/portaudio" + "github.com/giongto35/game-online/webrtc" ) const ( @@ -23,7 +24,7 @@ func init() { runtime.LockOSThread() } -func Run(paths []string, imageChannel chan *image.RGBA, inputChannel chan int) { +func Run(paths []string, imageChannel chan *image.RGBA, inputChannel chan int, webRTC *webrtc.WebRTC) { // initialize audio // portaudio.Initialize() // defer portaudio.Terminate() @@ -35,7 +36,7 @@ func Run(paths []string, imageChannel chan *image.RGBA, inputChannel chan int) { // defer audio.Stop() // run director - director := NewDirector(imageChannel, inputChannel) + director := NewDirector(imageChannel, inputChannel, webRTC) // director := NewDirector(audio, imageChannel, inputChannel) director.Start(paths) } diff --git a/webrtc/webrtc.go b/webrtc/webrtc.go index 7c56445f..095109af 100644 --- a/webrtc/webrtc.go +++ b/webrtc/webrtc.go @@ -108,6 +108,7 @@ type WebRTC struct { connection *webrtc.PeerConnection encoder *vpxEncoder.VpxEncoder isConnected bool + isClosed bool // for yuvI420 image ImageChannel chan []byte InputChannel chan int @@ -164,6 +165,7 @@ func (w *WebRTC) StartClient(remoteSession string, width, height int) (string, e w.StopClient() } }) + //w.listenInputChannel() // Data channel w.connection.OnDataChannel(func(d *webrtc.DataChannel) { @@ -210,6 +212,7 @@ func (w *WebRTC) StopClient() { w.connection.Close() } w.connection = nil + w.isClosed = true } // IsConnected comment @@ -217,6 +220,10 @@ func (w *WebRTC) IsConnected() bool { return w.isConnected } +func (w *WebRTC) IsClosed() bool { + return w.isClosed +} + func (w *WebRTC) startStreaming(vp8Track *webrtc.Track) { fmt.Println("Start streaming") // send screenshot From 1d4dc86135e67293f55e0e1e7bc7f2e696f02ae3 Mon Sep 17 00:00:00 2001 From: exel Date: Fri, 5 Apr 2019 17:58:08 +0800 Subject: [PATCH 2/9] remove sleep --- main.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/main.go b/main.go index ed71c53c..6758d16a 100644 --- a/main.go +++ b/main.go @@ -6,7 +6,7 @@ import ( "io/ioutil" "log" "net/http" - "time" + // "time" "github.com/giongto35/game-online/ui" "github.com/giongto35/game-online/util" @@ -18,7 +18,7 @@ import ( var width = 256 var height = 240 var gameName = "supermariobros.rom" -var FPS = 60 +// var FPS = 60 func init() { } @@ -68,7 +68,7 @@ func postSession(w http.ResponseWriter, r *http.Request) { log.Fatalln(err) } - imageChannel := make(chan *image.RGBA, FPS) + imageChannel := make(chan *image.RGBA, 100) go screenshotLoop(imageChannel, webRTC) go startGame("games/" + gameName, imageChannel, webRTC.InputChannel, webRTC) @@ -89,6 +89,6 @@ func screenshotLoop(imageChannel chan *image.RGBA, webRTC *webrtc.WebRTC) { webRTC.ImageChannel <- yuv } // time.Sleep(10 * time.Millisecond) - time.Sleep(time.Duration(1000 / FPS) * time.Millisecond) + // time.Sleep(time.Duration(1000 / FPS) * time.Millisecond) } } From cac8bb1a7a7d73eb9a8e0ace681e1074160c375b Mon Sep 17 00:00:00 2001 From: giongto35 Date: Fri, 5 Apr 2019 23:09:56 +0800 Subject: [PATCH 3/9] add websocket to server --- main.go | 118 ++++++++++++++++++++++++++++++++++++++--------- webrtc/webrtc.go | 31 +++++++------ 2 files changed, 115 insertions(+), 34 deletions(-) diff --git a/main.go b/main.go index 6758d16a..55efed86 100644 --- a/main.go +++ b/main.go @@ -6,20 +6,33 @@ import ( "io/ioutil" "log" "net/http" + // "time" "github.com/giongto35/game-online/ui" "github.com/giongto35/game-online/util" "github.com/giongto35/game-online/webrtc" - "github.com/gorilla/mux" + + // "github.com/gorilla/mux" + "github.com/gorilla/websocket" + + "encoding/json" ) // var webRTC *webrtc.WebRTC var width = 256 var height = 240 var gameName = "supermariobros.rom" + // var FPS = 60 +var upgrader = websocket.Upgrader{} + +type WSPacket struct { + ID string `json:"id"` + Data string `json:"data"` +} + func init() { } @@ -32,18 +45,18 @@ func main() { fmt.Println("http://localhost:8000") // webRTC = webrtc.NewWebRTC() - router := mux.NewRouter() - router.HandleFunc("/", getWeb).Methods("GET") - router.HandleFunc("/session", postSession).Methods("POST") + // router := mux.NewRouter() + // router.HandleFunc("/", getWeb).Methods("GET") + // router.HandleFunc("/session", postSession).Methods("POST") + // http.ListenAndServe(":8000", router) - // go http.ListenAndServe(":8000", router) - http.ListenAndServe(":8000", router) + // ignore origin + upgrader.CheckOrigin = func(r *http.Request) bool { return true } - // start screenshot loop, wait for connection - - // go screenshotLoop(imageChannel) - // startGame("games/"+gameName, imageChannel, webRTC.InputChannel) - // time.Sleep(time.Minute) + http.HandleFunc("/", getWeb) + http.HandleFunc("/ws", ws) + + http.ListenAndServe(":8000", nil) } func getWeb(w http.ResponseWriter, r *http.Request) { @@ -54,27 +67,90 @@ func getWeb(w http.ResponseWriter, r *http.Request) { w.Write(bs) } -func postSession(w http.ResponseWriter, r *http.Request) { - bs, err := ioutil.ReadAll(r.Body) +func ws(w http.ResponseWriter, r *http.Request) { + c, err := upgrader.Upgrade(w, r, nil) if err != nil { - log.Fatal(err) + log.Print("upgrade:", err) + return } - r.Body.Close() + defer c.Close() webRTC := webrtc.NewWebRTC() - - localSession, err := webRTC.StartClient(string(bs), width, height) + localSession, err := webRTC.StartClient(width, height) if err != nil { log.Fatalln(err) } - imageChannel := make(chan *image.RGBA, 100) - go screenshotLoop(imageChannel, webRTC) - go startGame("games/" + gameName, imageChannel, webRTC.InputChannel, webRTC) + // streaming game + // imageChannel := make(chan *image.RGBA, 100) + // go screenshotLoop(imageChannel, webRTC) + // go startGame("games/" + gameName, imageChannel, webRTC.InputChannel, webRTC) - w.Write([]byte(localSession)) + // start new games and webrtc stuff? + for { + mt, message, err := c.ReadMessage() + if err != nil { + log.Println("read:", err) + break + } + + req := WSPacket{} + err = json.Unmarshal(message, &req) + if err != nil { + log.Println("json unmarshal:", err) + break + } + log.Println(req) + + // connectivity + res := WSPacket{} + switch req.ID { + case "ping": + res.ID = "pong" + + case "sdp": + webRTC.SetRemoteSession(res.Data) + res.ID = "sdp" + res.Data = localSession + + case "candidate": + res.ID = "candidate" + } + + stRes, err := json.Marshal(res) + if err != nil { + log.Println("json marshal:", err) + } + + err = c.WriteMessage(mt, []byte(stRes)) + if err != nil { + log.Println("write:", err) + break + } + } } +// func postSession(w http.ResponseWriter, r *http.Request) { +// bs, err := ioutil.ReadAll(r.Body) +// if err != nil { +// log.Fatal(err) +// } +// r.Body.Close() + +// webRTC := webrtc.NewWebRTC() + +// localSession, err := webRTC.StartClient(string(bs), width, height) +// if err != nil { +// log.Fatalln(err) +// } + +// imageChannel := make(chan *image.RGBA, 100) +// go screenshotLoop(imageChannel, webRTC) +// go startGame("games/"+gameName, imageChannel, webRTC.InputChannel, webRTC) + +// w.Write([]byte(localSession)) +// } + // func screenshotLoop(imageChannel chan *image.RGBA) { func screenshotLoop(imageChannel chan *image.RGBA, webRTC *webrtc.WebRTC) { for image := range imageChannel { diff --git a/webrtc/webrtc.go b/webrtc/webrtc.go index 095109af..a529f0bf 100644 --- a/webrtc/webrtc.go +++ b/webrtc/webrtc.go @@ -108,14 +108,14 @@ type WebRTC struct { connection *webrtc.PeerConnection encoder *vpxEncoder.VpxEncoder isConnected bool - isClosed bool + isClosed bool // for yuvI420 image ImageChannel chan []byte InputChannel chan int } // StartClient start webrtc -func (w *WebRTC) StartClient(remoteSession string, width, height int) (string, error) { +func (w *WebRTC) StartClient(width, height int) (string, error) { defer func() { if err := recover(); err != nil { fmt.Println(err) @@ -151,6 +151,7 @@ func (w *WebRTC) StartClient(remoteSession string, width, height int) (string, e return "", err } + // WebRTC state callback w.connection.OnICEConnectionStateChange(func(connectionState webrtc.ICEConnectionState) { fmt.Printf("ICE Connection State has changed: %s\n", connectionState.String()) if connectionState == webrtc.ICEConnectionStateConnected { @@ -166,8 +167,7 @@ func (w *WebRTC) StartClient(remoteSession string, width, height int) (string, e } }) - //w.listenInputChannel() - // Data channel + // Data channel callback w.connection.OnDataChannel(func(d *webrtc.DataChannel) { fmt.Printf("New DataChannel %s %d\n", d.Label(), d.ID()) @@ -184,23 +184,28 @@ func (w *WebRTC) StartClient(remoteSession string, width, height int) (string, e }) }) - offer := webrtc.SessionDescription{} - Decode(remoteSession, &offer) - if err != nil { - return "", err - } - err = w.connection.SetRemoteDescription(offer) - if err != nil { - return "", err - } answer, err := w.connection.CreateAnswer(nil) if err != nil { return "", err } + localSession := Encode(answer) return localSession, nil } +func (w *WebRTC) SetRemoteSession(remoteSession string) error { + offer := webrtc.SessionDescription{} + + Decode(remoteSession, &offer) + + err := w.connection.SetRemoteDescription(offer) + if err != nil { + return err + } + + return nil +} + // StopClient disconnect func (w *WebRTC) StopClient() { fmt.Println("===StopClient===") From 26d2fe61629099ee88934f37f3878ef32816e0ed Mon Sep 17 00:00:00 2001 From: giongto35 Date: Fri, 5 Apr 2019 23:10:37 +0800 Subject: [PATCH 4/9] zz --- main.go | 1 + 1 file changed, 1 insertion(+) diff --git a/main.go b/main.go index 55efed86..a198407d 100644 --- a/main.go +++ b/main.go @@ -128,6 +128,7 @@ func ws(w http.ResponseWriter, r *http.Request) { break } } + } // func postSession(w http.ResponseWriter, r *http.Request) { From 50d56209954768636506624e0e1a557003e76203 Mon Sep 17 00:00:00 2001 From: giongto35 Date: Fri, 5 Apr 2019 23:13:44 +0800 Subject: [PATCH 5/9] yy --- main.go | 1 - 1 file changed, 1 deletion(-) diff --git a/main.go b/main.go index a198407d..55efed86 100644 --- a/main.go +++ b/main.go @@ -128,7 +128,6 @@ func ws(w http.ResponseWriter, r *http.Request) { break } } - } // func postSession(w http.ResponseWriter, r *http.Request) { From 721826c9b6aa38f08e6840cda82e7272e43f216b Mon Sep 17 00:00:00 2001 From: giongto35 Date: Fri, 5 Apr 2019 23:20:12 +0800 Subject: [PATCH 6/9] add brilliant code --- main.go | 1 + 1 file changed, 1 insertion(+) diff --git a/main.go b/main.go index 55efed86..428c3a4d 100644 --- a/main.go +++ b/main.go @@ -127,6 +127,7 @@ func ws(w http.ResponseWriter, r *http.Request) { log.Println("write:", err) break } + } } From 1398a7d3ab58fdec2acdea7aba77515e6f63f78f Mon Sep 17 00:00:00 2001 From: giongto35 Date: Fri, 5 Apr 2019 23:37:20 +0800 Subject: [PATCH 7/9] Good repo --- index.html | 132 ++++++++++++++++++++++++++++++++++------------------- main.go | 3 ++ 2 files changed, 87 insertions(+), 48 deletions(-) diff --git a/index.html b/index.html index 5440435a..46ade8a8 100644 --- a/index.html +++ b/index.html @@ -26,9 +26,36 @@ textarea { diff --git a/main.go b/main.go index 428c3a4d..f514176a 100644 --- a/main.go +++ b/main.go @@ -75,12 +75,15 @@ func ws(w http.ResponseWriter, r *http.Request) { } defer c.Close() + log.Println("new connection") webRTC := webrtc.NewWebRTC() localSession, err := webRTC.StartClient(width, height) if err != nil { log.Fatalln(err) } + log.Println("new connection2") + // streaming game // imageChannel := make(chan *image.RGBA, 100) // go screenshotLoop(imageChannel, webRTC) From 80b6e62cb8a3a02ed07304f3c2d3e4a5f6fc708d Mon Sep 17 00:00:00 2001 From: giongto35 Date: Sat, 6 Apr 2019 00:20:04 +0800 Subject: [PATCH 8/9] Revert "Good repo" This reverts commit a278fb4cd9901775f9ff5263abde07f26779c2e1. --- index.html | 132 +++++++++++++++++++---------------------------------- main.go | 3 -- 2 files changed, 48 insertions(+), 87 deletions(-) diff --git a/index.html b/index.html index 46ade8a8..5440435a 100644 --- a/index.html +++ b/index.html @@ -26,36 +26,9 @@ textarea { diff --git a/main.go b/main.go index f514176a..428c3a4d 100644 --- a/main.go +++ b/main.go @@ -75,15 +75,12 @@ func ws(w http.ResponseWriter, r *http.Request) { } defer c.Close() - log.Println("new connection") webRTC := webrtc.NewWebRTC() localSession, err := webRTC.StartClient(width, height) if err != nil { log.Fatalln(err) } - log.Println("new connection2") - // streaming game // imageChannel := make(chan *image.RGBA, 100) // go screenshotLoop(imageChannel, webRTC) From 9414f3f67a2a96492423c0a707a93254b3b1104e Mon Sep 17 00:00:00 2001 From: giongto35 Date: Sat, 6 Apr 2019 00:23:51 +0800 Subject: [PATCH 9/9] Remove websocket --- main.go | 115 +++++++++-------------------------------------- webrtc/webrtc.go | 31 ++++++------- 2 files changed, 33 insertions(+), 113 deletions(-) diff --git a/main.go b/main.go index 428c3a4d..fef5222b 100644 --- a/main.go +++ b/main.go @@ -12,11 +12,7 @@ import ( "github.com/giongto35/game-online/ui" "github.com/giongto35/game-online/util" "github.com/giongto35/game-online/webrtc" - - // "github.com/gorilla/mux" - "github.com/gorilla/websocket" - - "encoding/json" + "github.com/gorilla/mux" ) // var webRTC *webrtc.WebRTC @@ -26,13 +22,6 @@ var gameName = "supermariobros.rom" // var FPS = 60 -var upgrader = websocket.Upgrader{} - -type WSPacket struct { - ID string `json:"id"` - Data string `json:"data"` -} - func init() { } @@ -45,18 +34,18 @@ func main() { fmt.Println("http://localhost:8000") // webRTC = webrtc.NewWebRTC() - // router := mux.NewRouter() - // router.HandleFunc("/", getWeb).Methods("GET") - // router.HandleFunc("/session", postSession).Methods("POST") - // http.ListenAndServe(":8000", router) + router := mux.NewRouter() + router.HandleFunc("/", getWeb).Methods("GET") + router.HandleFunc("/session", postSession).Methods("POST") - // ignore origin - upgrader.CheckOrigin = func(r *http.Request) bool { return true } + // go http.ListenAndServe(":8000", router) + http.ListenAndServe(":8000", router) - http.HandleFunc("/", getWeb) - http.HandleFunc("/ws", ws) + // start screenshot loop, wait for connection - http.ListenAndServe(":8000", nil) + // go screenshotLoop(imageChannel) + // startGame("games/"+gameName, imageChannel, webRTC.InputChannel) + // time.Sleep(time.Minute) } func getWeb(w http.ResponseWriter, r *http.Request) { @@ -67,91 +56,27 @@ func getWeb(w http.ResponseWriter, r *http.Request) { w.Write(bs) } -func ws(w http.ResponseWriter, r *http.Request) { - c, err := upgrader.Upgrade(w, r, nil) +func postSession(w http.ResponseWriter, r *http.Request) { + bs, err := ioutil.ReadAll(r.Body) if err != nil { - log.Print("upgrade:", err) - return + log.Fatal(err) } - defer c.Close() + r.Body.Close() webRTC := webrtc.NewWebRTC() - localSession, err := webRTC.StartClient(width, height) + + localSession, err := webRTC.StartClient(string(bs), width, height) if err != nil { log.Fatalln(err) } - // streaming game - // imageChannel := make(chan *image.RGBA, 100) - // go screenshotLoop(imageChannel, webRTC) - // go startGame("games/" + gameName, imageChannel, webRTC.InputChannel, webRTC) + imageChannel := make(chan *image.RGBA, 100) + go screenshotLoop(imageChannel, webRTC) + go startGame("games/"+gameName, imageChannel, webRTC.InputChannel, webRTC) - // start new games and webrtc stuff? - for { - mt, message, err := c.ReadMessage() - if err != nil { - log.Println("read:", err) - break - } - - req := WSPacket{} - err = json.Unmarshal(message, &req) - if err != nil { - log.Println("json unmarshal:", err) - break - } - log.Println(req) - - // connectivity - res := WSPacket{} - switch req.ID { - case "ping": - res.ID = "pong" - - case "sdp": - webRTC.SetRemoteSession(res.Data) - res.ID = "sdp" - res.Data = localSession - - case "candidate": - res.ID = "candidate" - } - - stRes, err := json.Marshal(res) - if err != nil { - log.Println("json marshal:", err) - } - - err = c.WriteMessage(mt, []byte(stRes)) - if err != nil { - log.Println("write:", err) - break - } - - } + w.Write([]byte(localSession)) } -// func postSession(w http.ResponseWriter, r *http.Request) { -// bs, err := ioutil.ReadAll(r.Body) -// if err != nil { -// log.Fatal(err) -// } -// r.Body.Close() - -// webRTC := webrtc.NewWebRTC() - -// localSession, err := webRTC.StartClient(string(bs), width, height) -// if err != nil { -// log.Fatalln(err) -// } - -// imageChannel := make(chan *image.RGBA, 100) -// go screenshotLoop(imageChannel, webRTC) -// go startGame("games/"+gameName, imageChannel, webRTC.InputChannel, webRTC) - -// w.Write([]byte(localSession)) -// } - // func screenshotLoop(imageChannel chan *image.RGBA) { func screenshotLoop(imageChannel chan *image.RGBA, webRTC *webrtc.WebRTC) { for image := range imageChannel { diff --git a/webrtc/webrtc.go b/webrtc/webrtc.go index a529f0bf..095109af 100644 --- a/webrtc/webrtc.go +++ b/webrtc/webrtc.go @@ -108,14 +108,14 @@ type WebRTC struct { connection *webrtc.PeerConnection encoder *vpxEncoder.VpxEncoder isConnected bool - isClosed bool + isClosed bool // for yuvI420 image ImageChannel chan []byte InputChannel chan int } // StartClient start webrtc -func (w *WebRTC) StartClient(width, height int) (string, error) { +func (w *WebRTC) StartClient(remoteSession string, width, height int) (string, error) { defer func() { if err := recover(); err != nil { fmt.Println(err) @@ -151,7 +151,6 @@ func (w *WebRTC) StartClient(width, height int) (string, error) { return "", err } - // WebRTC state callback w.connection.OnICEConnectionStateChange(func(connectionState webrtc.ICEConnectionState) { fmt.Printf("ICE Connection State has changed: %s\n", connectionState.String()) if connectionState == webrtc.ICEConnectionStateConnected { @@ -167,7 +166,8 @@ func (w *WebRTC) StartClient(width, height int) (string, error) { } }) - // Data channel callback + //w.listenInputChannel() + // Data channel w.connection.OnDataChannel(func(d *webrtc.DataChannel) { fmt.Printf("New DataChannel %s %d\n", d.Label(), d.ID()) @@ -184,28 +184,23 @@ func (w *WebRTC) StartClient(width, height int) (string, error) { }) }) + offer := webrtc.SessionDescription{} + Decode(remoteSession, &offer) + if err != nil { + return "", err + } + err = w.connection.SetRemoteDescription(offer) + if err != nil { + return "", err + } answer, err := w.connection.CreateAnswer(nil) if err != nil { return "", err } - localSession := Encode(answer) return localSession, nil } -func (w *WebRTC) SetRemoteSession(remoteSession string) error { - offer := webrtc.SessionDescription{} - - Decode(remoteSession, &offer) - - err := w.connection.SetRemoteDescription(offer) - if err != nil { - return err - } - - return nil -} - // StopClient disconnect func (w *WebRTC) StopClient() { fmt.Println("===StopClient===")