基本かもしれないですけど。
なんで今更?ってtornado使ってWebSocketでやりとりしていた時
Javascriptでコールバックメソッド名送る
→ tornadoで指定されたメソッドを実行して、Javascriptにコールバック関数名送る
→ Javascriptで指定されたコールバック関数を実行する
ってやりたくて文字列からメソッドを呼び出しをしたかったのです。
まずはJavascript、WebSocket接続してtornado側の呼び出しメソッド名とその他のパラメータを送ります。
パラメータはJSONで送ってます。
var ws = new WebSocket('ws://server/ws');
var p = {};
// callbackメソッド名
p['callback'] = 'wake_up';
// その他のパラメータ
p['msg'] = 'Wake Up!!!!';
ws.send(JSON.stringify(p));
ws.onmessage = function(e) {
var data = JSON.parse(e.data);
console.log(data['message']);
};
tornado側、on_messageのgetattrが今回の表題のメイン部分です。
app.py
from tornado import ioloop,web,websocket
import json
# callbackクラス
from callback import Callback
class WSHandler(websocket.WebSocketHandler):
# メッセージが来た時
def on_message(self, message):
data = json.loads(message)
# Callbackクラスのインスタンス作成
cb = Callback(data)
# メソッド呼び出し
result = getattr(cb, data['callback'])()
# Javascriptに返す値
return_value = {}
return_value['message'] = result
# WebSocketでメッセージ送信
self.write_message(json.dumps(return_value))
handlers = [
(r'/ws', WSHandler),
]
settings = dict(
debug = False,
)
app = web.Application(handlers, **settings)
app.listen(sys.argv[1])
ioloop.IOLoop.instance().start()
呼び出されるメソッドです。
callback.py
class Callback(data):
def __init__(self, data):
self.data = data
def wake_up(self):
return self.data['msg']
これでブラウザのコンソールに'Wake Up!!!!’と表示されるはずです。
getattrの使い方は以下の通りです。詳細は公式ドキュメントに委ねます。
cb = Callback(data)
result = cb.wake_up()
# 上記は下記コードと同じです
result2 = getattr(cb, 'wake_up')()
# 因みに以下のようにやると返り値が返らずオブジェクトが代入されます
result3 = getattr(cb, 'wake_up')
最初上のresult3のようにやってしまい???ってなりましたが、考えてみればですよね〜ってなりました。。。
2013-03-15追記
微妙に間違いを修正しました。
失礼しました。