2012-07-27 10 views
17

私は基本的な竜巻のWebSocketのテストを持っている:竜巻:ウェブソケットの接続を識別/追跡しますか?

import tornado.httpserver 
import tornado.websocket 
import tornado.ioloop 
import tornado.web 

class WSHandler(tornado.websocket.WebSocketHandler): 
    def open(self): 
     print 'new connection' 
     self.write_message("Hello World") 

    def on_message(self, message): 
     print 'message received %s' % message 

    def on_close(self): 
     print 'connection closed' 


application = tornado.web.Application([ 
    (r'/ws', WSHandler), 
]) 


if __name__ == "__main__": 
    http_server = tornado.httpserver.HTTPServer(application) 
    http_server.listen(8888) 
    tornado.ioloop.IOLoop.instance().start() 

私は(すでにやっているようだ)複数の接続を処理するだけでなく、他の接続を参照できるようにすることができるようにしたいです。私は個々の接続を識別して追跡する方法は見当たりません。接続のオープン、メッセージの受信、および接続の終了時にイベントを処理できるようにするだけです。

[編集]
キーがSec-websocket-keyであり、その値がWSHandlerオブジェクト...思考であると思っていますか? Sec-websocket-keyがどのようにして信頼できるかが一意であるかどうかはわかりません。

+0

私が知る限り、接続ごとに1つのWSHandlerインスタンスが作成されます。だから、WSHandlerは基本的に接続インターフェースだけです。たとえば、http://code.google.com/p/pyscxml/のようなネットワークの上にメッセージ処理エンジンを追加したいのですか? – Vladimir

答えて

22

最も簡単な方法は、ちょうどWSHandlerインスタンスのリストや辞書を維持することです:

class WSHandler(tornado.websocket.WebSocketHandler): 
    clients = [] 

    def open(self): 
     self.clients.append(self) 
     print 'new connection' 
     self.write_message("Hello World") 

    def on_message(self, message): 
     print 'message received %s' % message 

    def on_close(self): 
     self.clients.remove(self) 
     print 'closed connection' 

あなたが接続を識別したい場合は、例えばおそらくその情報をソケット経由で送信する必要があります。

+0

'接続を特定する場合は、おそらく、その情報をソケット経由で送る必要があります。 "ここで何を意味するのか分からないのですか?ユーザーが接続を識別する方法 – securecurve

+1

片方向(例えば)は、セッションIDをソケット上で送信し、 'on_message'でそれを処理し、' WSHandler'インスタンス(またはどこにでも)に格納することです。 –

+0

私は、おかげで:) :) – securecurve

19

コールMaclean asnwerは、すべての接続の一覧が必要なときには簡単な解決策です。あなたがWSHandlerインスタンスの外で監視することができ、より複雑なものを、必要な場合 しかし、 - 勇敢なことのようにそれを行う:ユーザーがアクセストークンを持っている場合、これはあなたのWebSocketエンドポイントに

class WSHandler(tornado.websocket.WebSocketHandler): 

    def open(self): 
     self.id = uuid.uuid4() 
     external_storage[self.id] = {'id':self.id} 
     print 'new connection' 
     self.write_message("Hello World") 

    def on_message(self, message): 
     #Some message parsing here 
     if message.type == 'set_group': 
      external_storage[self.id]['group'] = message.group 
     print 'message received %s' % message 

    def on_close(self): 
     external_storage.remove(self.id) 
     print 'closed connection' 
+0

コールの答えは私の必要とするものですが、WSHandler自体の外部でより多くの制御が必要な場合は、助けを感謝します! – Joseph

+2

ニコライ、本当に良い答えニコライ、非常に良いアイデアは、彼らが誰であることを送信することなく、あなたは簡単にそれらを識別し、メッセージを送信する/それに応じて接続を閉じることができます...良い仕事:))。そのような情報の格納はRedisで行われます。 – securecurve

+0

このシナリオを確実に処理するための確実な方法です。 – kniteli

1

を追加することができ、 SSLの上で作業してください。

ユーザーがトークンを提供していないか、指定されたトークンが期限切れになっているためにアクセストークンを使用できない場合、ユーザーは認証されず、できるだけ早くソケットを強制終了します。

ただし、これを行うには、アクセストークンを識別子を持つユーザーに関連付ける必要があります。その識別子は、開かれる前にソケットに結びつけることができます。識別子は、このユーザに結びつけられたソケットの集合である辞書キーとして機能することができる。

0

私はこの話題の起源をチェックしてこの問題を解決しました。したがって、メソッドdef check_origin(self, origin)をオーバーライドすると役に立ちます。たとえば、:

clients = {} 

class WSHandler(tornado.websocket.WebSocketHandler): 


    def check_origin(self, origin): 

     clients[origin] = self 
     print(clients) 
     return True 
関連する問題