Skip to content
This repository has been archived by the owner on May 27, 2024. It is now read-only.

Commit

Permalink
use the new method for HTTP:/minicap
Browse files Browse the repository at this point in the history
  • Loading branch information
codeskyblue committed Mar 16, 2020
1 parent 19a5604 commit 67e2e24
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 78 deletions.
44 changes: 42 additions & 2 deletions assets/remote.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@
<div id="app">
<h3>极简手机远程控制 <small style="color: gray" v-text="message"></small></h3>
<div style="margin: 5px 0px">
<button @click="refreshImg">刷新画面</button>
<span style="background-color:blueviolet; color:whilte" v-show="readonly">ReadOnly</span>
<button @click="refreshImg">刷新画面 fps: <span v-text="fps.toFixed(1)"></span></button>
<button @click="keyevent('HOME')">HOME</button>
<input v-model="command" placeholder="shell command" v-on:keyup.enter="runCommand">
</div>
<div>
<img ref="display" style="border: 1px solid blue;" />
Expand Down Expand Up @@ -109,6 +112,10 @@ <h3>极简手机远程控制 <small style="color: gray" v-text="message"></small
canvas: null,
img: null,
rotation: 0,
command: "",
readonly: true,
fps: 0,
periodImageCount: 0,
},
mounted() {
const img = this.img = this.$refs.display
Expand All @@ -121,8 +128,37 @@ <h3>极简手机远程控制 <small style="color: gray" v-text="message"></small
// }
this.syncDisplay()
this.syncTouchpad()

// calculate fps
setInterval(()=>{
this.fps = this.periodImageCount / 0.5
this.periodImageCount = 0
}, 500)
},
methods: {
keyevent(key) {
return $.ajax({
url: "/shell",
method: "post",
data: {
command: "input keyevent " + key,
}
})
},
runCommand() {
return $.ajax({
url: "/shell",
method: "post",
data: {
command: this.command,
},
dataType: "json",
}).then((resp) => {
console.log(this.command + ": " + resp.output)
this.command = ""
alert(resp.output)
})
},
refreshImg() {
this.notify("image loading ...")
this.img.src = `http://${location.host}/screenshot?t=${new Date().getTime()}`
Expand Down Expand Up @@ -169,6 +205,7 @@ <h3>极简手机远程控制 <small style="color: gray" v-text="message"></small
let ws = new WebSocket("ws://" + location.host + "/minitouch")

ws.onopen = (ret) => {
this.readonly = false
console.log("minitouch connected")
ws.send(JSON.stringify({ // touch reset, fix when device is outof control
operation: "r",
Expand All @@ -180,13 +217,15 @@ <h3>极简手机远程控制 <small style="color: gray" v-text="message"></small
}

ws.onclose = () => {
this.readonly = true
console.log("minitouch closed")
element.removeEventListener("mousedown", mouseDownListener)
this.notify("minitouch closed")
}
},
syncDisplay(canvas) {
let ws = new WebSocket('ws://' + location.host + "/minicap/broadcast")
let ws = new WebSocket('ws://' + location.host + "/minicap")

ws.onclose = () => {
var warn = document.createElement("div")
warn.innerText = "Websocket closed, Refresh to reload."
Expand All @@ -199,6 +238,7 @@ <h3>极简手机远程控制 <small style="color: gray" v-text="message"></small
}
ws.onmessage = (message) => {
if (message.data instanceof Blob) {
this.periodImageCount += 1 // help for calculate fps
let blob = new Blob([message.data], {
type: 'image/jpeg'
})
Expand Down
79 changes: 3 additions & 76 deletions httpserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -965,82 +965,9 @@ func (server *Server) initHTTPServer() {
}
}).Methods("PUT")

m.HandleFunc("/minicap/broadcast", broadcastWebsocket()).Methods("GET")

m.HandleFunc("/minicap", singleFightNewerWebsocket(func(w http.ResponseWriter, r *http.Request, ws *websocket.Conn) {
ctx := r.Context()
defer ws.Close()

const wsWriteWait = 10 * time.Second
wsWrite := func(messageType int, data []byte) error {
ws.SetWriteDeadline(time.Now().Add(wsWriteWait))
return ws.WriteMessage(messageType, data)
}
wsWrite(websocket.TextMessage, []byte("restart @minicap service"))
if err := service.Restart("minicap"); err != nil && err != cmdctrl.ErrAlreadyRunning {
wsWrite(websocket.TextMessage, []byte("@minicap service start failed: "+err.Error()))
return
}

wsWrite(websocket.TextMessage, []byte("dial unix:@minicap"))
log.Printf("minicap connection: %v", r.RemoteAddr)
dataC := make(chan []byte, 10)

go func() {
defer close(dataC)
retries := 0
for {
if retries > 10 {
log.Println("unix @minicap connect failed")
dataC <- []byte("@minicap listen timeout, possibly minicap not installed")
break
}
conn, err := net.Dial("unix", "@minicap")
if err != nil {
retries++
log.Printf("dial @minicap err: %v, wait 0.5s", err)
select {
case <-ctx.Done():
return
case <-time.After(500 * time.Millisecond):
}
continue
}
dataC <- []byte("rotation " + strconv.Itoa(deviceRotation))
retries = 0 // connected, reset retries
if er := translateMinicap(conn, dataC, ctx); er == nil {
conn.Close()
log.Println("transfer closed")
break
} else {
conn.Close()
log.Println("minicap read error, try to read again")
}
}
}()
go func() {
for {
if _, _, err := ws.ReadMessage(); err != nil {
break
}
}
}()
for data := range dataC {
if string(data[:2]) == "\xff\xd8" { // jpeg data
if err := wsWrite(websocket.BinaryMessage, data); err != nil {
break
}
if err := wsWrite(websocket.TextMessage, []byte("data size: "+strconv.Itoa(len(data)))); err != nil {
break
}
} else {
if err := wsWrite(websocket.TextMessage, data); err != nil {
break
}
}
}
log.Println("stream finished")
})).Methods("GET")
minicapHandler := broadcastWebsocket()
m.HandleFunc("/minicap/broadcast", minicapHandler).Methods("GET")
m.HandleFunc("/minicap", minicapHandler).Methods("GET")

// TODO(ssx): perfer to delete
// FIXME(ssx): screenrecord is not good enough, need to change later
Expand Down

0 comments on commit 67e2e24

Please sign in to comment.