]> git.proxmox.com Git - pve-xtermjs.git/blob - src/www/main.js
a489937354f81af503fdc635278a1aee01ef2322
[pve-xtermjs.git] / src / www / main.js
1 console.log('xtermjs: starting');
2
3 var states = {
4 start: 1,
5 connecting: 2,
6 connected: 3,
7 disconnecting: 4,
8 disconnected: 5,
9 };
10
11 var term,
12 protocol,
13 socketURL,
14 socket,
15 ticket,
16 path,
17 resize,
18 ping,
19 state = states.start;
20
21 function updateState(newState, msg) {
22 var timeout, severity, message;
23 switch (newState) {
24 case states.connecting:
25 message = "Connecting...";
26 timeout = 0;
27 severity = severities.warning;
28 break;
29 case states.connected:
30 message = "Connected";
31 break;
32 case states.disconnecting:
33 message = "Disconnecting...";
34 timeout = 0;
35 severity = severities.warning;
36 break;
37 case states.disconnected:
38 switch (state) {
39 case states.start:
40 case states.connecting:
41 message = "Connection failed";
42 timeout = 0;
43 severity = severities.error;
44 break;
45 case states.connected:
46 case states.disconnecting:
47 message = "Connection closed";
48 timeout = 0;
49 break;
50 case states.disconnected:
51 // no state change
52 break;
53 default:
54 throw "unknown state";
55 }
56 break;
57 default:
58 throw "unknown state";
59 }
60 if (msg) {
61 message += " (" + msg + ")";
62 }
63 state = newState;
64 showMsg(message, timeout, severity);
65 }
66
67 var terminalContainer = document.getElementById('terminal-container');
68 document.getElementById('status_bar').addEventListener('click', hideMsg);
69
70 createTerminal();
71
72 function createTerminal() {
73 term = new Terminal();
74
75 term.on('resize', function (size) {
76 if (state === states.connected) {
77 socket.send("1:" + size.cols + ":" + size.rows + ":");
78 }
79 });
80
81 protocol = (location.protocol === 'https:') ? 'wss://' : 'ws://';
82
83 var params = {};
84 var type = getQueryParameter('console');
85 var vmid = getQueryParameter('vmid');
86 var vmname = getQueryParameter('vmname');
87 var nodename = getQueryParameter('node');
88 var url = '/nodes/' + nodename;
89 switch (type) {
90 case 'kvm':
91 url += '/qemu/' + vmid;
92 path = '/vms/' + vmid;
93 break;
94 case 'lxc':
95 url += '/lxc/' + vmid;
96 path = '/vms/' + vmid;
97 break;
98 case 'shell':
99 path = '/nodes/' + nodename;
100 break;
101 case 'upgrade':
102 params.upgrade = 1;
103 path = '/nodes/' + nodename;
104 break;
105 }
106 API2Request({
107 method: 'POST',
108 params: params,
109 url: url + '/termproxy',
110 success: function(result) {
111 var port = encodeURIComponent(result.data.port);
112 ticket = result.data.ticket;
113 socketURL = protocol + location.hostname + ((location.port) ? (':' + location.port) : '') + '/api2/json' + url + '/vncwebsocket?port=' + port + '&vncticket=' + encodeURIComponent(ticket);
114
115 term.open(terminalContainer, true);
116 socket = new WebSocket(socketURL, 'binary');
117 socket.binaryType = 'arraybuffer';
118 socket.onopen = runTerminal;
119 socket.onclose = stopTerminal;
120 socket.onerror = errorTerminal;
121 window.onbeforeunload = stopTerminal;
122 updateState(states.connecting);
123 },
124 failure: function(msg) {
125 updateState(states.disconnected,msg);
126 }
127 });
128
129 }
130
131 function runTerminal() {
132 socket.onmessage = function(event) {
133 var answer = Utf8ArrayToStr(event.data);
134 if (state === states.connected) {
135 term.write(answer);
136 } else if(state === states.connecting) {
137 if (answer.slice(0,2) === "OK") {
138 updateState(states.connected);
139 term.write(answer.slice(2));
140 } else {
141 socket.close();
142 }
143 }
144 };
145
146 term.on('data', function(data) {
147 if (state === states.connected) {
148 socket.send("0:" + unescape(encodeURIComponent(data)).length.toString() + ":" + data);
149 }
150 });
151
152 ping = setInterval(function() {
153 socket.send("2");
154 }, 30*1000);
155
156 window.addEventListener('resize', function() {
157 clearTimeout(resize);
158 resize = setTimeout(function() {
159 // done resizing
160 term.fit();
161 }, 250);
162 });
163
164 socket.send(PVE.UserName + ':' + path + ':' + ticket + "\n");
165
166 setTimeout(function() {term.fit();}, 250);
167 }
168
169 function stopTerminal(event) {
170 term.off('resize');
171 term.off('data');
172 clearInterval(ping);
173 socket.close();
174 updateState(states.disconnected, event.msg + event.code);
175 }
176
177 function errorTerminal(event) {
178 term.off('resize');
179 term.off('data');
180 clearInterval(ping);
181 socket.close();
182 term.destroy();
183 updateState(states.disconnected, event.msg + event.code);
184 }