]>
Commit | Line | Data |
---|---|---|
dcf3d43b DC |
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, | |
dcf3d43b DC |
16 | resize, |
17 | ping, | |
18 | state = states.start; | |
19 | ||
20 | function updateState(newState, msg) { | |
21 | var timeout, severity, message; | |
22 | switch (newState) { | |
23 | case states.connecting: | |
24 | message = "Connecting..."; | |
25 | timeout = 0; | |
26 | severity = severities.warning; | |
27 | break; | |
28 | case states.connected: | |
29 | message = "Connected"; | |
30 | break; | |
31 | case states.disconnecting: | |
32 | message = "Disconnecting..."; | |
33 | timeout = 0; | |
34 | severity = severities.warning; | |
35 | break; | |
36 | case states.disconnected: | |
37 | switch (state) { | |
38 | case states.start: | |
39 | case states.connecting: | |
40 | message = "Connection failed"; | |
41 | timeout = 0; | |
42 | severity = severities.error; | |
43 | break; | |
44 | case states.connected: | |
45 | case states.disconnecting: | |
46 | message = "Connection closed"; | |
47 | timeout = 0; | |
48 | break; | |
49 | case states.disconnected: | |
50 | // no state change | |
51 | break; | |
52 | default: | |
53 | throw "unknown state"; | |
54 | } | |
55 | break; | |
56 | default: | |
57 | throw "unknown state"; | |
58 | } | |
59 | if (msg) { | |
60 | message += " (" + msg + ")"; | |
61 | } | |
62 | state = newState; | |
63 | showMsg(message, timeout, severity); | |
64 | } | |
65 | ||
66 | var terminalContainer = document.getElementById('terminal-container'); | |
67 | document.getElementById('status_bar').addEventListener('click', hideMsg); | |
5e8b8730 | 68 | Terminal.applyAddon(fit); |
dcf3d43b DC |
69 | |
70 | createTerminal(); | |
71 | ||
72 | function createTerminal() { | |
37445374 | 73 | term = new Terminal(getTerminalSettings()); |
dcf3d43b DC |
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; | |
dcf3d43b DC |
92 | break; |
93 | case 'lxc': | |
94 | url += '/lxc/' + vmid; | |
dcf3d43b DC |
95 | break; |
96 | case 'upgrade': | |
97 | params.upgrade = 1; | |
dcf3d43b DC |
98 | break; |
99 | } | |
100 | API2Request({ | |
101 | method: 'POST', | |
102 | params: params, | |
103 | url: url + '/termproxy', | |
104 | success: function(result) { | |
105 | var port = encodeURIComponent(result.data.port); | |
106 | ticket = result.data.ticket; | |
107 | socketURL = protocol + location.hostname + ((location.port) ? (':' + location.port) : '') + '/api2/json' + url + '/vncwebsocket?port=' + port + '&vncticket=' + encodeURIComponent(ticket); | |
108 | ||
109 | term.open(terminalContainer, true); | |
110 | socket = new WebSocket(socketURL, 'binary'); | |
111 | socket.binaryType = 'arraybuffer'; | |
112 | socket.onopen = runTerminal; | |
113 | socket.onclose = stopTerminal; | |
114 | socket.onerror = errorTerminal; | |
115 | window.onbeforeunload = stopTerminal; | |
116 | updateState(states.connecting); | |
117 | }, | |
118 | failure: function(msg) { | |
119 | updateState(states.disconnected,msg); | |
120 | } | |
121 | }); | |
122 | ||
123 | } | |
124 | ||
125 | function runTerminal() { | |
126 | socket.onmessage = function(event) { | |
127 | var answer = Utf8ArrayToStr(event.data); | |
128 | if (state === states.connected) { | |
129 | term.write(answer); | |
130 | } else if(state === states.connecting) { | |
131 | if (answer.slice(0,2) === "OK") { | |
132 | updateState(states.connected); | |
133 | term.write(answer.slice(2)); | |
134 | } else { | |
135 | socket.close(); | |
136 | } | |
137 | } | |
138 | }; | |
139 | ||
140 | term.on('data', function(data) { | |
141 | if (state === states.connected) { | |
142 | socket.send("0:" + unescape(encodeURIComponent(data)).length.toString() + ":" + data); | |
143 | } | |
144 | }); | |
145 | ||
146 | ping = setInterval(function() { | |
147 | socket.send("2"); | |
148 | }, 30*1000); | |
149 | ||
150 | window.addEventListener('resize', function() { | |
151 | clearTimeout(resize); | |
152 | resize = setTimeout(function() { | |
153 | // done resizing | |
154 | term.fit(); | |
155 | }, 250); | |
156 | }); | |
157 | ||
5e91985c | 158 | socket.send(PVE.UserName + ':' + ticket + "\n"); |
dcf3d43b DC |
159 | |
160 | setTimeout(function() {term.fit();}, 250); | |
161 | } | |
162 | ||
163 | function stopTerminal(event) { | |
164 | term.off('resize'); | |
165 | term.off('data'); | |
166 | clearInterval(ping); | |
167 | socket.close(); | |
168 | updateState(states.disconnected, event.msg + event.code); | |
169 | } | |
170 | ||
171 | function errorTerminal(event) { | |
172 | term.off('resize'); | |
173 | term.off('data'); | |
174 | clearInterval(ping); | |
175 | socket.close(); | |
176 | term.destroy(); | |
177 | updateState(states.disconnected, event.msg + event.code); | |
178 | } |