やりたかったのは
・ともかくwebsocket. これが動く環境
・んでもframeworkないとどうしようもないからなんかのframeworkとのセット
・django使ってたけどこの際だからFlask
・Flaskのinteractiveなデバッグ環境に惚れたからあれが動くようにする
・djangoとかみたいに、ソース書き替えたらリロードは必須だと思ったのでこれも動くように
てとこ。
ハマリぽいんとは
・pythonのwebsocketっていうと選択肢が狭くて、GEvent系のGEventwebsocketか、pywebsocketぐらいしかない
・んでもpywebsocketはmod-pythonだからウンコ。
・GEventwebsocketは、GEventだからこれまた癖がある
・GEventはシングルスレッドで動くから、threading.Threadとか使ってauto reloadさせようとしてもうごかない
・GEventのwebsocketがFlaskとかでつつんでしまうと応答しなくなるからWSGIServer.serve_foreverあたりはむき出しにしておかないといけない
とかまぁ、それは多くのハマリポイント。
色々やったら動いたからまぁよし。
これで快適デバッグ環境とwebsocketとFlaskだ。
pycassaについてはあまり触れない。
誰か後からきたひとのためにソース張っておく。
きれいでは無い。清書前だけどとりあえず動くだけのソース。
質問は返答できると思う。
C:\Users\myr>c:\Python26\python.exe c:\prj\groovy\src\groovy\autoreload.py c:\prj\groovy\src\groovy\groovy.py
みたいにうつと、 autoreload.pyがsubprocess.Popenで groovy.py起動しますんで。
subprocessが死なないのはwinだとそういうものなのか?やだなぁ
autoreload.py
# -*- coding: utf-8 -*-import osimport sysimport subprocessimport timedef file_times(path):for root, dirs, files in os.walk(path):# print 'rdf ', root, dirs, filesfor file in files:filename = os.path.join(root, file)# print 'load,', filenameif filename[-4:] in ('.pyc', '.pyo'):filename = filename[:-1]yield os.stat(filename).st_mtimedef print_stdout(process):stdout = process.stdoutif stdout != None:print stdout# We concatenate all of the arguments together, and treat that as the command to runcommand = ' '.join(sys.argv[1:])# The path to watchpath = 'c:\\prj\\groovy\\src'# How often we check the filesystem for changes (in seconds)wait = 1# The process to autoreloadprocess = subprocess.Popen(command, shell=True)# The current maximum file modified time under the watched directorylast_mtime = max(file_times(path))while True:max_mtime = max(file_times(path))# print "max_mtime", max_mtimeprint_stdout(process)if max_mtime > last_mtime:last_mtime = max_mtimeprint 'Restarting process.', process# print "now :",process.poll()while not process.poll():try:process.kill()except:passprocess = subprocess.Popen(command, shell=True)time.sleep(wait)
groovy.py
# -*- coding: utf-8 -*-from time import gmtime, strftimeimport osimport sysimport subprocessimport timeimport randomfrom gevent import pywsgiimport geventfrom geventwebsocket.handler import WebSocketHandlerfrom flask import Flask, request, session, g, redirect, url_for, abort, render_template, flashfrom werkzeug.debug import DebuggedApplication# demo app# configurationDATABASE = '/tmp/flaskr.db'DEBUG = TrueSECRET_KEY = 'development key'USERNAME = 'admin'PASSWORD = 'default'def handle(ws):""" This is the websocket handler function. Note that we can dispatch based on path in here, too."""if ws.path == '/echo':while True:m = ws.wait()if m is None:breakws.send(m)elif ws.path == '/data':for i in xrange(10000):ws.send("0 %s %s\n" % (i, random.random())) #ここは通信エラーが起きることがある.print "0 %s %s\n" % (i, random.random())gevent.sleep(0.1)#Flash作る. Tornadoとかでもできると思われる.app = Flask(__name__)app.debug = Trued_app = DebuggedApplication(app, True)#app.config.from_object(__name__)#app.config.from_envvar('FLASKR_SETTINGS', silent=True)def groovy(environ, start_response):path = environ["PATH_INFO"]if path == "/":return d_app(environ, start_response)elif path == '/test':start_response("200 OK", [('Content-Type', 'text/plain')])return ["blaat"]elif path == "/data":handle(environ['wsgi.websocket'])else:return d_app(environ, start_response)@app.route("/")def hello():app.logger.debug('AAAAAAAAAA value for debugging???')# return "Hello World!!!!"return render_template('base.html', name="unko")groovy_server = Nonedef run_groovy():# from werkzeug.debug import DebuggedApplicationapp.debug = True# a = DebuggedApplication(app, True)a = appserver = pywsgi.WSGIServer(('0.0.0.0', 8080), groovy, handler_class=WebSocketHandler)groovy_server = serverserver.serve_forever()print "here"#app.run(debug=True, port=8080)print sys.argv[:]print sys.executableif __name__ == "__main__":print "deketa"run_groovy()
2 件のコメント:
ぬお、preタグじゃないのか..
ソース嘘でした。他のエントリーで補足しますが、これだと子プロセスしなないでポートがめつづけるのでhttp responceがかわんないです
コメントを投稿