mirror of
https://github.com/netfun2000/rttys_zhaojh329.git
synced 2026-02-27 09:53:24 +08:00
Restructure
No longer use JSON; Using binary data in TLV format; Optimization code; Signed-off-by: Jianhui Zhao <jianhuizhao329@gmail.com>
This commit is contained in:
+36
-140
@@ -20,14 +20,6 @@
|
||||
<Button type="primary" size="large" long :loading="modal_loading" @click="doUpload">{{ modal_loading ? 'Uploading' : 'Click to upload' }}</Button>
|
||||
</div>
|
||||
</Modal>
|
||||
<Modal v-model="filelist_modal" width="600" :mask-closable="false">
|
||||
<p slot="header">
|
||||
<span>Please select file to download</span>
|
||||
</p>
|
||||
<Tag>{{'/' + dl_path.join('/')}}</Tag>
|
||||
<Table :columns="filelist_title" height="300" :data="filelist" @on-row-dblclick="filelistDblclick"></Table>
|
||||
<div slot="footer"></div>
|
||||
</Modal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -38,6 +30,7 @@ import { Terminal } from 'xterm'
|
||||
import 'xterm/lib/xterm.css'
|
||||
import * as fit from 'xterm/lib/addons/fit/fit';
|
||||
import axios from 'axios'
|
||||
import * as rtty from './rtty'
|
||||
|
||||
Terminal.applyAddon(fit);
|
||||
|
||||
@@ -52,8 +45,6 @@ export default {
|
||||
terminal_loading: false,
|
||||
modal_loading: false,
|
||||
upmodal: false,
|
||||
filelist_modal: false,
|
||||
dl_path: [],
|
||||
file: null,
|
||||
filePos: 0,
|
||||
fileStep: 2048,
|
||||
@@ -64,7 +55,7 @@ export default {
|
||||
recvCnt: 0,
|
||||
username: '',
|
||||
password: '',
|
||||
did: '',
|
||||
devId: '',
|
||||
columns: [
|
||||
{
|
||||
title: 'ID',
|
||||
@@ -90,7 +81,7 @@ export default {
|
||||
click: () => {
|
||||
this.terminal_loading = true;
|
||||
this.termOn = true;
|
||||
this.did = params.row.id;
|
||||
this.devId = params.row.id;
|
||||
window.setTimeout(this.login, 200);
|
||||
}
|
||||
}
|
||||
@@ -98,62 +89,11 @@ export default {
|
||||
}
|
||||
}
|
||||
],
|
||||
devlist: [ ],
|
||||
filelist_title: [
|
||||
{
|
||||
title: 'Name',
|
||||
key: 'name',
|
||||
render: (h, params) => {
|
||||
if (params.row.type == 'dir')
|
||||
return h('div', [
|
||||
h('Icon', {props: {type: 'folder', color: '#FFE793', size: 20}}),
|
||||
h('strong', ' ' + params.row.name)
|
||||
]);
|
||||
else
|
||||
return params.row.name;
|
||||
}
|
||||
}, {
|
||||
title: 'Size',
|
||||
key: 'size',
|
||||
sortable: true,
|
||||
render: (h, params) => {
|
||||
let size = params.row.size;
|
||||
let unit = 'B';
|
||||
|
||||
if (!size)
|
||||
return;
|
||||
|
||||
if (size > 1024 * 1024 * 1024) {
|
||||
size /= 1024.0 * 1024 * 1024;
|
||||
unit = 'GB';
|
||||
} else if (size > 1024 * 1024) {
|
||||
size /= 1024.0 * 1024;
|
||||
unit = 'MB';
|
||||
} else if (size > 1024) {
|
||||
size /= 1024.0;
|
||||
unit = 'KB';
|
||||
}
|
||||
return size.toFixed(2) + ' ' + unit;
|
||||
}
|
||||
}, {
|
||||
title: 'modification',
|
||||
key: 'mtim',
|
||||
sortable: true
|
||||
}
|
||||
],
|
||||
filelist: []
|
||||
devlist: [ ]
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
/* ucs-2 string to base64 encoded ascii */
|
||||
utoa(str) {
|
||||
return window.btoa(unescape(encodeURIComponent(str)));
|
||||
},
|
||||
/* base64 encoded ascii to ucs-2 string */
|
||||
atou(str) {
|
||||
return decodeURIComponent(escape(window.atob(str)));
|
||||
},
|
||||
beforeUpload (file) {
|
||||
this.file = file;
|
||||
this.filePos = 0;
|
||||
@@ -171,6 +111,7 @@ export default {
|
||||
|
||||
this.cancel_upfile = false;
|
||||
this.modal_loading = true;
|
||||
|
||||
var fr = new FileReader();
|
||||
fr.onload = (e) => {
|
||||
if (this.cancel_upfile) {
|
||||
@@ -180,7 +121,9 @@ export default {
|
||||
return;
|
||||
}
|
||||
|
||||
this.ws.send(fr.result);
|
||||
let pkt = rtty.newPacket(rtty.RTTY_PACKET_UPFILE, {sid: this.sid, code: 1, data: fr.result});
|
||||
this.ws.send(pkt);
|
||||
|
||||
this.filePos += e.loaded;
|
||||
|
||||
if (this.filePos < this.file.size) {
|
||||
@@ -200,29 +143,18 @@ export default {
|
||||
}
|
||||
};
|
||||
|
||||
var msg = {
|
||||
type: 'upfile',
|
||||
sid: this.sid,
|
||||
name: this.file.name,
|
||||
size: this.file.size
|
||||
};
|
||||
this.ws.send(JSON.stringify(msg));
|
||||
|
||||
window.setTimeout(() => {
|
||||
this.readFile(fr);
|
||||
}, 100);
|
||||
let pkt = rtty.newPacket(rtty.RTTY_PACKET_UPFILE, {sid: this.sid, name: this.file.name, size: this.file.size, code: 0});
|
||||
this.ws.send(pkt);
|
||||
this.readFile(fr);
|
||||
},
|
||||
cancelUpfile() {
|
||||
if (!this.modal_loading)
|
||||
return;
|
||||
this.cancel_upfile = true;
|
||||
this.$Message.info("Upload canceled");
|
||||
var msg = {
|
||||
type: 'upfile',
|
||||
sid: this.sid,
|
||||
err: 'canceled'
|
||||
};
|
||||
this.ws.send(JSON.stringify(msg));
|
||||
|
||||
let pkt = rtty.newPacket(rtty.RTTY_PACKET_UPFILE, {sid: this.sid, code: 2});
|
||||
this.ws.send(pkt);
|
||||
},
|
||||
showMenu(show) {
|
||||
if (!this.termOn)
|
||||
@@ -235,42 +167,9 @@ export default {
|
||||
this.modal_loading = false;
|
||||
this.file = null;
|
||||
},
|
||||
filelistDblclick(row, index) {
|
||||
if (row.type == 'dir') {
|
||||
if (row.name == '..')
|
||||
this.dl_path.pop();
|
||||
else
|
||||
this.dl_path.push(row.name);
|
||||
var msg = {
|
||||
type: 'filelist',
|
||||
sid: this.sid,
|
||||
name: '/' + this.dl_path.join('/')
|
||||
};
|
||||
this.ws.send(JSON.stringify(msg));
|
||||
} else {
|
||||
var msg = {
|
||||
type: 'downfile',
|
||||
sid: this.sid
|
||||
};
|
||||
|
||||
if (this.dl_path.length > 0)
|
||||
msg.name = '/' + this.dl_path.join('/') + '/' + row.name;
|
||||
else
|
||||
msg.name = '/' + row.name;
|
||||
this.ws.send(JSON.stringify(msg));
|
||||
this.filelist_modal = false;
|
||||
this.$Message.info("TODO");
|
||||
}
|
||||
},
|
||||
downFile () {
|
||||
this.contextMenuVisible = false;
|
||||
this.filelist_modal = true;
|
||||
this.dl_path = [];
|
||||
var msg = {
|
||||
type: 'filelist',
|
||||
sid: this.sid
|
||||
};
|
||||
this.ws.send(JSON.stringify(msg));
|
||||
this.$Message.info("TODO");
|
||||
},
|
||||
getQueryString(name) {
|
||||
var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");
|
||||
@@ -301,46 +200,43 @@ export default {
|
||||
if (location.protocol == 'https://')
|
||||
protocol = 'wss://';
|
||||
|
||||
var ws = new Socket(protocol + location.host + '/ws/browser?did=' + this.did);
|
||||
ws.on('connect', ()=> {
|
||||
ws.on('data', (data)=>{
|
||||
var resp = JSON.parse(data);
|
||||
var type = resp.type;
|
||||
var ws = new Socket(protocol + location.host + '/ws?devid=' + this.devId);
|
||||
ws.on('connect', () => {
|
||||
ws.on('data', (data) => {
|
||||
let pkt = rtty.parsePacket(data);
|
||||
|
||||
if (type == 'login') {
|
||||
if (pkt.typ == rtty.RTTY_PACKET_LOGINACK) {
|
||||
this.terminal_loading = false;
|
||||
|
||||
if (resp.err) {
|
||||
this.$Message.error(resp.err);
|
||||
if (pkt.code != 0) {
|
||||
this.$Message.error('Device offline');
|
||||
this.logout(null, term);
|
||||
return;
|
||||
}
|
||||
this.ws = ws;
|
||||
this.sid = resp.sid;
|
||||
term.on('data', (data)=> {
|
||||
data = JSON.stringify({type: 'data', sid: this.sid, data: this.utoa(data)});
|
||||
ws.send(data);
|
||||
this.sid = pkt.sid;
|
||||
term.on('data', (data) => {
|
||||
let pkt = rtty.newPacket(rtty.RTTY_PACKET_TTY, {sid: this.sid, data: Buffer.from(data)});
|
||||
ws.send(pkt);
|
||||
});
|
||||
} else if (type == 'data') {
|
||||
} else if (pkt.typ == rtty.RTTY_PACKET_TTY) {
|
||||
this.recvCnt++;
|
||||
var data = this.atou(resp.data);
|
||||
var data = pkt.data.toString();
|
||||
|
||||
if (this.recvCnt < 4) {
|
||||
if (data.match('login:') && this.username != '') {
|
||||
data = JSON.stringify({type: 'data', sid: this.sid, data: this.utoa(this.username + '\n')});
|
||||
ws.send(data);
|
||||
let pkt = rtty.newPacket(rtty.RTTY_PACKET_TTY, {sid: this.sid, data: this.username + '\n'});
|
||||
ws.send(pkt);
|
||||
return;
|
||||
}
|
||||
|
||||
if (data.match('Password:') && this.password != '') {
|
||||
data = JSON.stringify({type: 'data', sid: this.sid, data: this.utoa(this.password + '\n')});
|
||||
ws.send(data);
|
||||
let pkt = rtty.newPacket(rtty.RTTY_PACKET_TTY, {sid: this.sid, data: this.password + '\n'});
|
||||
ws.send(pkt);
|
||||
return;
|
||||
}
|
||||
}
|
||||
term.write(data);
|
||||
} else if (type == 'filelist') {
|
||||
this.filelist = resp.list;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -351,7 +247,7 @@ export default {
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
var id = this.getQueryString('id');
|
||||
var devId = this.getQueryString('id');
|
||||
var username = this.getQueryString('username');
|
||||
var password = this.getQueryString('password');
|
||||
|
||||
@@ -360,15 +256,15 @@ export default {
|
||||
if (password)
|
||||
this.password = password;
|
||||
|
||||
if (id) {
|
||||
if (devId) {
|
||||
this.terminal_loading = true;
|
||||
this.termOn = true;
|
||||
this.did = id;
|
||||
this.devId = devId;
|
||||
window.setTimeout(this.login, 200);
|
||||
}
|
||||
|
||||
window.setInterval(() => {
|
||||
axios.get('/list').then((res => {
|
||||
axios.get('/devs').then((res => {
|
||||
this.table_loading = false;
|
||||
this.devlist = res.data;
|
||||
}));
|
||||
|
||||
Executable
+98
@@ -0,0 +1,98 @@
|
||||
export const RTTY_PROTOCOL_VERSION = 1
|
||||
|
||||
export const RTTY_PACKET_LOGIN = 1
|
||||
export const RTTY_PACKET_LOGINACK = 2
|
||||
export const RTTY_PACKET_LOGOUT = 3
|
||||
export const RTTY_PACKET_TTY = 4
|
||||
export const RTTY_PACKET_ANNOUNCE = 5
|
||||
export const RTTY_PACKET_UPFILE = 6
|
||||
|
||||
export const RTTY_ATTR_SID = 1
|
||||
export const RTTY_ATTR_CODE = 2
|
||||
export const RTTY_ATTR_DATA = 3
|
||||
export const RTTY_ATTR_NAME = 4
|
||||
export const RTTY_ATTR_SIZE = 5
|
||||
|
||||
export let parsePacket = function(buf) {
|
||||
let pkt = { };
|
||||
|
||||
pkt.version = buf.readUInt8(0);
|
||||
pkt.typ = buf.readUInt8(1);
|
||||
|
||||
let i = 2;
|
||||
while (i < buf.length) {
|
||||
let typ = buf.readUInt8(i);
|
||||
let length = buf.readUInt16BE(i + 1);
|
||||
|
||||
i += 3;
|
||||
if (typ == RTTY_ATTR_SID)
|
||||
pkt.sid = buf.toString('utf8', i, i + length - 1);
|
||||
else if (typ == RTTY_ATTR_CODE)
|
||||
pkt.code = buf.readUInt8(i);
|
||||
else if (typ == RTTY_ATTR_DATA)
|
||||
pkt.data = buf.slice(i, i + length);
|
||||
|
||||
i += length;
|
||||
}
|
||||
|
||||
return pkt
|
||||
}
|
||||
|
||||
function addAttr(buf, typ, data) {
|
||||
let tmp, length
|
||||
|
||||
if (typeof data == 'string') {
|
||||
length = data.length + 1;
|
||||
tmp = Buffer.alloc(3 + length);
|
||||
} else {
|
||||
length = data.byteLength;
|
||||
tmp = Buffer.alloc(3);
|
||||
}
|
||||
|
||||
tmp.writeUInt8(typ, 0);
|
||||
tmp.writeUInt16BE(length, 1);
|
||||
|
||||
if (typeof data == 'string') {
|
||||
tmp.write(data, 3);
|
||||
return Buffer.concat([buf, tmp]);
|
||||
} else {
|
||||
return Buffer.concat([buf, tmp, Buffer.from(data)]);
|
||||
}
|
||||
}
|
||||
|
||||
function addAttrU8(buf, typ, val) {
|
||||
let tmp = Buffer.alloc(3 + 1);
|
||||
tmp.writeUInt8(typ, 0);
|
||||
tmp.writeUInt16BE(1, 1);
|
||||
tmp.writeUInt8(val, 3);
|
||||
return Buffer.concat([buf, tmp]);
|
||||
}
|
||||
|
||||
function addAttrU32(buf, typ, val) {
|
||||
let tmp = Buffer.alloc(3 + 4);
|
||||
tmp.writeUInt8(typ, 0);
|
||||
tmp.writeUInt16BE(4, 1);
|
||||
tmp.writeUInt32BE(val, 3);
|
||||
return Buffer.concat([buf, tmp]);
|
||||
}
|
||||
|
||||
export let newPacket = function(typ, attr) {
|
||||
let buf = Buffer.from([RTTY_PROTOCOL_VERSION, typ]);
|
||||
|
||||
if (attr.sid)
|
||||
buf = addAttr(buf, RTTY_ATTR_SID, attr.sid)
|
||||
|
||||
if (attr.code)
|
||||
buf = addAttrU8(buf, RTTY_ATTR_CODE, attr.code)
|
||||
|
||||
if (attr.data)
|
||||
buf = addAttr(buf, RTTY_ATTR_DATA, attr.data)
|
||||
|
||||
if (attr.name)
|
||||
buf = addAttr(buf, RTTY_ATTR_NAME, attr.name)
|
||||
|
||||
if (attr.size)
|
||||
buf = addAttrU32(buf, RTTY_ATTR_SIZE, attr.size)
|
||||
|
||||
return buf;
|
||||
}
|
||||
Reference in New Issue
Block a user