BETA

【Python】AdminLTEとWebSocketでチャット機能を作ってみる その2(ログイン機能)

投稿日:2019-01-21
最終更新:2019-01-21
※この記事は外部サイト(https://www.doraxdora.com/blog/2018/10/06/...)からのクロス投稿です

チャットの実装ですが、
ユーザー毎の制御(トークルームみたいな)を実現するためにMySQLにマスタを持たせて、ひとまずログイン機能を実装します。

プログラムは前回のものを流用します。
【Python】AdminLTEとWebSocketでチャット機能を作ってみる その1(とりあえず版)

下準備


今回から、MySQLを使っていきますのでその下準備を。
次のテーブルを作成してデータを登録しておきます。

テーブル

-- パスワードマスタ  
create table MST_PASSWORD (  
  USER_ID varchar(20) not null comment 'ユーザーID'  
  , PASSWORD varchar(128) not null comment 'パスワード'  
  , CREATE_USER varchar(20) comment '作成者'  
  , CREATE_DATE datetime comment '作成日時'  
  , UPDATE_USER varchar(20) comment '更新者'  
  , UPDATE_DATE datetime comment '更新日時'  
  , constraint MST_PASSWORD_PKC primary key (USER_ID)  
) comment 'パスワードマスタ' ;  

-- ユーザマスタ  
create table MST_USER (  
  USER_ID varchar(20) not null comment 'ユーザーID'  
  , USER_NAME varchar(60) not null comment 'ユーザー名'  
  , ICON varchar(20) comment 'アイコン:画像ファイル名'  
  , MESSAGE varchar(50) comment '一言メッセージ'  
  , CREATE_USER varchar(20) comment '作成者'  
  , CREATE_DATE datetime comment '作成日時'  
  , UPDATE_USER varchar(20) comment '更新者'  
  , UPDATE_DATE datetime comment '更新日時'  
  , constraint MST_USER_PKC primary key (USER_ID)  
) comment 'ユーザマスタ' ;

データ

-- MSTユーザー  
DELETE FROM MST_USER;  
INSERT INTO MST_USER VALUES('001','そら','sora.jpg','いいことないかな','INIT',NULL,NULL,NULL);  
INSERT INTO MST_USER VALUES('002','りく','riku.jpg','ちゅーるちゅーるちゃおちゅーるー','INIT',NULL,NULL,NULL);  
INSERT INTO MST_USER VALUES('003','うみ','umi.jpg','誰かブラッシングしてくれないかしら','INIT',NULL,NULL,NULL);  
INSERT INTO MST_USER VALUES('004','こうめ','koume.jpg','ごはんまだ?','INIT',NULL,NULL,NULL);  
INSERT INTO MST_USER VALUES('005','こなつ','konatsu.jpg','早く新しい家に引っ越ししたい','INIT',NULL,NULL,NULL);  

-- MSTパスワード  
DELETE FROM MST_PASSWORD  
INSERT INTO MST_PASSWORD VALUES('001','001','INIT',NULL,NULL,NULL);  
INSERT INTO MST_PASSWORD VALUES('002','002','INIT',NULL,NULL,NULL);  
INSERT INTO MST_PASSWORD VALUES('003','003','INIT',NULL,NULL,NULL);  
INSERT INTO MST_PASSWORD VALUES('004','004','INIT',NULL,NULL,NULL);  
INSERT INTO MST_PASSWORD VALUES('005','005','INIT',NULL,NULL,NULL);

 

ライブラリの追加


次の2つを、「メニュー」>「Default Settings」よりインストールします。

  • mysql-connector-python-rf

  • configparser

フォルダ構成


フォルダ構成は次のようになります。
前回からの変更点は、conf、Daoあたりですかね。
SampleChat  
│ Main.py  
│  
├─conf  
│     db.config  
│  
├─Dao  
│     MstPasswordDao.py  
│     MstUserDao.py  
│     SqlClient.py  
│  
├─static  
│ ├─css  
│ │ │     AdminLTE.css  
│ │ │     AdminLTE.min.css  
│ │ │     login.css  
│ │ │     style.css  
│ │ │  
│ │ └─skins  
│ │             skin-blue.css  
│ │             skin-blue.min.css  
│ │  
│ ├─img  
│ │     konatsu.jpg  
│ │     koume.jpg  
│ │     riku.jpg  
│ │     sora.jpg  
│ │     umi.jpg  
│ │  
│ └─js  
│         adminlte.min.js  
│         script.js  
│  
└─templates  
login.html  
main.html

画面

ログイン画面


以前記事に書いた【Python】FullCalendarにログイン機能をつけてみる を流用しました。

画面

login.html

<!DOCTYPE html>  
<html lang="en">  
    <head>  
        <meta charset="UTF-8">  
        <title>チャットサンプル- ログイン</title>  
        <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">  
        <link rel="stylesheet" href="{{ static_url('css/login.css') }}"/>  
           <link rel="stylesheet" href="https:////maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">  
        <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>  
        <script type="text/javascript" src="https://stackpath.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>  
        <script type="text/javascript">  
            function submitLogin() {  
                $("#loginForm").submit();  
            }  
        </script>  
    </head>  
    <body>  
        <form id="loginForm" method="post" action="/login">  
            <div class="jumbotron">  
                <div class="container">  
                    <span class="fa fa-comments"></span>  
                    <h2>チャットサンプル</h2>  
                    <div class="box">  
                        {% module xsrf_form_html() %}  
                        <input id="inputUserId" name="user_id" type="text" placeholder="ユーザーID">  
                        <input id="inputPassword" name="password" type="password" placeholder="パスワード">  
                        <span class="errMsg">{{ error_msg }}</span>  
                        <button class="btn btn-default full-width" onclick="submitLogin()">  
                            <span class="glyphicon glyphicon-ok"></span>  
                        </button>  
                    </div>  
                </div>  
            </div>  
        </form>  
    </body>  
</html>

スタイル

login.css

body {  
    background: #ffbb55 none repeat scroll 0 0;  
}  

.jumbotron {  
    text-align: center;  
    width: 35rem;  
    border-radius: 0.5rem;  
    top: 0;  
    bottom: 0;  
    left: 0;  
    right: 0;  
    position: absolute;  
    margin: 4rem auto;  
    background-color: #fff;  
    padding: 2rem;  
    height:45rem;  
}  

.container .fa {  
    font-size: 10rem;  
    margin-top: 3rem;  
    color: #f96145;  
}  

input {  
    width: 100%;  
    margin-bottom: 1.4rem;  
    padding: 1rem;  
    background-color: #ecf2f4;  
    border-radius: 0.2rem;  
    border: none;  
}  
h2 {  
    margin-bottom: 3rem;  
    font-weight: bold;  
    color: #ababab;  
}  
.btn {  
    border-radius: 0.2rem;  
}  
.btn .glyphicon {  
    font-size: 3rem;  
    color: #fff;  
}  
.full-width {  
    background-color: #8eb5e2;  
    width: 100%;  
    -webkit-border-top-right-radius: 0;  
    -webkit-border-bottom-right-radius: 0;  
    -moz-border-radius-topright: 0;  
    -moz-border-radius-bottomright: 0;  
    border-top-right-radius: 0;  
    border-bottom-right-radius: 0;  
}  

.box {  
    position: absolute;  
    bottom: 0;  
    left: 0;  
    margin-bottom: 3rem;  
    margin-left: 3rem;  
    margin-right: 3rem;  
}  

span.errMsg {  
    color: #f96145;  
    font-size: 11px;  
}

メイン画面


ヘッダーメニューを追加、
OSSのCSS、JSはCDNから取得するように変更しました。

main.html

<!DOCTYPE html>  
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja">  
<head>  
    <meta charset="utf-8">  
    <meta http-equiv="X-UA-Compatible" content="IE=edge">  
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">  
    <title>チャットサンプル</title>  
    <meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport">  
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">  
    <link rel="stylesheet" href="https:////maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">  
    <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,600,700,300italic,400italic,600italic">  
    <link rel="stylesheet" href="{{ static_url('css/AdminLTE.min.css') }}">  
    <link rel="stylesheet" href="{{ static_url('css/style.css') }}">  
    <link rel="stylesheet" href="{{ static_url('css/skins/skin-blue.min.css') }}">  
</head>  
<body class="hold-transition fixed">  
    <form id="logoutForm" action="/logout" method="get">  
        {% module xsrf_form_html() %}  
    </form>  
    <nav class="navbar navbar-default">  
        <div class="container-fluid">  
            <!-- 2.ヘッダ情報 -->  
            <div class="navbar-header" style="padding:15px;">  
                ユーザー名:{{ user_name }}  
            </div>  
            <!-- 3.リストの配置 -->  
            <ul class="nav navbar-nav">  
                <li class="active"><a href="#">チャット</a></li>  
                <li><a href="#">メニュー1</a></li>  
                <li><a href="#">メニュー2</a></li>  
            </ul>  
            <!-- 4.ボタン -->  
            <button type="button" class="pull-right btn btn-default navbar-btn" onclick="logout();">  
                ログアウト&amp;nbsp;<span class="fa fa-sign-out"></span>  
            </button>  
        </div>  
    </nav>  

    <section class="content container-fluid">  
        <div class="row">  
            <!-- Left col -->  
            <div class="col-xs-8">  
                <!-- /.box -->  
                <div class="row">  
                    <div class="col-xs-8">  
                        <!-- DIRECT CHAT -->  
                        <div id="chat-panel" class="box box-warning direct-chat direct-chat-warning box-solid" style="display:none;">  
                            <div class="box-header with-border">  
                                <h3 class="box-title">チャットメッセージ</h3>  
                                <div class="box-tools pull-right">  
                                    <span id="status" class="status"></span>  
                                    <span data-toggle="tooltip" title="3 New Messages" class="badge bg-yellow">3</span>  
                                    <button type="button" class="btn btn-box-tool" data-widget="collapse"><i class="fa fa-minus"></i></button>  
                                    <button type="button" class="btn btn-box-tool" data-toggle="tooltip" title="Contacts" data-widget="chat-pane-toggle">  
                                        <i class="fa fa-comments"></i>  
                                    </button>  
                                    <button type="button" class="btn btn-box-tool" data-widget="remove"><i class="fa fa-times"></i></button>  
                                </div>  
                            </div>  
                            <!-- /.box-header -->  
                            <div class="box-body">  
                                <!-- Conversations are loaded here -->  
                                <div class="direct-chat-messages">  
                                    <!-- Message. Default to the left -->  
                                    <div class="direct-chat-msg">  
                                        <div class="direct-chat-info clearfix">  
                                            <span class="direct-chat-name pull-left">こなつ</span>  
                                            <span class="direct-chat-timestamp pull-right">2018/09/25(月) 02:00</span>  
                                        </div>  
                                        <!-- /.direct-chat-info -->  
                                        <img class="direct-chat-img" src="static/img/konatsu.jpg" alt="message user image">  
                                        <!-- /.direct-chat-img -->  
                                        <div class="direct-chat-text">  
                                            そら最近どうしてる?  
                                        </div>  
                                        <!-- /.direct-chat-text -->  
                                    </div>  
                                    <!-- /.direct-chat-msg -->  
                                    <!-- Message to the right -->  
                                    <div class="direct-chat-msg right">  
                                        <div class="direct-chat-info clearfix">  
                                            <span class="direct-chat-name pull-right">そら</span>  
                                            <span class="direct-chat-timestamp pull-left">2018/09/25(月) 02:05</span>  
                                        </div>  
                                        <!-- /.direct-chat-info -->  
                                        <img class="direct-chat-img" src="static/img/sora.jpg" alt="message user image">  
                                        <!-- /.direct-chat-img -->  
                                        <div class="direct-chat-text">  
                                            相変わらずだよ。<BR>  
                                            あいつらの面倒で手一杯でさ。  
                                        </div>  
                                        <!-- /.direct-chat-text -->  
                                    </div>  
                                    <!-- /.direct-chat-msg -->  
                                    <!-- Message. Default to the left -->  
                                    <div class="direct-chat-msg">  
                                        <div class="direct-chat-info clearfix">  
                                            <span class="direct-chat-name pull-left">こなつ</span>  
                                            <span class="direct-chat-timestamp pull-right">2018/09/25(月) 05:37</span>  
                                        </div>  
                                        <!-- /.direct-chat-info -->  
                                        <img class="direct-chat-img" src="static/img/konatsu.jpg" alt="message user image">  
                                        <!-- /.direct-chat-img -->  
                                        <div class="direct-chat-text">  
                                            一番のお兄さんだから大変ね。<BR>  
                                            私は一人で快適な暮らしを送っているわ(^^♪  
                                        </div>  
                                        <!-- /.direct-chat-text -->  
                                    </div>  
                                    <!-- /.direct-chat-msg -->  
                                    <!-- Message to the right -->  
                                    <div class="direct-chat-msg right">  
                                        <div class="direct-chat-info clearfix">  
                                            <span class="direct-chat-name pull-right">そら</span>  
                                            <span class="direct-chat-timestamp pull-left">2018/09/25(月) 06:10</span>  
                                        </div>  
                                        <!-- /.direct-chat-info -->  
                                        <img class="direct-chat-img" src="static/img/sora.jpg" alt="message user image">  
                                        <!-- /.direct-chat-img -->  
                                        <div class="direct-chat-text">  
                                            え、なにそれ自慢ですか?  
                                        </div>  
                                        <!-- /.direct-chat-text -->  
                                    </div>  
                                    <!-- /.direct-chat-msg -->  
                                </div>  
                                <!--/.direct-chat-messages-->  
                                <!-- Contacts are loaded here -->  
                                <div class="direct-chat-contacts">  
                                    <ul class="contacts-list">  
                                        <li>  
                                            <a href="#">  
                                                <img class="contacts-list-img" src="static/img/konatsu.jpg" alt="User Image">  
                                                <div class="contacts-list-info">  
                                                    <span class="contacts-list-name">  
                                                        こなつ  
                                                        <small class="contacts-list-date pull-right">2018/09/25(月)</small>  
                                                    </span>  
                                                    <span class="contacts-list-msg">早く新しい家に引っ越ししたい。</span>  
                                                </div>  
                                                <!-- /.contacts-list-info -->  
                                            </a>  
                                        </li>  
                                        <li>  
                                            <a href="#">  
                                                <img class="contacts-list-img" src="static/img/umi.jpg" alt="User Image">  
                                                <div class="contacts-list-info">  
                                                    <span class="contacts-list-name">  
                                                        うみ  
                                                        <small class="contacts-list-date pull-right">2018/09/25(月)</small>  
                                                    </span>  
                                                    <span class="contacts-list-msg">誰かブラッシングしてくれないかしら。</span>  
                                                </div>  
                                                <!-- /.contacts-list-info -->  
                                            </a>  
                                        </li>  
                                        <li>  
                                            <a href="#">  
                                                <img class="contacts-list-img" src="static/img/koume.jpg" alt="User Image">  
                                                <div class="contacts-list-info">  
                                                    <span class="contacts-list-name">  
                                                        こうめ  
                                                        <small class="contacts-list-date pull-right">2018/09/24(日)</small>  
                                                    </span>  
                                                    <span class="contacts-list-msg">ちゅーるちゅーるちゃおちゅーるー</span>  
                                                </div>  
                                                <!-- /.contacts-list-info -->  
                                            </a>  
                                        </li>  
                                        <li>  
                                            <a href="#">  
                                                <img class="contacts-list-img" src="static/img/riku.jpg" alt="User Image">  
                                                <div class="contacts-list-info">  
                                                    <span class="contacts-list-name">  
                                                        りく  
                                                        <small class="contacts-list-date pull-right">2018/09/12(水)</small>  
                                                    </span>  
                                                    <span class="contacts-list-msg">ごはんまだ?</span>  
                                                </div>  
                                                <!-- /.contacts-list-info -->  
                                            </a>  
                                        </li>  
                                        <!-- End Contact Item -->  
                                    </ul>  
                                    <!-- /.contatcts-list -->  
                                </div>  
                                <!-- /.direct-chat-pane -->  
                            </div>  
                            <!-- /.box-body -->  
                            <div class="box-footer">  
                                <form action="#" method="post">  
                                    <div class="input-group">  
                                        <input id="message" type="text" name="message" placeholder="Type Message ..." class="form-control">  
                                        <span class="input-group-btn">  
                                            <button id="sendButton" type="button" class="btn btn-warning btn-flat">Send</button>  
                                        </span>  
                                    </div>  
                                </form>  
                            </div>  
                            <!-- /.box-footer-->  
                        </div>  
                        <!--/.direct-chat -->  
                    </div>  
                    <!-- /.col -->  
                </div>  
                <!-- /.col -->  
            </div>  
        </div>  
    </section>  
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>  
    <script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.8.19/jquery-ui.min.js"></script>  
    <script src="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>  
    <script src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.10.6/moment.js"></script>  
    <script src="{{ static_url('js/adminlte.min.js') }}"></script>  
    <script src="{{ static_url('js/script.js') }}"></script>  
    <script>  
        $(document).ready( function () {  
            initialize();  
        } );  
    </script>  
    </body>  
</html>

プログラム

新規追加


MySQLとやり取りするクラスを新規で作成します。

Dao/SqlClient.py

import mysql.connector  
from contextlib import closing  
import configparser  


class SqlClient:  
    """  
    SQLクライアントクラス.  
    """  

    def __init__(self, host=None, port=None, user=None, password=None, database=None):  
        """  
        イニシャライザ  
        :param host:  
        :param port:  
        :param user:  
        :param password:  
        :param database:  
        """  

        conf = configparser.ConfigParser()  
        conf.read("conf/db.config")  

        # 指定されていないパラメータは設定ファイルから読み込み  
        host = host if host is not None else conf.get("MySQL", "host")  
        port = port if port is not None else conf.get("MySQL", "port")  
        user = user if user is not None else conf.get("MySQL", "user")  
        password = password if password is not None else conf.get("MySQL", "password")  
        database = database if database is not None else conf.get("MySQL", "database")  

        self.config = {  
            "host": host,  
            "port": port,  
            "user": user,  
            "password": password,  
            "database": database  
        }  

    def select(self, sql, data=None):  
        """  
        データを検索します  
        :param sql:  
        :param data:  
        :return:  
        """  

        with closing(mysql.connector.connect(**self.config)) as conn:  
            c = conn.cursor(dictionary=True)  
            c.execute(sql, data)  

            return c.fetchall()  

    def execute(self, sql, data):  
        """  
        クエリを実行します.  
        :param sql:  
        :param data:  
        :return:  
        """  

        with closing(mysql.connector.connect(**self.config)) as conn:  
            c = conn.cursor()  
            c.execute(sql, data)  
            c.close()  
            conn.commit()

さらに、それぞれのテーブルよりデータを取得するためのクラスを追加。

Dao/MstUserDao.py

from Dao.SqlClient import SqlClient  


class MstUserDao(SqlClient):  
    """  
    MSTユーザーDAOクラス  
    """  

    def select_user(self, user_id):  
        """  
        ユーザIDを指定してデータを取得します  
        :param user_id:  
        :return:  
        """  
        sql = "SELECT * FROM MST_USER WHERE USER_ID = %s"  

        data = super().select(sql, [user_id])  
        if len(data) > 0:  
            return self.mapping_data(data[0])  

        return None  

    @staticmethod  
    def mapping_data(record):  
        """  
        レコードをマッピングします  
        :param record:  
        :return:  
        """  
        dic = {  
            "user_id": record['USER_ID'],  
            "user_name": record['USER_NAME'],  
            "icon": record['ICON'],  
            "message": record['MESSAGE'],  
            "createUser": record['CREATE_USER'],  
            "createDate": record['CREATE_DATE'],  
            "updateUser": record['UPDATE_USER'],  
            "updateDate": record['UPDATE_DATE']}  

        return dic

 

MstPasswordDao.py

from Dao.SqlClient import SqlClient  


class MstPasswordDao(SqlClient):  
    """  
    MSTパスワードDAOクラス  
    """  

    def select_password(self, user_id):  
        """  
        ユーザIDを指定してパスワードを取得します  
        :param user_id:  
        :return:  
        """  
        sql = "SELECT * FROM MST_PASSWORD WHERE USER_ID = %s"  

        data = super().select(sql, [user_id])  
        if len(data) > 0:  
            dic = self.mapping_data(data[0])  
            return dic['password']  

        return ""  

    @staticmethod  
    def mapping_data(record):  
        """  
        レコードをマッピングします  
        :param record:  
        :return:  
        """  
        dic = {  
            "user_id": record['USER_ID'],  
            "password": record['PASSWORD'],  
            "createUser": record['CREATE_USER'],  
            "createDate": record['CREATE_DATE'],  
            "updateUser": record['UPDATE_USER'],  
            "updateDate": record['UPDATE_DATE']}  

        return dic

既存クラスの修正


メイン処理にログイン機能を追加します。
# --- coding: utf-8 ---  
"""  
チャットサンプル  
"""  

import os  
import logging  

import tornado.web  
import tornado.ioloop  
import tornado.websocket  

from tornado.web import RequestHandler  
from tornado.options import options  
from tornado.websocket import WebSocketHandler  
from Dao.MstPasswordDao import MstPasswordDao  
from Dao.MstUserDao import MstUserDao  


client = []  

class AuthBaseHandler(RequestHandler):  
    """  
    認証ハンドラー基底クラス  
    """  
    cookie_user_id = "user_id"  

    def get_current_user(self):  
        logging.info("AuthBaseHandler [get_current_user]")  

        user_id = self.get_secure_cookie(self.cookie_user_id)  
        if not user_id:  
            return ""  
        return user_id.decode("UTF-8")  

    def set_current_user(self, user_id):  
        logging.info("AuthBaseHandler [set_current_user]")  

        self.set_secure_cookie(self.cookie_user_id, user_id)  

    def clear_current_user(self):  
        logging.info("AuthBaseHandler [clear_current_user]")  

        self.clear_cookie(self.cookie_user_id)  


class AuthLoginHandler(AuthBaseHandler):  
    """  
    ログインハンドラー  
    """  

    def get(self):  
        logging.info("AuthLoginHandler [get]")  

        self.render("Login.html", error_msg="")  

    def post(self):  
        logging.info("AuthLoginHandler [post]")  

        self.check_xsrf_cookie()  

        # 認証処理  
        input_user_id = self.get_argument("user_id")  
        input_password = self.get_argument("password")  

        dao = MstPasswordDao()  
        password = dao.select_password(input_user_id)  

        # 入力されたパスワードと保存されているパスワードをチェック  
        is_auth = False if input_password != password else True  

        if is_auth:  
            self.set_current_user(input_user_id)  
            self.redirect("/main")  
        else:  
            self.render("login.html", error_msg="ユーザーコードまたはパスワードが間違っています。")  


class AuthLogoutHandler(AuthBaseHandler):  
    """  
    ログアウトハンドラー  
    """  

    def get(self):  
        self.clear_current_user()  
        self.redirect('/login')  


class MainHandler(AuthBaseHandler):  
    """  
    初期表示処理  
    """  

    def initialize(self):  
        logging.info("[MainHandler] initialize")  

    @tornado.web.authenticated  
    def get(self):  
        logging.info("[MainHandler] get")  

        dao = MstUserDao()  
        user = dao.select_user(self.get_current_user())  
        user_name = user['user_name']  

        self.render("main.html", user_name=user_name)  


class ChatHandler(WebSocketHandler):  
    """  
    チャット処理  
    """  

    def open(self):  
        logging.info("[ChatHandler] open")  

        if self not in client:  
            client.append(self)  

    def on_message(self, message):  
        logging.info("[ChatHandler] on_message : " + message)  

        for cl in client:  
            cl.write_message(message)  

    def on_close(self):  
        logging.info("[ChatHandler] on_close")  

        if self in client:  
            client.remove(self)  


application = tornado.web.Application([  
    (r"/login", AuthLoginHandler),  
    (r"/logout", AuthLogoutHandler),  
    (r"/main", MainHandler),  
    (r"/chat", ChatHandler),  
],  
    template_path=os.path.join(os.getcwd(),  "templates"),  
    static_path=os.path.join(os.getcwd(),  "static"),  
    login_url="/login",  
    cookie_secret="adfaskljfwepmaldskf:as;k",  
    xsrf_cookies=True  
)  

if __name__ == "__main__":  
    tornado.options.parse_command_line()  
    application.listen(8888)  
    logging.info("server started")  
    tornado.ioloop.IOLoop.instance().start()

起動してみる


ユーザID、パスワードを入力してボタンをクリック。

チャット画面が表示されました。

まとめ


ログイン自体は以前もやったので大したことはなかったのですが、トークルームの実装について悩んでいます。
(複数人でのチャットや入室、退室をどうしよう)

とりあえず次回はデータを取得して表示するのと、メッセージ送信時にDBに登録するところをやってみようかと思います。

ではでは。

技術ブログをはじめよう Qrunch(クランチ)は、プログラマの技術アプトプットに特化したブログサービスです
駆け出しエンジニアからエキスパートまで全ての方々のアウトプットを歓迎しております!
or 外部アカウントで 登録 / ログイン する
クランチについてもっと詳しく

この記事が掲載されているブログ

@doraxdoraの技術ブログ 主に Java, C#, Python, Javascript の記事を載せていく予定。

よく一緒に読まれる記事

0件のコメント

ブログ開設 or ログイン してコメントを送ってみよう
目次をみる
技術ブログをはじめよう Qrunch(クランチ)は、プログラマの技術アプトプットに特化したブログサービスです
or 外部アカウントではじめる
10秒で技術ブログが作れます!