From adbfe49125bd21c25551e3d3dfd5c7bd311ca82f Mon Sep 17 00:00:00 2001 From: Jesse Luehrs Date: Mon, 6 Oct 2014 15:49:58 -0400 Subject: try to send updates rather than the full screen on every frame this is not a very intelligent method at the moment, but it should (probably?) be an improvement over the current method. it probably fails pretty miserably on scrolling though - need to figure out a better idea for that. --- termcast_server/index.html | 26 +++++++++++++++++++++++++- termcast_server/ssh.py | 2 +- termcast_server/termcast.py | 34 ++++++++++++++++++++++++++++------ termcast_server/web.py | 17 ++++++++++++----- 4 files changed, 66 insertions(+), 13 deletions(-) (limited to 'termcast_server') diff --git a/termcast_server/index.html b/termcast_server/index.html index 459d9c1..7e37c06 100644 --- a/termcast_server/index.html +++ b/termcast_server/index.html @@ -51,7 +51,7 @@ socket.onmessage = function (e) { menudiv.innerHTML = menu; menudiv.style.setProperty('display', 'block'); } - else if (type == "update_screen") { + else if (type == "redraw_screen") { document.querySelector('.menu').style.setProperty('display', 'none'); var termdiv = document.querySelector('.term'); term = ''; @@ -84,6 +84,30 @@ socket.onmessage = function (e) { termdiv.innerHTML = term; termdiv.style.setProperty('display', 'block'); } + else if (type == "update_screen") { + var termtable = document.querySelector('.term tbody'); + data.updates.forEach(function (update) { + var tr = termtable.children[update.row]; + var td = tr.children[update.col]; + var contents = update.cell.contents; + if (contents == " ") { + contents = " "; + } + td.innerHTML = contents; + if (update.cell.fgcolor) { + td.style.setProperty('color', colors[update.cell.fgcolor]); + } + else { + td.style.removeProperty('color'); + } + if (update.cell.bgcolor) { + td.style.setProperty('background-color', colors[update.cell.bgcolor]); + } + else { + td.style.removeProperty('background-color'); + } + }) + } else if (type == "streamer_disconnect") { socket.send(JSON.stringify({"type": "request_streamer_list"})); } diff --git a/termcast_server/ssh.py b/termcast_server/ssh.py index d828fca..360c3f7 100644 --- a/termcast_server/ssh.py +++ b/termcast_server/ssh.py @@ -106,7 +106,7 @@ class Connection(object): else: return self.select_stream() - def msg_new_data(self, connection_id, prev_buf, data, screen): + def msg_new_data(self, connection_id, prev_buf, data, screen, updates): if self.watching_id != connection_id: return diff --git a/termcast_server/termcast.py b/termcast_server/termcast.py index 743274b..f99971d 100644 --- a/termcast_server/termcast.py +++ b/termcast_server/termcast.py @@ -68,17 +68,36 @@ class Handler(object): term.append([]) for j in range(0, self.cols): cell = self.vt.cell(i, j) - contents = cell.contents() - if len(contents) == 0: - contents = " " term[i].append({ - "contents": contents, + "contents": cell.contents(), "fgcolor": cell.fgcolor().color(), "bgcolor": cell.bgcolor().color(), }) return term + def get_term_updates(self, screen): + changes = [] + for i in range(0, self.rows): + for j in range(0, self.cols): + cell = self.vt.cell(i, j) + prev_cell = screen[i][j] + contents = cell.contents() + fgcolor = cell.fgcolor().color() + bgcolor = cell.bgcolor().color() + if contents != prev_cell["contents"] or fgcolor != prev_cell["fgcolor"] or bgcolor != prev_cell["bgcolor"]: + changes.append({ + "row": i, + "col": j, + "cell": { + "contents": contents, + "fgcolor": fgcolor, + "bgcolor": bgcolor, + }, + }) + + return changes + def total_time(self): return self._human_readable_duration(time.time() - self.created_at) @@ -171,13 +190,15 @@ class Connection(object): print('*** recv failed: ' + str(e)) if len(buf) > 0: + prev_screen = self.handler.get_term() self.handler.process(buf) self.publisher.notify( "new_data", self.connection_id, self.handler.buf, buf, - self.handler.get_term() + self.handler.get_term(), + self.handler.get_term_updates(prev_screen) ) else: self.publisher.notify("streamer_disconnect", self.connection_id) @@ -192,7 +213,8 @@ class Connection(object): self.connection_id, self.handler.buf, b'', - self.handler.get_term() + self.handler.get_term(), + None ) self.client.send(b"msg watcher connected\n") diff --git a/termcast_server/web.py b/termcast_server/web.py index 8b9f9e3..1c64fd4 100644 --- a/termcast_server/web.py +++ b/termcast_server/web.py @@ -34,14 +34,21 @@ class WebSocketHandler(tornado.websocket.WebSocketHandler): def on_finish(self): self.publisher.unsubscribe(self) - def msg_new_data(self, connection_id, prev_buf, data, screen): + def msg_new_data(self, connection_id, prev_buf, data, screen, updates): if self.watching_id != connection_id: return - reply = { - "type": "update_screen", - "screen": screen, - } + if updates: + reply = { + "type": "update_screen", + "updates": updates, + } + else: + reply = { + "type": "redraw_screen", + "screen": screen, + } + try: self.write_message(json.dumps(reply)) except: -- cgit v1.2.3