我有一个包含六个div元素的网页,需要每分钟每分钟从服务器更新一次。我已经有一个开放的websocket,可以将数据从服务器传递到客户端。基于服务器上的计时器发送数据可能是最简单的,但是如果更好,我可以根据客户端的时钟向服务器请求数据没有问题。我已经在另一个过程中基于击键向服务器请求数据了。
div元素的样式:
div.Out {
position: fixed;
top: 45px;
left: 510px;
width: 300px;
font: bold 65px Lora;
color: white;
}
div.In {
position: fixed;
top: 214px;
left: 138px;
width: 400px;
font: bold 126px Lora;
color: rgb(0,44,255);
}
div.Press {
position: fixed;
top: 400px;
left: 585px;
width: 250px;
font: bold 29px Bookman;
color: rgb(50,50,50);
}
div.Time {
position: fixed;
top: 42px;
left: 178px;
width: 250px;
font: Bold 90px Arial Bold;
color: rgb(255,0,0);
}
div.Date {
position: fixed;
top: 245px;
left: 490px;
width: 250px;
font: Bold 45px Arial Bold;
color: rgb(0,150,0);
}
div.Status {
position: fixed;
top: 350px;
left: 160px;
width: 250px;
font: 50px Arial Bold;
}
Websocket体内代码(Python):
print('<script language="javascript" type="text/javascript">')
print('websocket = new WebSocket("ws://', host_ip, ':8000");', sep="")
print('document.addEventListener("keydown", function(event) {')
print('event.preventDefault();')
print(' const key = event.key; // "ArrowRight", "ArrowLeft", "ArrowUp", or "ArrowDown"')
print(' switch (key) { // change to event.key to key to use the above variable')
print(' case "ArrowLeft":')
print(' // Left pressed')
print(' message = "Left";')
print(' websocket.send(message);')
print(' location.reload();')
print(' break;')
print(' case "ArrowRight":')
print(' // Right pressed')
print(' message = "Right";')
print(' websocket.send(message);')
print(' location.reload();')
print(' break;')
print(' case "ArrowUp":')
print(' // Up pressed')
print(' message = "Up";')
print(' websocket.send(message);')
print(' location.reload();')
print(' break;')
print(' case "ArrowDown":')
print(' // Down pressed')
print(' message = "Down";')
print(' websocket.send(message);')
print(' location.reload();')
print(' break;')
print(' }')
print('});')
print('websocket.onopen = function(evt) { onOpen(evt) };')
print(' function onOpen(evt)')
正文中的div元素:
print('<div class="Out">')
if FindCheck < 300:
with open("/run/thermostat/outsideT","r") as f: # Get the Outside Temperature reading
Tout = float(f.read())
print('{0:5.1f}'.format(Tout),'<span style="font-size:44px">', ClassValues[0][LineValue[0]], '</span>', sep="") # Show the outside temperature; note the inline style
else:
print("----") # Stale data, display dashes
print('</div>')
print('<div class="In">')
if FindCheck < 300:
with open("/run/thermostat/insideT","r") as f: # Get the Inside Temperature reading
Tin = float(f.read())
if LineValue[0] == 0:
Tin = (Tin - 32) * 5 / 9
print('{0:5.1f}'.format(Tin),'<span style="font-size:80px">', ClassValues[0][LineValue[0]], '</span>', sep="") # Show the inside temperature; note the inline style
else:
print("----") # Stale data, display dashes
print('</div>')
print('<div class="Press">')
if FindCheck < 300:
with open("/run/thermostat/insideP","r") as f: # Get the Inside Pressure reading
Pressure = float(f.read())
print('{0:5.1f}'.format(Pressure), ClassValues[2][LineValue[0]]) # Print Barometric Pressure
else:
print("----") # Stale data, display dashes
print('</div>')
print('<div class="Date">')
StringA=subprocess.check_output(["date", "+%a"])
StringA=StringA.decode("utf-8")
StringB=subprocess.check_output(["date", "+%b%e"])
StringB=StringB.decode("utf-8")
print(StringA.rstrip(), StringB.rstrip())
print('</div>')
if LineValue[4] == 0 or LineValue[4] == 2: # Auto or Cooling
print('<div style="color:',bColor[5],'" class="Hot">Cool: {:02.1f}'.format(ClassValues[5]),'</div>', sep="")
if LineValue[4] == 0 or LineValue[4] == 1: # Auto or Heating
print('<div style="color:',bColor[6],'" class="Cold">Heat: {:02.1f}'.format(ClassValues[6]),'</div>', sep="")
print('<div id="txt" Class="Time">', datetime.now().strftime('%H:%M'), '</div>')
以上内容将所有内容都写到了网页上,我可以强制每分钟更新一次整页,但这很慢,而且效果不佳。
编辑:我相信我有一个部分答案。通过将div元素设置为具有以下ID的ID:
print('<div id="Out" class="Out">')
看来我以后可以通过更新innerHTML对其进行编辑:
print('var Out = document.getElementById("Out");')
print('Out.innerHTML = "New Text";')
但是,在某些情况下,我需要更新样式元素以及文本(这就是为什么我最初包含CSS标记,但是有人删除了它)的原因,我不确定如何做到这一点。
答案 0 :(得分:0)
这是我的解决方案。首先,在Python中创建一个websocket中继以将消息中继到所有客户端(注意:此websocket不仅处理此功能):
from simple_websocket_server import WebSocketServer, WebSocket
class Control(WebSocket):
def handle(self):
<Code to handle arrow presses from web page>
string = pickle.loads(self.data) # Get text list from data stream
List = "Date Time StatusT StatusC Hot Cold Pressure TOutside TInside" # List of valid keywords
result = List.find(string[0]) # Make sure the first text element is a valid keyword
if result != -1:
MessageText = ",".join(string)
for client in self.server.connections.values():
client.send_message(MessageText)
server = WebSocketServer('', 8000, Control)
server.serve_forever()
接下来,也使用Python创建一个客户端,以格式化数据并将其发送到websocket中继。每分钟(或任何时间)运行:
import os, subprocess, pickle, time
def Transmit_Message(Key, String, *args):
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
message = []
message.append(Key)
message.append(String)
if args:
for x in args:
message.append(x)
loop.run_until_complete(SendMessage(pickle.dumps(message)))
@asyncio.coroutine
def SendMessage(message):
websocket = yield from websockets.connect('ws://localhost:8000')
try:
yield from websocket.send(message)
finally:
yield from websocket.close()
# Display the date
StringA = subprocess.check_output(["date", "+%a"])
StringA = StringA.decode("utf-8")
StringB = subprocess.check_output(["date", "+%b"])
StringB = StringB.decode("utf-8")
StringC = subprocess.check_output(["date", "+%e"])
StringC = StringC.decode("utf-8")
Date = StringA + StringB + StringC.rstrip()
transmit_Message("Date", Date)
# Display the time
Time = subprocess.check_output(["date", "+%H:%M"])
Time = Time.decode("utf-8")
transmit_Message("Time", Time.rstrip())
# Display the temperature
with open("/run/thermostat/outsideT","r") as f: # Get the Outside Temperature reading
Tout = f.read()
Tout = float(Tout)
TOutside = '{:04.1f}'.format(Tout)
Scale = '℉' # Symbol for degrees F
transmit_Message("TOutside", TOutside, Scale)
在网页上,使用javascript创建一个websocket以接收值:
<script>
document.addEventListener("keydown", function(event) {
const key = event.key; // "ArrowRight", "ArrowLeft", "ArrowUp", or "ArrowDown"
switch (key) {
case "ArrowLeft":
message = "Left";
websocket.send(message);
break;
case "ArrowRight":
message = "Right";
websocket.send(message);
break;
case "ArrowUp":
message = "Up";
websocket.send(message);
break;
case "ArrowDown":
message = "Down";
websocket.send(message);
}
});
socket = "ws://" + window.location.hostname + ":8000"
websocket = new WebSocket(socket);
websocket.onopen = function(evt) { onOpen(evt) };
websocket.onclose = function(evt) { onClose(evt) };
websocket.onmessage = function(evt) { onMessage(evt) };
websocket.onerror = function(evt) { onError(evt) };
function onOpen(evt) {
document.getElementById("Connect").innerHTML = "Network: Connected";
}
function onClose(evt) {
document.getElementById("Connect").innerHTML = "Network: Disconnected";
}
function onMessage(evt) {
var msg = evt.data; // Index 0 is "TInside", "TOutside", "Pressure", "Date", or "Time"
var array = msg.split(',');
switch(array[0])
case "TInside":
document.getElementById("In").innerHTML = array[1];
document.getElementById("InScale").innerHTML = array[2];
break;
case "TOutside":
document.getElementById("Out").innerHTML = array[1];
document.getElementById("OutScale").innerHTML = array[2];
break;
case "Pressure":
document.getElementById("Press").innerHTML = array[1];
break;
case "Date":
document.getElementById("Date").innerHTML = array[1];
break;
case "Time":
document.getElementById("Time").innerHTML = array[1];
break;
}
}
</script>
如果数据更复杂或更广泛,可以使用JSON而不是pickle。