2016-12-06 13 views
0

Webソケットが新しくなっています。私はバックエンドに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ミリ秒のバックエンドに空白のWebソケットのリクエスト要求を作っています。これは私にとって非常に悪い解決策に思えます。バックエンドに複数のsend()を行い、メーターの読み取り値の変更だけをユーザーに通知することなく、これを行うより良い方法はありますか?

また、私はこれをより良い方法で行うためにMQTTプロトコルを使用しました。誰かがどのように実装することができますか?あなたは竜巻がwrite_messageメソッドを介してクライアントにpingを実行するためにいくつかのイベントを必要と気づくことができたよう

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()}) 

+0

ここで何を求めているのかはっきりしません。そのコードをすべてMQTTに置き換えたいですか? – hardillb

+0

@hardillb私は100ミリ秒ごとにサーバーにsend()を行う必要がないように、より良い解決策が必要です。 –

+0

あなたはすでに何を試してみましたか、うまくいかないものを修正するのを手伝ってくれますが、それをすべてあなたのために書くつもりはありませんか? – hardillb

答えて

0

あなたはほとんどここあなたの問題への解決策を見つけました。あなたはこのように、イベントとして簡単なタイムアウトコールに変更しようと、このようなイベントとして、クライアントからの新しいメッセージを使用している:

# 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() 

PeriodicCallbackおよびその他のオプションの詳細についてtornado.ioloop documentationをチェックしてください。

トルネードをMQTTプロトコルに使用する場合は、トルネードでは不可能です。あなたは例えばemqtt serverを試すことができますが、これは実際のサーバーであり、アプリケーションを書くためのフレームワークではありませんので、IMHOよりも徹底して、竜巻を使ってWebソケットを介してpingすることができます。

+0

これは定期的なコールバックとチェックを行うための本当に非常に良いアプローチですが、私の質問に対する答えではありません。私はフロントエンドのjsコードが、私は今やっているのではなく、ユーザーに通知する必要があります。現在、私は100ミリ秒のsetIntervalを使ってステータスをチェックしていますので、これを行う必要はありません。 –

+0

@binayrあなたの 'メートル'抽象化についてもっと詳しく教えてください。私はあなたを正しく理解していますか?新しいメーターデータがあるときだけ、バックエンドからフロントエンドにメッセージを送信する必要がありますか? – sanddog

+0

はい、それは私の要求です。 @sanddog –

関連する問題