自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

用 Python 從頭搭建一個在線聊天室

開發(fā) 前端
我們只需要一個 user 用戶表,只包含三個字段的簡單表。用戶密碼也只是簡單的保存了明文,后面再處理用戶密碼的 hash 問題。

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

今天先完成第一部分,搭建起聊天網(wǎng)站的整體框架。

整體技術(shù)棧

  • flask 框架
  • flask_login 的使用
  • jquery 簡單應(yīng)用

搭建權(quán)限框架

還是使用 Flask 來搭建后臺應(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')

一個簡單的登陸表單,不做過多解釋。

接下來定義數(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)前,我們只需要一個 user 用戶表,只包含三個字段的簡單表。用戶密碼也只是簡單的保存了明文,后面再處理用戶密碼的 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 對象存儲到瀏覽器的 session 中,然后在調(diào)用 login_user 函數(shù)時,就會調(diào)用 load_user 來把真正需要登陸的用戶設(shè)置到 session 中。當(dāng)?shù)顷懗晒?,就會跳轉(zhuǎn)到 chat 函數(shù)所對應(yīng)的頁面。

chat 函數(shù)比較簡單,只是展示一個網(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/<user>', 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 %}
<div class="navbar navbar-inverse" role="navigation">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="/">Flasky</a>
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li><a href="/">Home</a></li>
</ul>
<ul class="nav navbar-nav navbar-right">
{% if current_user.is_authenticated %}
<li><a href="{{ url_for('logout') }}">Logout</a></li>
{% else %}
<li><a href="{{ url_for('login') }}">Login</a></li>
{% endif %}
</ul>
</div>
</div>
</div> {% endblock %}

{% block content %}
<div class="container">
<div class="page-header">
<h1>Hello, Welcome!</h1>
</div>
{{ wtf.quick_form(form) }}
</div>
{% 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 %}
<head>
<meta charset="utf-8">
<title>Hi Hi 聊天室</title>
<link rel="shortcut icon" href="{{ url_for('static',filename='chat/images/hihi.jpg')}}">
<link rel="icon" href="{{ url_for('static',filename='chat/images/hihi.jpg')}}" type="image/x-icon">
<link type="text/css" rel="stylesheet" href="/static/chat/css/style.css">
<script type="text/javascript" src="{{ url_for('static', filename='chat/js/jquery.min.js') }}"></script>
</head>
{% endblock %}
{% block content %}
<body>
<div class="chatbox">
<div class="chat_top fn-clear">
<div class="uinfo fn-clear" style="float: left;"><div class="uface"><h1 style="color: #7777">ROOM: 聊天室123哈哈哈</h1></div></div>
<div class="uinfo fn-clear">
{% if current_user.is_authenticated %}
<div class="uface"><img src="{{ url_for('static', filename='chat/images/hi.jpg') }}" width="40" height="40" alt=""/></div>
{% else %}
<div class="uface"><img src="{{ url_for('static', filename='chat/images/hi.jpg')}}" width="40" height="40" alt=""/></div>
{% endif %}
<div class="uname">
小HI<i class="fontico down"></i>
<ul class="managerbox">
{% if current_user.is_authenticated %}
<li><a href="{{ url_for('login') }}"><i class="fontico lock"></i>退出登陸</a></li>
{% else %}
<li><a href="{{ url_for('logout') }}"><i class="fontico logout"></i>登錄</a></li>
{% endif %}
</ul>
</div>
</div>
</div>
<div class="chat_message fn-clear">
<div class="chat_left">
<div class="message_box" id="message_box">
<div class="msg_item fn-clear">
<div class="uface"><img src="{{ url_for('static', filename='chat/images/duck.jpg')}}" width="40" height="40" alt=""/></div>
<div class="item_right">
<div class="msg own"><img src="{{ url_for('static', filename='chat/images/hihi.jpg')}}" width="400" height="400" alt=""/></div>
<div class="name_time">小黃鴨 </div>
</div>
</div>
{% if current_user.is_authenticated %}
<div class="msg_item fn-clear">
<div class="uface"><img src="{{ url_for('static', filename='chat/images/duck.jpg')}}" width="40" height="40" alt=""/></div>
<div class="item_right">
<div class="msg">Welcome to Hihi Chat Room. 歡迎來到 Hihi 聊天室。 </div>
<div class="name_time">小黃鴨 </div>
</div>
</div>
{% else %}
<div class="msg_item fn-clear">
<div class="uface"><img src="{{ url_for('static', filename='chat/images/duck.jpg')}}" width="40" height="40" alt=""/></div>
<div class="item_right">
<div class="msg">您還沒有登陸,先和小黃鴨聊聊吧。 </div>
<div class="name_time">小黃鴨 </div>
</div>
</div>
{% endif %}
</div>
<div class="write_box">
{% if current_user.is_authenticated %}
<textarea id="message" name="message" class="write_area" placeholder="說點(diǎn)啥吧..."></textarea>
{% else %}
<textarea id="message_not" name="message" class="write_area" placeholder="說點(diǎn)啥吧..."></textarea>
{% endif %}
<input type="hidden" name="fromname" id="fromname" value="你" />
<input type="hidden" name="to_uid" id="to_uid" value="0">
<div class="facebox fn-clear">
<div class="expression"></div>
<div class="chat_type" id="chat_type">群聊</div>
{% if current_user.is_authenticated %}
<button name="login" class="sub_but" id="sub_but_login">提 交</button>
{% else %}
<button name="logout" class="sub_but" id="sub_but">提 交</button>
{% endif %}
</div>
</div>
</div>
</div>
</div>

整體效果如下,是不是挺少女系的。

圖片

當(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 = '<div class="msg_item fn-clear">'
+ ' <div class="uface">{% if current_user.is_authenticated %}<img src="{{ url_for('static', filename='chat/images/hi.jpg') }}" width="40" height="40" alt=""/>{% endif %}</div>'
+ ' <div class="item_right">'
+ ' <div class="msg own">' + msg + '</div>'
+ ' <div class="name_time">' + from_name + ' · ' + itTime +'</div>'
+ ' </div>'
+ '</div>';
$("#message_box").append(htmlData);
$('#message_box').scrollTop($("#message_box")[0].scrollHeight + 20);
$("#message").val('');
setTimeout(function(){sendToServer(from_name, msg)}, 1000); //延時調(diào)用
}

接收幾個參數(shù),然后將當(dāng)前會話消息追加到 HTML 頁面中,并且調(diào)用真正的后臺 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 = '<div class="msg_item fn-clear">'
+ ' <div class="uface"><img src="{{ url_for('static', filename='chat/images/duck.jpg')}}" width="40" height="40" alt=""/></div>'
+ ' <div class="item_right">'
+ ' <div class="msg">' + myObj + '</div>'
+ ' <div class="name_time">' + '小黃鴨' + ' · ' + myTime +'</div>'
+ ' </div>'
+ '</div>';
$("#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)用后臺 API,并把接收到的消息回寫到 HTML 頁面中。

而目前的后臺 API 也比較簡單,直接返回用戶輸入的消息

@app.route('/api/sendchat/<info>', methods=['GET', 'POST'])
@login_required
def send_chat(info):
return info

這樣,一個整體的聊天室架子就搭建好了,后面我們再接入 redis 和自己訓(xùn)練的聊天機(jī)器人,來實(shí)現(xiàn)真正的在線聊天室。

責(zé)任編輯:武曉燕 來源: 蘿卜大雜燴
相關(guān)推薦

2024-01-18 11:15:46

Pythonsocket聊天室

2024-04-03 15:20:08

2021-02-06 23:26:25

聊天室開發(fā)WebSocket

2023-01-13 00:02:41

2023-01-05 09:17:58

2011-12-15 11:11:51

JavaNIO

2023-02-10 08:16:48

WebSocket簡易聊天室

2022-07-26 14:53:10

WebSocket網(wǎng)絡(luò)通信協(xié)議

2022-04-18 10:36:48

社交軟件聊天平臺rocket.cha

2015-07-06 10:42:18

PHP聊天室應(yīng)用

2021-11-16 09:38:10

鴻蒙HarmonyOS應(yīng)用

2013-11-27 10:46:31

JavaEEWebsockets

2021-10-14 18:46:29

Websocket瀏覽器API

2015-10-19 17:38:01

AnsibleDocker應(yīng)用部署

2022-12-01 08:25:23

eTsTCP聊天室

2011-06-09 15:44:29

Spring

2021-12-09 16:48:25

鴻蒙HarmonyOS應(yīng)用

2020-07-03 10:21:48

Go框架Docker

2011-11-30 16:37:58

sync

2022-09-30 13:55:46

Python機(jī)器人
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號