146 lines
6.5 KiB
HTML
146 lines
6.5 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
|
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0, user-scalable=no"/>
|
|
<title>{{title}}</title>
|
|
<link rel="icon" href="//assets.megvii.com/static%2Ffavicon.ico?ver=1498037959257">
|
|
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
|
|
<script src="//cdnjs.cloudflare.com/ajax/libs/vue/2.2.6/vue.min.js"></script>
|
|
</head>
|
|
|
|
<body>
|
|
<script language="javascript" type="text/javascript">
|
|
var vm = null;
|
|
function isCharacterKeyPress(evt) {
|
|
if (typeof evt.which == "undefined") {
|
|
// This is IE, which only fires keypress events for printable keys
|
|
return true;
|
|
} else if (typeof evt.which == "number" && evt.which > 0) {
|
|
// In other browsers except old versions of WebKit, evt.which is
|
|
// only greater than zero if the keypress is a printable key.
|
|
// We need to filter out backspace and ctrl/alt/meta key combinations
|
|
return !evt.ctrlKey && !evt.metaKey && !evt.altKey && evt.which != 8;
|
|
}
|
|
return false;
|
|
};
|
|
$(function() {
|
|
vm = new Vue({
|
|
el: '#board',
|
|
data: {
|
|
websocket: null,
|
|
// resources
|
|
delay: -1,
|
|
data_alive: null,
|
|
img_lst: null,
|
|
// network
|
|
package_size: 0,
|
|
download_time: 0,
|
|
net_speed: 0,
|
|
// timer
|
|
timer_interval: null,
|
|
timer_step: 100,
|
|
},
|
|
created: function() {
|
|
this.create_connection();
|
|
document.addEventListener("keypress", this.send_key, false);
|
|
},
|
|
computed: {
|
|
connection_alive: function() {
|
|
return (this.websocket != null) &&
|
|
!(this.websocket.readyState == this.websocket.CLOSING || this.websocket.readyState == this.websocket.CLOSED);
|
|
},
|
|
},
|
|
methods: {
|
|
get_ws_url: function(s) {
|
|
var l = window.location;
|
|
return ((l.protocol === "https:") ? "wss://" : "ws://") + l.hostname + (((l.port != 80) && (l.port != 443)) ? ":" + l.port : "") + l.pathname + s;
|
|
},
|
|
create_connection: function() {
|
|
this.websocket = new WebSocket(this.get_ws_url("stream"));
|
|
this.websocket.binaryType = "arraybuffer";
|
|
this.websocket.onopen = function(evt) { console.log("connected"); };
|
|
this.websocket.onclose = this.close_connection;
|
|
this.websocket.onerror = function(evt) { console.log("error occurred"); console.log(evt); };
|
|
this.websocket.onmessage = this.receive_message;
|
|
},
|
|
close_connection: function() {
|
|
console.log("disconnected");
|
|
this.websocket = null;
|
|
},
|
|
receive_message: function(evt) {
|
|
var obj = JSON.parse(evt.data);
|
|
var send_time = obj[0], recv_time = (new Date()).getTime() / 1000;
|
|
this.package_size = evt.data.length * 8;
|
|
this.download_time = recv_time - send_time;
|
|
this.net_speed = this.package_size / this.download_time;
|
|
console.log(obj);
|
|
this.data_alive = obj[1];
|
|
this.delay = obj[2];
|
|
this.img_lst = obj[3];
|
|
this.start_timer();
|
|
},
|
|
send_key: function(evt) {
|
|
if (!this.connection_alive || !this.data_alive) return;
|
|
if (!isCharacterKeyPress(evt)) return;
|
|
this.delay = 0;
|
|
this.data_alive = false;
|
|
var keycode = evt.keyCode;
|
|
console.log("key pressed " + keycode + " " + String.fromCharCode(keycode));
|
|
this.websocket.send(keycode);
|
|
},
|
|
update_timer: function() {
|
|
if (this.delay > 0) this.delay -= this.timer_step;
|
|
if (this.delay <= 0) {
|
|
this.data_alive = false;
|
|
if (this.timer_interval != null) {
|
|
clearInterval(this.timer_interval);
|
|
this.timer_interval = null;
|
|
}
|
|
}
|
|
},
|
|
start_timer: function() {
|
|
if (this.timer_interval != null) {
|
|
clearInterval(this.timer_interval);
|
|
this.timer_interval = null;
|
|
}
|
|
if (this.delay > 0) this.timer_interval = setInterval(this.update_timer, this.timer_step);
|
|
},
|
|
},
|
|
filters: {
|
|
decimal: function(num, fixed_point) {
|
|
return num.toFixed(fixed_point);
|
|
},
|
|
},
|
|
});
|
|
});
|
|
</script>
|
|
|
|
{% raw %}
|
|
<!-- Vue template -->
|
|
<div id="board">
|
|
<template v-if="connection_alive">
|
|
<template v-if="data_alive">
|
|
<p v-if="delay > 0">Press any key in {{delay / 1000 | decimal(1)}} seconds. </p>
|
|
<p v-else>Press any key to continue. </p>
|
|
</template>
|
|
<template v-else>
|
|
<p>Waiting for response from server. </p>
|
|
</template>
|
|
</template>
|
|
<template v-else>
|
|
<p>Disconnected from server. </p>
|
|
</template>
|
|
<p>Network: {{net_speed / 1000000 | decimal(2)}} MB/s * {{download_time | decimal(2)}} s = {{package_size / 1000000 | decimal(2)}} MB</p>
|
|
<div style="display:inline-block">
|
|
<div style="display:inline-block; vertical-align: top;" v-for="obj in img_lst">
|
|
<p>{{obj[0]}}</p>
|
|
<img :src="'data:image/png;base64,' + obj[1]" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endraw %}
|
|
|
|
</body>
|
|
</html>
|