Python websocket-clientでBottleフレームワークと通信する

BottleフレームワークでWebSocketが使用できるよう構成し、JavaScriptで通信してみました。
BottleフレームワークでWebsocket通信を行う

Pythonからの通信を試してみます。


websocket-client



こちらを使用して接続することにしました。
https://github.com/websocket-client/websocket-client

pipでインストールしておきます。


$ pip3 install websocket-client





http通信のサンプル



jsonデータを送信しサーバー側で解析。
jsonデータの応答を返すサンプルを動かしてみることにします。

まず、http通信でのサンプル。

・app.py


  1. import json
  2. import bottle
  3. import gevent
  4. from bottle.ext.websocket import GeventWebSocketServer
  5. from bottle.ext.websocket import websocket
  6. app = bottle.Bottle()
  7. @app.route('/httpecho', method='POST')
  8. def httpecho():
  9.     body = bottle.request.body
  10.     data = body.read().decode('utf-8')
  11.     json_data = json.loads(data)
  12.     return json.dumps({'status':'ok', 'message': 'hello ' + json_data['name']})
  13. app.run(host='localhost', port=8080, reloader=True, debug=True, server=GeventWebSocketServer)




・client.py


  1. import json
  2. import urllib.request
  3. import urllib.parse
  4. url = 'http://localhost:8080/httpecho'
  5. data = json.dumps({'name': 'symfoware'})
  6. response = urllib.request.urlopen(url, data.encode('utf-8'))
  7. body = response.read().decode('utf-8')
  8. result = json.loads(body)
  9. print(result['message'])




http通信でjson通信できました。


$ python3 client.py
hello symfoware



これをWebSocket版に変更してみます。




WebSocket



WebSocket版のサンプルは以下のようになりました。

・app.py


  1. import json
  2. import bottle
  3. import gevent
  4. from bottle.ext.websocket import GeventWebSocketServer
  5. from bottle.ext.websocket import websocket
  6. app = bottle.Bottle()
  7. @app.route('/wsecho', apply=[websocket])
  8. def wsecho(ws):
  9.     while True:
  10.         body = ws.receive()
  11.         if not body:
  12.             break
  13.         
  14.         json_data = json.loads(body)
  15.         ws.send(json.dumps({'status':'ok', 'message': 'hello ' + json_data['name']}))
  16. app.run(host='localhost', port=8080, reloader=True, debug=True, server=GeventWebSocketServer)




・client.py


  1. import json
  2. import websocket
  3. url = 'ws://localhost:8080/wsecho'
  4. data = json.dumps({'name': 'symfoware'})
  5. ws = websocket.create_connection(url)
  6. ws.send(data)
  7. body = ws.recv()
  8. result = json.loads(body)
  9. print(result['message'])
  10. ws.close()




実行結果に変化はありませんが、WebSocketでの通信を確認できました。


$ python3 client.py
hello symfoware






通信速度の比較



http、WebSocket各々1,000回通信した際の速度を比較してみました。

・app.py


  1. import json
  2. import bottle
  3. import gevent
  4. from bottle.ext.websocket import GeventWebSocketServer
  5. from bottle.ext.websocket import websocket
  6. app = bottle.Bottle()
  7. @app.route('/httpecho', method='POST')
  8. def httpecho():
  9.     body = bottle.request.body
  10.     data = body.read().decode('utf-8')
  11.     json_data = json.loads(data)
  12.     return json.dumps({'status':'ok', 'message': 'hello ' + json_data['name']})
  13. @app.route('/wsecho', apply=[websocket])
  14. def wsecho(ws):
  15.     while True:
  16.         body = ws.receive()
  17.         if not body:
  18.             break
  19.         
  20.         json_data = json.loads(body)
  21.         ws.send(json.dumps({'status':'ok', 'message': 'hello ' + json_data['name']}))
  22. app.run(host='localhost', port=8080, reloader=True, debug=True, server=GeventWebSocketServer)




・client.py


  1. import json
  2. import time
  3. import urllib.request
  4. import urllib.parse
  5. import websocket
  6. def http_call():
  7.     start_time = time.perf_counter()
  8.     url = 'http://localhost:8080/httpecho'
  9.     data = json.dumps({'name': 'symfoware'})
  10.     for i in range(1000):
  11.         response = urllib.request.urlopen(url, data.encode('utf-8'))
  12.         body = response.read().decode('utf-8')
  13.         result = json.loads(body)
  14.     print('http: %.4f sec' % (time.perf_counter() - start_time))
  15.     
  16. def ws_call():
  17.     start_time = time.perf_counter()
  18.     url = 'ws://localhost:8080/wsecho'
  19.     data = json.dumps({'name': 'symfoware'})
  20.     ws = websocket.create_connection(url)
  21.     
  22.     for i in range(1000):
  23.         ws.send(data)
  24.         body = ws.recv()
  25.         result = json.loads(body)
  26.     ws.close()
  27.     print('ws: %.4f sec' % (time.perf_counter() - start_time))
  28. if __name__ == '__main__':
  29.     http_call()
  30.     ws_call()




実行結果


$ python3 client.py
http: 0.4717 sec
ws: 0.1240 sec



WebSocketの方が4倍程度高速になりました。

関連記事

コメント

非公開コメント

プロフィール

Author:symfo
blog形式だと探しにくいので、まとめサイト作成中です。
Symfoware まとめ

PR




検索フォーム

月別アーカイブ