2016-12-06 54 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 –