2016-12-06 24 views
0

我是网络套接字的新手。我为我的后端使用了tornado/python,并编写了下面的代码。使用Web套接字和龙卷风从后端通知ping

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毫秒。这对我来说似乎是一个很糟糕的解决方案有没有更好的方法来做到这一点,而不需要向后端发送多个send(),只有在读表中发生任何变化时才通知用户?

此外,我已经通过MQTT协议以更好的方式做到这一点,有人可以建议我如何实现这一点?

+0

目前还不清楚你在这里问了什么,你想用MQTT替换所有的代码吗? – hardillb

+0

@hardillb我想要一个更好的解决方案,以便我不需要每100毫秒就发送一次send()到服务器。 –

+0

那么,你有什么尝试,我们会帮你解决一些不起作用的东西,但不太可能为你写所有的东西? – hardillb

回答

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通网络套接字。

+0

这是一个非常好的方法来定期回调和检查,但不是我的问题的答案。我需要前端js代码来通知用户,而不是我现在正在做什么。目前我正在使用100毫秒的setInterval来检查状态是否有更好的方法,以便我不需要那样做。 –

+0

@binayr您能否给我提供关于您的'计量器'抽象的更多信息?我现在是否正确理解你,只有当有新的电表数据时,你是否需要从后端发送信息到前端? – sanddog

+0

是的,这正是我的要求。 @sanddog –