アナリティクス

2017年6月26日月曜日

Tornadoを使ったWebAPIサーバ(の素)

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のコードをそのまま使う。

0 件のコメント:

コメントを投稿