mirror of
https://github.com/lwch/natpass.git
synced 2024-04-21 12:41:54 +00:00
增加流量统计和dashboard页面
This commit is contained in:
@@ -68,7 +68,7 @@ func (v *VNC) remoteRead(ctx context.Context, ch <-chan *network.Msg, local *web
|
||||
case network.Msg_vnc_image:
|
||||
data, err := decodeImage(msg.GetVimg())
|
||||
runtime.Assert(err)
|
||||
replyImage(local, msg.GetVimg(), data)
|
||||
replyImage(local, msg.GetVimg(), data, len(msg.GetVimg().GetData()))
|
||||
default:
|
||||
logging.Error("on message: %s", msg.GetXType().String())
|
||||
return
|
||||
@@ -142,15 +142,16 @@ func dumpImage(img image.Image) {
|
||||
}
|
||||
}
|
||||
|
||||
func replyImage(conn *websocket.Conn, msg *network.VncImage, data []byte) {
|
||||
func replyImage(conn *websocket.Conn, msg *network.VncImage, data []byte, srcSize int) {
|
||||
info := msg.GetXInfo()
|
||||
buf := make([]byte, len(data)+24)
|
||||
buf := make([]byte, len(data)+28)
|
||||
binary.BigEndian.PutUint32(buf, info.GetScreenWidth())
|
||||
binary.BigEndian.PutUint32(buf[4:], info.GetScreenHeight())
|
||||
binary.BigEndian.PutUint32(buf[8:], info.GetRectX())
|
||||
binary.BigEndian.PutUint32(buf[12:], info.GetRectY())
|
||||
binary.BigEndian.PutUint32(buf[16:], info.GetRectWidth())
|
||||
binary.BigEndian.PutUint32(buf[20:], info.GetRectHeight())
|
||||
copy(buf[24:], data)
|
||||
binary.BigEndian.PutUint32(buf[24:], uint32(srcSize))
|
||||
copy(buf[28:], data)
|
||||
conn.WriteMessage(websocket.BinaryMessage, buf)
|
||||
}
|
||||
|
||||
@@ -38,6 +38,7 @@ var page = {
|
||||
<a href="https://${location.hostname}:${tunnel.port}" target="_blank">https</a>`;
|
||||
break;
|
||||
case 'shell':
|
||||
case 'vnc':
|
||||
op = `<a href="http://${location.host}/terminal.html?name=${tunnel.name}" target="_blank">连接</a>`;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -14,7 +14,8 @@ var page = {
|
||||
$.get('/api/tunnels', function(ret) {
|
||||
$('#terms').empty();
|
||||
$.each(ret, function(_, tunnel) {
|
||||
if (tunnel.type != 'shell') {
|
||||
if (tunnel.type != 'shell' &&
|
||||
tunnel.type != 'vnc') {
|
||||
return;
|
||||
}
|
||||
$('#terms').append($(`<option value="${tunnel.port}">${tunnel.name}</option>`));
|
||||
@@ -44,7 +45,7 @@ var page = {
|
||||
var str = `
|
||||
<div class="tab-pane fade show active" id="tab-${idx}">
|
||||
<iframe src="http://${location.hostname}:${$('#terms').val()}"
|
||||
style="width:100%;min-height:500px"></iframe>
|
||||
style="width:100%;min-height:800px"></iframe>
|
||||
</div>`;
|
||||
var obj = $(str);
|
||||
$('#tab-content').append(obj);
|
||||
|
||||
Symlink
+1
@@ -0,0 +1 @@
|
||||
../js/common.js
|
||||
@@ -7,4 +7,7 @@
|
||||
}
|
||||
#vnc {
|
||||
margin-top: 10px;
|
||||
}
|
||||
#cad {
|
||||
float: right;
|
||||
}
|
||||
@@ -11,6 +11,7 @@
|
||||
<script src="/bootstrap/js/bootstrap.min.js"></script>
|
||||
<script src="/AdminLTE/js/adminlte.min.js"></script>
|
||||
<link rel="stylesheet" href="/index.css" />
|
||||
<script src="common.js"></script>
|
||||
<script src="/index.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
@@ -27,6 +28,7 @@
|
||||
<input id="show-cursor" class="form-check-input" type="checkbox">
|
||||
<label class="form-check-label">绘制鼠标</label>
|
||||
</div>
|
||||
<span id="info">fps: 0, bandwidth: 0 B/s</span>
|
||||
<button id="cad" type="button" class="btn btn-primary">ctrl+alt+del</button>
|
||||
</div>
|
||||
<!-- header -->
|
||||
|
||||
+34
-3
@@ -17,6 +17,7 @@ var page = {
|
||||
$('#cad').click(page.cad);
|
||||
// connect
|
||||
page.connect();
|
||||
setInterval(page.update_info, page.secs*1000);
|
||||
},
|
||||
connect: function() {
|
||||
var quality = $('#quality').val();
|
||||
@@ -28,6 +29,7 @@ var page = {
|
||||
});
|
||||
},
|
||||
render: function(e) {
|
||||
page.fps++;
|
||||
var reader = new FileReader;
|
||||
reader.onload = function() {
|
||||
var dv = new DataView(this.result);
|
||||
@@ -42,8 +44,10 @@ var page = {
|
||||
var dy = dv.getUint32(12, false);
|
||||
var dwidth = dv.getUint32(16, false);
|
||||
var dheight = dv.getUint32(20, false);
|
||||
var size = dv.getUint32(24, false);
|
||||
page.bandwidth += size;
|
||||
var id = page.ctx.getImageData(dx, dy, dwidth, dheight);
|
||||
var data = new Uint8Array(this.result.slice(24));
|
||||
var data = new Uint8Array(this.result.slice(28));
|
||||
var buf = id.data;
|
||||
for (var i = 0; i < buf.length; i++) {
|
||||
buf[i] = data[i];
|
||||
@@ -178,8 +182,25 @@ var page = {
|
||||
key = 'alt';
|
||||
} else if (e.which == 32) {
|
||||
key = 'space';
|
||||
} else if (e.which == 189) {
|
||||
key = '-';
|
||||
} else if (e.which == 187) {
|
||||
key = '=';
|
||||
} else if (e.which == 219) {
|
||||
key = '[';
|
||||
} else if (e.which == 221) {
|
||||
key = ']';
|
||||
} else if (e.which == 186) {
|
||||
key = ';';
|
||||
} else if (e.which == 222) {
|
||||
key = "'";
|
||||
} else if (e.which == 188) {
|
||||
key = ',';
|
||||
} else if (e.which == 190) {
|
||||
key = '.';
|
||||
} else if (e.which == 191) {
|
||||
key = '/';
|
||||
}
|
||||
// TODO: 符号
|
||||
page.ws.send(JSON.stringify({
|
||||
action: 'keyboard',
|
||||
payload: {
|
||||
@@ -189,9 +210,19 @@ var page = {
|
||||
}));
|
||||
console.log(e);
|
||||
},
|
||||
update_info: function() {
|
||||
var str = 'fps: '+parseInt(page.fps/page.secs)+
|
||||
', bandwidth: '+humanize.bytes(page.bandwidth/page.secs)+'/s';
|
||||
page.fps = 0;
|
||||
page.bandwidth = 0;
|
||||
$('#info').text(str);
|
||||
},
|
||||
canvas: undefined,
|
||||
ctx: undefined,
|
||||
id: '',
|
||||
ws: undefined
|
||||
ws: undefined,
|
||||
secs: 2,
|
||||
fps: 0,
|
||||
bandwidth: 0
|
||||
};
|
||||
$(document).ready(page.init);
|
||||
Reference in New Issue
Block a user