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===")