2011-12-07 6 views
1

私はTwistedでロングポーリングサーバーを作成しようとしていますが、私はリクエスト管理について理解していません。Twisted Longpoll Server:切断後にリクエストループが続く

クライアントがページから移動すると、コンソールでループが続きます。クライアントが切断するとインスタンスが破壊されると思っていました。

これが私の目標です。接続するクライアントごとにDataServiceのロジックを個別に実行したいと考えています。

ここで私が持っているものだ。(私は簡単に消費のためにダウンし、このコードを刻んだ、そのため、いくつかの構文エラーであってもよいが、それは動作するコードから来たかもしれません)

class DataService(Resource): 
    def __init__(self, sid): 
     # set looping call 
     self.loopingCall = task.LoopingCall(self.__print_data) 
     self.loopingCall.start(5, False) 
     Resource.__init__(self) 
     self.sid = int(sid); 
     self.finished = False 

     # initialize response 
     self.response = response = {'status':1, 'message': 'OK', 'time':int(time.time()), 'data': {}} 

    def connectionLost(self, reason): 
     self.loopingCall.stop(); 

    def render_GET(self, request): 
     # response will be json format 
     request.setHeader('Content-Type', 'application/json') 
     # make sure required GET vars exist 
     if 'lastupdate' not in request.args: 
      self.loopingCall.stop() 
      return ujson.dumps({'status':0,'message':'invalid query','data':{}}) 

     # set last update timestamp from query string 
     self.lastupdate = int(request.args['lastupdate'][0]) 

     # set self.request so we can access it in __print_data 
     self.request = request 
     # call print data 
     self.__print_data() 

     if not self.finished: 
      return server.NOT_DONE_YET 

    def __print_data(self): 

     # set updated data 
     if self.lastupdate < self.myappobj.lastupdate 
      self.response{'data']['items'] = {'foo':'bar'} 

     # if updates were found, close loop, print, and finish request 
     if len(response['data']) > 0: 
      self.loopingCall.stop() 
      self.request.write(self.jsonpcallback+'('+ujson.dumps(response)+')') 
      self.request.finish() 
      self.finished = True 


class DataServer(Resource): 
    def getChild(self, sid, request): 
     return DataService(sid) 

答えて

1

クライアントが離れてから移動するときページ、私はそれがコンソールでループを続けて見ることができます。クライアントが切断するとインスタンスが破壊されると思っていました。

これはありません。最初に、インスタンスは、「到達可能」になっていなくても破棄されます(他の種類のオブジェクトと同じように)。

あなたが行う場合は、この:

self.loopingCall = task.LoopingCall(self.__print_data) 

あなたはselfへの参照を持っているself.__print_dataへの参照を、作成しています。 LoopingCallは、原子炉に自身を登録します(起動時に)。だから、リアクターはselfへの間接参照を持っています。したがって、selfは永遠に、または何かが変わるまで生き続けます。

LoopingCallを反応炉から登録解除することができます。リアクタがもはやLoopingCallを参照しなくなると、それはもはやインスタンス(self)が生きている状態に保たれなくなります。

クライアントが接続を閉じるときにこれを行う場合は、Request.notifyFinishを使用します。これはcovered in the Twisted documentationですが、それはかなり簡単です。あなたはこのような何かをする必要があります

request.notifyFinish().addErrback(lambda ignored: self.loopingcall.stop()) 

あなたが唯一のクライアントが接続ではなく、あなたが接続を閉じるケースを閉じた場合を気にするのでそれはエラーバックです。

+0

よく説明された回答ありがとう! – Coder1

関連する問題