2016-12-06 4 views
0

Я новичок в веб-сокетах. Я использую tornado/python для своего back-end и написал следующий код.Уведомление 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 Я хочу лучшее решение, так что мне не нужно будет отправлять send() на сервер каждые 100 миллисекунд. –

+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 метод. Вы используете новое сообщение от клиента в качестве такого события, попробуйте изменить на простой вызов таймаута как событие, например:

# 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, но это фактический сервер, а не фреймворк для написания приложений, поэтому ИМХО было бы более всеобъемлющим, чтобы пинговать через веб-сокет с торнадо.

+0

Это действительно очень хороший подход для периодического вызова и проверки, но не ответ на мой вопрос. Мне нужен код js front-end для уведомления пользователя, а не того, что я делаю прямо сейчас. В настоящее время я использую setInterval в 100 миллисекунд, чтобы проверить статус, есть ли лучший способ, чтобы мне не нужно было это делать. –

+0

@binayr Не могли бы вы дать больше информации о вашей абстракции 'meter'? Я правильно понял вас сейчас, вам нужно отправить сообщение на передний конец с заднего конца только тогда, когда есть новые данные счетчика? – sanddog

+0

Да, именно это мое требование. @sanddog –

 Смежные вопросы

  • Нет связанных вопросов^_^