BLEやPiCameraを外からコントロールしたいと思ったけど、PHPとかのページから叩くのはなんか違うと思ったので、TornadoでWebSocketのサーバを作ってみた。内容はこことここの組み合わせ。
Tornadoのインストール
pip install tornado
サーバープログラム
ここのサーバーサイドのコードほぼまんま。ここにある方法でデーモン化。デーモンになると何やってるかわからんので、/var/log/websocket_server.logになんか吐き出すようにしている。on_messageがサンプルのままでAPIサーバーでもなく、ただのエコーサーバーだけど、中身は後でネタに応じて実装するということで。
websocket_server.service
[Unit]
Description=Websocket server daemon
[Service]
ExecStart=/usr/local/sbin/websocket_serverd.py
Restart=always
Type=forking
PIDFile=/var/run/websocket_serverd.pid
[Install]
WantedBy=multi-user.target
websocket_serverd.py
#!/usr/bin/python
# -*- coding: utf-8 -*-
import socket
import os
import sys
import tornado.httpserver
import tornado.websocket
import tornado.ioloop
import tornado.web
WS_LISTENING_PORT = '41072'
class WebSocketServer(tornado.websocket.WebSocketHandler):
'''WebSocket event handler class'''
_log_file = None
def open(self):
if self._log_file is None:
self._log_file = open('/var/log/websocket_server.log', 'at')
self._log_file.write('WebSocketServer::open : new connection')
def on_message(self, message):
self._log_file.write(
'WebSocketServer::on_message : message received: %s\r\n' %
message)
self._log_file.write(
'WebSocketServer::on_message : sending back message: %s\r\n' %
message[::-1])
self.write_message(message[::-1])
def on_close(self):
if self._log_file is not None:
self._log_file.write(
'WebSocketServer::on_close : connection closed\r\n')
self._log_file.close()
self._log_file = None
def check_origin(self, origin):
return True
def websocket_handler_main(app):
'''websocket main procedure'''
pid = os.fork()
if pid > 0:
pid_file = open('/var/run/websocket_serverd.pid', 'w')
pid_file.write(str(pid)+"\n")
pid_file.close()
sys.exit()
if pid == 0:
http_server = tornado.httpserver.HTTPServer(app)
http_server.listen(WS_LISTENING_PORT)
my_ip = socket.gethostbyname(socket.gethostname())
print('*** Websocket Server Started at %s***' % my_ip)
tornado.ioloop.IOLoop.instance().start()
APP = tornado.web.Application([
(r'/ws', WebSocketServer),
])
if __name__ == "__main__":
websocket_handler_main(APP)
インストール
こんな手順で
chmod 755 ./websocket_serverd.py
cp ./websocket_serverd.py /usr/local/sbin
mkdir /usr/lib/systemd/system
sudo cp ./websocket_server.service /usr/lib/systemd/system
sudo systemctl daemon-reload
sudo systemctl enable websocket_server
再起動かsystemctlでサービス開始。クライアントプログラムはここに載っているHTMLのコードをそのまま使う。