新聞中心
今天從頭開始做一個(gè)在線聊天網(wǎng)站,網(wǎng)上各種各樣的聊天工具已經(jīng)很多了,為啥還要做這么一個(gè)聊天工具呢,無他,興趣耳!

成都創(chuàng)新互聯(lián)堅(jiān)持“要么做到,要么別承諾”的工作理念,服務(wù)領(lǐng)域包括:網(wǎng)站設(shè)計(jì)、成都網(wǎng)站設(shè)計(jì)、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣等服務(wù),滿足客戶于互聯(lián)網(wǎng)時(shí)代的城關(guān)網(wǎng)站設(shè)計(jì)、移動(dòng)媒體設(shè)計(jì)的需求,幫助企業(yè)找到有效的互聯(lián)網(wǎng)解決方案。努力成為您成熟可靠的網(wǎng)絡(luò)建設(shè)合作伙伴!
今天先完成第一部分,搭建起聊天網(wǎng)站的整體框架。
整體技術(shù)棧
- flask 框架
- flask_login 的使用
- jquery 簡(jiǎn)單應(yīng)用
搭建權(quán)限框架
還是使用 Flask 來搭建后臺(tái)應(yīng)用,使用 flask-login 擴(kuò)展來處理用戶登陸鑒權(quán)邏輯。首先定義登陸表單。
class LoginForm(FlaskForm):
username = StringField('Username', validators=[DataRequired(), ])
password = PasswordField('Password', validators=[DataRequired()])
remember_me = BooleanField('Keep me logged in')
submit = SubmitField('Log in')
一個(gè)簡(jiǎn)單的登陸表單,不做過多解釋。
接下來定義數(shù)據(jù)庫結(jié)構(gòu)。
class User(UserMixin, db.Model):
__tablename__ = 'users'
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(64), unique=True, index=True)
password = db.Column(db.String(64))
當(dāng)前,我們只需要一個(gè) user 用戶表,只包含三個(gè)字段的簡(jiǎn)單表。用戶密碼也只是簡(jiǎn)單的保存了明文,后面再處理用戶密碼的 hash 問題。
下面就可以定義用戶登陸表單
from flask_login import LoginManager
login_manager = LoginManager()
login_manager.session_protection = 'strong'
login_manager.login_view = 'login'
app = Flask(__name__)
login_manager.init_app(app)
app.config['SECRET_KEY'] = 'hardtohard'
@login_manager.user_loader
def load_user(user_id):
return User.query.get(int(user_id))
@app.route('/login', methods=['GET', 'POST'])
def login():
form = LoginForm()
if form.validate_on_submit():
user = User.query.filter_by(username=form.username.data).first()
if user:
login_user(user)
return redirect(url_for('chat'))
return render_template('login.html', form=form)
這里定義了,只檢查用戶名是否存在,如果存在,就執(zhí)行 login_user() 函數(shù),登陸。用戶密碼的使用,也留到后面再做處理。
其中 load_user,是回調(diào)函數(shù),將獲取到的 user 對(duì)象存儲(chǔ)到瀏覽器的 session 中,然后在調(diào)用 login_user 函數(shù)時(shí),就會(huì)調(diào)用 load_user 來把真正需要登陸的用戶設(shè)置到 session 中。當(dāng)?shù)顷懗晒?,就?huì)跳轉(zhuǎn)到 chat 函數(shù)所對(duì)應(yīng)的頁面。
chat 函數(shù)比較簡(jiǎn)單,只是展示一個(gè)網(wǎng)頁
@app.route('/chat', methods=['GET', 'POST'])
@login_required
def chat():
return render_template('chat.html')使用 login_required 裝飾器,保證該函數(shù)只允許登陸的用戶訪問。
增加些初始化函數(shù)
@app.route('/adddb', methods=['GET', 'POST'])
def addbd():
db.create_all()
return "OK"
@app.route('/deldb', methods=['GET', 'POST'])
def delbd():
db.drop_all()
return "OK"
@app.route('/adduser/', methods=['GET', 'POST'])
def adduser(user):
user = User(username=user, password='admin')
db.session.add(user)
db.session.commit()
return "OK" 增加了初始化數(shù)據(jù)庫和新增用戶的函數(shù)。
構(gòu)建前端頁面
首先處理登陸頁面,在 login.html 中添加
{% extends "bootstrap/base.html" %}
{% import "bootstrap/wtf.html" as wtf %}
{% block title %}Flasky{% endblock %}
{% block navbar %}
{% endblock %}
{% block content %}
Hello, Welcome!
{{ wtf.quick_form(form) }}
{% endblock %}使用擴(kuò)展庫 flask_bootstrap 來快速構(gòu)建頁面。
下面重點(diǎn)來看看 chat 頁面,主要使用了 Ajax 來處理文字交互。首先來看看主體頁面,在 chat.html 中填入代碼
{% extends 'bootstrap/base.html' %}
{% import "bootstrap/wtf.html" as wtf %}
{% block title %}Kung Fu Realm{%endblock %}
{% block head %}
Hi Hi 聊天室
{% endblock %}
{% block content %}
整體效果如下,是不是挺少女系的。
當(dāng)用戶在點(diǎn)擊“提交”按鈕后,調(diào)用 JS 函數(shù)
/*用戶登陸的用戶點(diǎn)擊提交按鈕發(fā)送消息按鈕*/
$('#sub_but_login').click(function(event){
sendMessageLogin(event, fromname, to_uid, to_uname);
});
為了后面便于擴(kuò)展,將未登錄的用戶特別區(qū)分開來,后面也許同樣允許未登陸用戶訪問該頁面,但是只能同機(jī)器人小黃鴨聊天
/*用戶未登陸的用戶點(diǎn)擊提交按鈕發(fā)送消息按鈕*/
$('#sub_but').click(function(event){
sendMessage(event, fromname, to_uid, to_uname);
});
再來看函數(shù) sendMessageLogin
function sendMessageLogin(event, from_name, to_uid, to_uname){
var msg = $("#message").val();
var myDate = new Date();
var myTime = myDate.toLocaleTimeString();
var itTime = myDate.toLocaleString();
//var iTime = myDate.toDateString();
var htmlData = ''
+ ' {% if current_user.is_authenticated %}
{% endif %}'
+ ' '
+ ' ' + msg + ''
+ ' ' + from_name + ' · ' + itTime +''
+ ' '
+ '';
$("#message_box").append(htmlData);
$('#message_box').scrollTop($("#message_box")[0].scrollHeight + 20);
$("#message").val('');
setTimeout(function(){sendToServer(from_name, msg)}, 1000); //延時(shí)調(diào)用
}接收幾個(gè)參數(shù),然后將當(dāng)前會(huì)話消息追加到 HTML 頁面中,并且調(diào)用真正的后臺(tái) API 函數(shù) sendToServer
function sendToServer(name, msg){
var xmlhttp = new XMLHttpRequest();
var myDate = new Date();
//var myTime = myDate.toLocaleTimeString();
var myTime = myDate.toLocaleString();
xmlhttp.notallow=function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
myObj = xmlhttp.responseText;
var htmlData2 = ''
+ '
'
+ ' '
+ ' ' + myObj + ''
+ ' ' + '小黃鴨' + ' · ' + myTime +''
+ ' '
+ '';
$("#message_box").append(htmlData2);
$('#message_box').scrollTop($("#message_box")[0].scrollHeight + 20);
}
}
xmlhttp.open("GET", "/api/sendchat/" + msg, true);
xmlhttp.send();
};sendToServer 函數(shù)調(diào)用后臺(tái) API,并把接收到的消息回寫到 HTML 頁面中。
而目前的后臺(tái) API 也比較簡(jiǎn)單,直接返回用戶輸入的消息
@app.route('/api/sendchat/', methods=['GET', 'POST'])
@login_required
def send_chat(info):
return info 這樣,一個(gè)整體的聊天室架子就搭建好了,后面我們?cè)俳尤?redis 和自己訓(xùn)練的聊天機(jī)器人,來實(shí)現(xiàn)真正的在線聊天室。
當(dāng)前標(biāo)題:用Python從頭搭建一個(gè)在線聊天室
URL分享:http://fisionsoft.com.cn/article/cddcjis.html


咨詢
建站咨詢
}})
