我是网络套接字的新手。我在后端使用tornado / python并编写了以下代码。
class BaseWebSocketHandler(websocket.WebSocketHandler):
"""Base Class to establish an websocket connection."""
def open(self):
"""Opening the web socket connection."""
self.write_message('Connection Established.')
def on_message(self, message):
"""On message module send the response."""
pass
def on_close(self):
"""Close the connection."""
self.write_message('bye')
class MeterInfo(BaseWebSocketHandler):
"""Establish an websocket connection and send meter readings."""
def on_message(self, message):
"""On message module send to the response."""
self.write_message({'A': get_meter_reading()})
我的JavaScript代码如下所示,
var meter = new WebSocket("ws://"+window.location.host+"/socket/meterstatus/");
meter.onopen = function() {
$('#meter-well').text('Establishing connection...');
};
meter.onmessage = function (evt) {
var data = JSON.parse(evt.data)
var text = "<div class='meter'><h2>" + data.A +"</h2></div>";
$('#meter-pre').html(text);
};
meter.onclose = function (evt) {
console.log(JSON.parse(evt.data))
$('#meter-pre').append('\n'+evt.data);
};
window.setInterval(function(){ meter.send('') }, 100);
我每100毫秒向后端发出一个空白的Web套接字请求请求。这似乎是一个非常糟糕的解决方案。有没有更好的方法来做到这一点,而不需要在后端进行多次send(),只在抄表中发生任何变化时通知用户?
此外,我已经通过MQTT协议以更好的方式执行此操作,有人可以建议我如何实现它?
答案 0 :(得分:0)
您几乎找到了解决问题的方法:
class MeterInfo(BaseWebSocketHandler):
"""Establish an websocket connection and send meter readings."""
def on_message(self, message):
"""On message module send to the response."""
self.write_message({'A': get_meter_reading()})
您可能会注意到龙卷风需要一些事件来通过write_message
方法ping客户端。您正在使用来自客户端的新消息作为此类事件,尝试将简单超时调用更改为事件,如下所示:
# BaseWebSocketHandler removed, because we need to track all opened
# sockets in the class. You could change this later.
class MeterInfo(websocket.WebSocketHandler):
"""Establish an websocket connection and send meter readings."""
opened_sockets = []
previous_meter_reading = 0
def open(self):
"""Opening the web socket connection."""
self.write_message('Connection Established.')
MeterInfo.opened_sockets.append(self)
def on_close(self):
"""Close the connection."""
self.write_message('bye')
MeterInfo.opened_sockets.remove(self)
@classmethod
def try_send_new_reading(cls):
"""Send new reading to all connected clients"""
new_reading = get_meter_reading()
if new_reading == cls.previous_meter_reading:
return
cls.previous_meter_reading = new_reading
for socket in cls.opened_sockets:
socket.write_message({'A': new_reading})
if __name__ == '__main__':
# add this after all set up and before starting ioloop
METER_CHECK_INTERVAL = 100 # ms
ioloop.PeriodicCallback(MeterInfo.try_send_new_reading,
METER_CHECK_INTERVAL).start()
# start loop
ioloop.IOLoop.instance().start()
查看tornado.ioloop documentation以了解有关PeriodicCallback和其他选项的更多信息。
如果你想将龙卷风用于MQTT协议,龙卷风是不可能的。例如,您可以尝试emqtt server,但这是实际的服务器,而不是编写应用程序的框架,所以恕我直言,通过龙卷风ping网络套接字会更全面。