目录整体技术栈搭建权限框架构建前端页面今天从头开始做一个在线聊天网站,网上各种各样的聊天工具已经很多了,为啥还要做这么一个聊天工具呢,无他,兴趣耳!今天先完成第一部分,搭建起聊天网站的整体框架。整体技...
目录
整体技术栈搭建权限框架
构建前端页面
今天从头开始做一个在线聊天网站,网上各种各样的聊天工具已经很多了,为啥还要做这么一个聊天工具呢,无他,兴趣耳!
今天先完成第一部分,搭建起聊天网站的整体框架。
整体技术栈
flask 框架flask_login 的使用
jquery 简单应用
搭建权限框架
还是使用 Flask 来搭建后台应用,使用 flask-login 扩展来处理用户登陆鉴权逻辑。
首先定义登陆表单
classLoginForm(FlaskForm):
username=StringField('Username',validators=[DataRequired(),])
password=PasswordField('Password',validators=[DataRequired()])
remember_me=BooleanField('Keepmeloggedin')
submit=SubmitField('Login')
一个简单的登陆表单,不做过多解释
接下来定义数据库结构
classUser(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))
当前,我们只需要一个 user 用户表,只包含三个字段的简单表。用户密码也只是简单的保存了明文,后面再处理用户密码的 hash 问题。
下面就可以定义用户登陆表单
fromflask_loginimportLoginManager
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
defload_user(user_id):
returnUser.query.get(int(user_id))
@app.route('/login',methods=['GET','POST'])
deflogin():
form=LoginForm()
ifform.validate_on_submit():
user=User.query.filter_by(username=form.username.data).first()
ifuser:
login_user(user)
returnredirect(url_for('chat'))
returnrender_template('login.html',form=form)
这里定义了,只检查用户名是否存在,如果存在,就执行 login_user() 函数,登陆。用户密码的使用,也留到后面再做处理。
其中 load_user,是回调函数,将获取到的 user 对象存储到浏览器的 session 中,然后在调用 login_user 函数时,就会调用 load_user 来把真正需要登陆的用户设置到 session 中。当登陆成功后,就会跳转到 chat 函数所对应的页面。
chat 函数比较简单,只是展示一个网页
@app.route('/chat',methods=['GET','POST'])
@login_required
defchat():
returnrender_template('chat.html')
使用 login_required 装饰器,保证该函数只允许登陆的用户访问。
增加些初始化函数
@app.route('/adddb',methods=['GET','POST'])
defaddbd():
db.create_all()
return"OK"
@app.route('/deldb',methods=['GET','POST'])
defdelbd():
db.drop_all()
return"OK"
@app.route('/adduser/<user>',methods=['GET','POST'])
defadduser(user):
user=User(username=user,password='admin')
db.session.add(user)
db.session.commit()
return"OK"
增加了初始化数据库和新增用户的函数。
构建前端页面
首先处理登陆页面,在 login.html 中添加
{%extends"bootstrap/base.html"%}
{%import"bootstrap/wtf.html"aswtf%}
{%blocktitle%}Flasky{%endblock%}
{%blocknavbar%}
<divclass="naVBArnavbar-inverse"role="navigation">
<divclass="container">
<divclass="navbar-header">
<buttontype="button"class="navbar-toggle"data-toggle="collapse"data-target=".navbar-collapse">
<spanclass="sr-only">Togglenavigation</span>
<spanclass="icon-bar"></span>
<spanclass="icon-bar"></span>
<spanclass="icon-bar"></span>
</button>
<aclass="navbar-brand"href="/" rel="external nofollow" rel="external nofollow" >Flasky</a>
</div>
<divclass="navbar-collapsecollapse">
<ulclass="navnavbar-nav">
<li><ahref="/" rel="external nofollow" rel="external nofollow" >Home</a></li>
</ul>
<ulclass="navnavbar-navnavbar-right">
{%ifcurrent_user.is_authenticated%}
<li><ahref="{{url_for('logout')}}" rel="external nofollow" rel="external nofollow" >Logout</a></li>
{%else%}
<li><ahref="{{url_for('login')}}" rel="external nofollow" rel="external nofollow" >Login</a></li>
{%endif%}
</ul>
</div>
</div>
</div>{%endblock%}
{%blockcontent%}
<divclass="container">
<divclass="page-header">
<h1>Hello,Welcome!</h1>
</div>
{{wtf.quick_form(form)}}
</div>
{%endblock%}
使用扩展库 flask_bootstrap 来快速构建页面。
下面重点来看看 chat 页面,主要使用了 AJAX 来处理文字交互。
首先来看看主体页面,在 chat.html 中填入代码
{%extends'bootstrap/base.html'%}
{%import"bootstrap/wtf.html"aswtf%}
{%blocktitle%}KungFuRealm{%endblock%}
{%blockhead%}
<head>
<metacharset="utf-8">
<title>HiHi聊天室</title>
<linkrel="shortcuticon"href="{{url_for('static',filename='chat/images/hihi.jpg')}}" rel="external nofollow" rel="external nofollow" >
<linkrel="icon"href="{{url_for('static',filename='chat/images/hihi.jpg')}}" rel="external nofollow" rel="external nofollow" type="image/x-icon">
<linktype="text/css"rel="stylesheet"href="/static/chat/css/style.css" rel="external nofollow" >
<scripttype="text/Javascript"src="{{url_for('static',filename='chat/js/jquery.min.js')}}"></script>
</head>
{%endblock%}
{%blockcontent%}
<body>
<divclass="chatbox">
<divclass="chat_topfn-clear">
<divclass="uinfofn-clear"style="float:left;"><divclass="uface"><h1style="color:#7777">ROOM:聊天室123哈哈哈</h1></div></div>
<divclass="uinfofn-clear">
{%ifcurrent_user.is_authenticated%}
<divclass="uface"><imgsrc="{{url_for('static',filename='chat/images/hi.jpg')}}"width="40"height="40"alt="基于python实现从头搭建一个在线聊天室框架"/></div>
{%else%}
<divclass="uface"><imgsrc="{{url_for('static',filename='chat/images/hi.jpg')}}"width="40"height="40"alt="基于Python实现从头搭建一个在线聊天室框架"/></div>
{%endif%}
<divclass="uname">
小HI<iclass="fonticodown"></i>
<ulclass="managerbox">
{%ifcurrent_user.is_authenticated%}
<li><ahref="{{url_for('login')}}" rel="external nofollow" rel="external nofollow" ><iclass="fonticolock"></i>退出登陆</a></li>
{%else%}
<li><ahref="{{url_for('logout')}}" rel="external nofollow" rel="external nofollow" ><iclass="fonticologout"></i>登录</a></li>
{%endif%}
</ul>
</div>
</div>
</div>
<divclass="chat_messagefn-clear">
<divclass="chat_left">
<divclass="message_box"id="message_box">
<divclass="msg_itemfn-clear">
<divclass="uface"><imgsrc="{{url_for('static',filename='chat/images/duck.jpg')}}"width="40"height="40"alt="基于Python实现从头搭建一个在线聊天室框架"/></div>
<divclass="item_right">
<divclass="msgown"><imgsrc="{{url_for('static',filename='chat/images/hihi.jpg')}}"width="400"height="400"alt="基于Python实现从头搭建一个在线聊天室框架"/></div>
<divclass="name_time">小黄鸭</div>
</div>
</div>
{%ifcurrent_user.is_authenticated%}
<divclass="msg_itemfn-clear">
<divclass="uface"><imgsrc="{{url_for('static',filename='chat/images/duck.jpg')}}"width="40"height="40"alt="基于Python实现从头搭建一个在线聊天室框架"/></div>
<divclass="item_right">
<divclass="msg">Welcome to Hihi Chat Room. 欢迎来到 Hihi 聊天室。</div>
<divclass="name_time">小黄鸭</div>
</div>
</div>
{%else%}
<divclass="msg_itemfn-clear">
<divclass="uface"><imgsrc="{{url_for('static',filename='chat/images/duck.jpg')}}"width="40"height="40"alt="基于Python实现从头搭建一个在线聊天室框架"/></div>
<divclass="item_right">
<divclass="msg">您还没有登陆,先和小黄鸭聊聊吧。</div>
<divclass="name_time">小黄鸭</div>
</div>
</div>
{%endif%}
</div>
<divclass="write_box">
{%ifcurrent_user.is_authenticated%}
<textareaid="message"name="message"class="write_area"placeholder="说点啥吧..."></textarea>
{%else%}
<textareaid="message_not"name="message"class="write_area"placeholder="说点啥吧..."></textarea>
{%endif%}
<inputtype="hidden"name="fromname"id="fromname"value="你"/>
<inputtype="hidden"name="to_uid"id="to_uid"value="0">
<divclass="faceboxfn-clear">
<divclass="expression"></div>
<divclass="chat_type"id="chat_type">群聊</div>
{%ifcurrent_user.is_authenticated%}
<buttonname="login"class="sub_but"id="sub_but_login">提交</button>
{%else%}
<buttonname="logout"class="sub_but"id="sub_but">提交</button>
{%endif%}
</div>
</div>
</div>
</div>
</div>
整体效果如下,是不是挺少女系的。

当用户在点击“提交”按钮后,调用 JS 函数
/*用户登陆的用户点击提交按钮发送消息按钮*/
$('#sub_but_login').click(function(event){
sendMessageLogin(event,fromname,to_uid,to_uname);
});
为了后面便于扩展,将未登录的用户特别区分开来,后面也许同样允许未登陆用户访问该页面,但是只能同机器人小黄鸭聊天
/*用户未登陆的用户点击提交按钮发送消息按钮*/
$('#sub_but').click(function(event){
sendMessage(event,fromname,to_uid,to_uname);
});
再来看函数 sendMessageLogin
functionsendMessageLogin(event,from_name,to_uid,to_uname){
varmsg=$("#message").val();
varmyDate=newDate();
varmyTime=myDate.toLocaleTimeString();
varitTime=myDate.toLocaleString();
//variTime=myDate.toDateString();
varhtmlData='<divclass="msg_itemfn-clear">'
+'<divclass="uface">{%ifcurrent_user.is_authenticated%}<imgsrc="{{url_for('static',filename='chat/images/hi.jpg')}}"width="40"height="40"alt="基于Python实现从头搭建一个在线聊天室框架"/>{%endif%}</div>'
+'<divclass="item_right">'
+'<divclass="msgown">'+msg+'</div>'
+'<divclass="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);//延时调用
}
接收几个参数,然后将当前会话消息追加到 HTML 页面中,并且调用真正的后台 API 函数 sendToServer
functionsendToServer(name,msg){
varXMLhttp=newXMLHttpRequest();
varmyDate=newDate();
//varmyTime=myDate.toLocaleTimeString();
varmyTime=myDate.toLocaleString();
xmlhttp.onreadystatechange=function(){
if(xmlhttp.readyState==4&&xmlhttp.status==200){
myObj=xmlhttp.responseText;
varhtmlData2='<divclass="msg_itemfn-clear">'
+'<divclass="uface"><imgsrc="{{url_for('static',filename='chat/images/duck.jpg')}}"width="40"height="40"alt="基于Python实现从头搭建一个在线聊天室框架"/></div>'
+'<divclass="item_right">'
+'<divclass="msg">'+myObj+'</div>'
+'<divclass="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 函数调用后台 API,并把接收到的消息回写到 HTML 页面中。
而目前的后台 API 也比较简单,直接返回用户输入的消息
@app.route('/api/sendchat/<info>',methods=['GET','POST'])
@login_required
defsend_chat(info):
returninfo
这样,一个整体的聊天室架子就搭建好了,后面我们再接入 Redis 和自己训练的聊天机器人,来实现真正的在线聊天室。
到此这篇关于基于Python实现从头搭建一个在线聊天室的文章就介绍到这了,更多相关Python在线聊天室内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!










