基于flask的网页聊天室(四)

前言

接前天的内容,今天完成了消息的处理

具体内容

上次使用了flask_login做用户登录,但是直接访问login_requare装饰的函数会报401错误,这里可以自定义login_requare拦截后的操作:


@login_manager.unauthorized_handler
def unauthorized(): return redirect(url_for('auth.login'))

这样会重定向到登录页面

然后建立了用户的消息表:


class User(UserMixin,db.Model): id = db.Column(db.Integer,primary_key=True,autoincrement=True)
email = db.Column(db.String(256),unique=True,nullable=False)
username = db.Column(db.String(32),unique=True,nullable=False)
password_hash = db.Column(db.String(128))
avatar_url = db.Column(db.String(256))
messages = db.relationship('Message',back_populates='author',cascade='all') def __init__(self,**kwargs):
super(User,self).__init__(**kwargs)
if self.email is not None and self.avatar_url is None:
self.avatar_url = 'https://gravatar.com/avatar/'+hashlib.md5(self.email.encode('utf-8')).hexdigest()+'?d=identicon' class Message(db.Model):
id = db.Column(db.Integer,primary_key=True,autoincrement=True)
content = db.Column(db.Text,nullable=False)
create_time = db.Column(db.DateTime,default=datetime.utcnow,index=True)
author_id = db.Column(db.Integer,db.ForeignKey('user.id'))
author = db.relationship('User',back_populates='messages')

然后用bootstarp做了个消息的显示以及发送的页面,再自己随便改吧改吧。

接下来就是怎样做消息的发送以及接收了

这里使用websocket的方式,它可以使客户端与服务端建立起全双工的通信方式

客户端使用socket.io.js,服务端使用flask-socketio扩展

于是首先要pip安装flask-socketio

然后:


from flask_socketio import SocketIO
socketio = SocketIO(app, async_mode='eventlet') socketio.run(app,host='0.0.0.0')

像上边这样把原来的app启动改一下,eventlet是服务器,它支持websocket,必须要先pip安装

然后具体处理消息,首先是消息的发送:

在前端

首先要引入socket.io.js,然后


function send() {
//点击发送按钮
$('#send_button').click(function () {
var content = $('#text_area').val().trim();
if (content==""){ }else {
socket.emit('new_message',content);
$('#text_area').val("")
}
})
}

通过socket.emit,把消息发送到服务端new_message就是相当于这个事件的名称,content作为参数传递

在服务端:


@socketio.on('new_message')
def new_message(content):
print(content)
message = models.Message(author=current_user._get_current_object(),content=clean_html(content))
db.session.add(message)
db.session.commit()
emit('new_message',{'message_html':render_template('message.html',message=message)},broadcast=True)

用装饰器socketio.on(‘new_message’)装饰的函数就是new_message的事件处理,这里把它存入表中,并返回一个消息的html字符串,传入message对象渲染,broadcast=True表示广播,意思是所有与服务端建立websocket链接的都能收到该消息

接下来是客户端消息的显示:


function get() {
socket.on('new_message',function (data) {
$('#message_container').append(data.message_html);
scrollToEnd(); })
}

这里同样用socket.on方法接受客户端返回的信息,并把它添加到显示区域,并把滚轮滚到底部。

除此之外,每次访问浏览器页面我默认设置的是显示历史10条消息,之后可能会添加历史消息刷新


@chat.route('/chat', methods=['GET', "POST"],endpoint='chat')
@login_required
def chatroom():
if request.method == 'GET':
message_list = db.session.query(models.Message).order_by(models.Message.id).all()
message_list.reverse()
message_list = message_list[:9]
message_list.reverse()
return render_template('chatroom.html',message_list=message_list)

到这里,基本的内容就算完成了,下面是一个效果图,是我用手机和电脑交互的:

总结

聊天室的内容基本完成,最初目标已经达到,代码放在了github上,如果之后有空还会再完善或添加功能

基于flask的网页聊天室(四)的更多相关文章

  1. 基于flask的网页聊天室(三)

    基于flask的网页聊天室(三) 前言 继续上一次的内容,今天完成了csrf防御的添加,用户头像的存储以及用户的登录状态 具体内容 首先是添加csrf的防御,为整个app添加防御: from flas ...

  2. 基于flask的网页聊天室(二)

    基于flask的网页聊天室(二) 前言 接上一次的内容继续完善,今天完成的内容不是很多,只是简单的用户注册登录,内容具体如下 具体内容 这次要加入与数据哭交互的操作,所以首先要建立相关表结构,这里使用 ...

  3. 基于flask的网页聊天室(一)

    基于flask的网页聊天室(一) 基本目标 基于flask实现的web聊天室,具有基本的登录注册,多人发送消息,接受消息 扩展目标 除基本目标外添加当前在线人数,消息回复,markdown支持,历史消 ...

  4. Java和WebSocket开发网页聊天室

    小编心语:咳咳咳,今天又是聊天室,到现在为止小编已经分享了不下两个了,这一次跟之前的又不大相同,这一次是网页聊天室,具体怎么着,还请各位看官往下看~ Java和WebSocket开发网页聊天室 一.项 ...

  5. JavaWeb网页聊天室(WebSocket即时通讯)

    原文:http://baike.xsoftlab.net/view/656.html Git地址 http://git.oschina.net/loopcc/WebSocketChat 概要: Web ...

  6. workerman-chat(PHP开发的基于Websocket协议的聊天室框架)(thinkphp也是支持socket聊天的)

    workerman-chat(PHP开发的基于Websocket协议的聊天室框架)(thinkphp也是支持socket聊天的) 一.总结 1.下面链接里面还有一个来聊的php聊天室源码可以学习 2. ...

  7. WebSocket 网页聊天室

    先给大家开一个原始的websocket的连接使用范例 <?php /* * recv是从套接口接收数据,也就是拿过来,但是不知道是什么 * read是读取拿过来的数据,就是要知道recv过来的是 ...

  8. SpringBoot基于websocket的网页聊天

    一.入门简介正常聊天程序需要使用消息组件ActiveMQ或者Kafka等,这里是一个Websocket入门程序. 有人有疑问这个技术有什么作用,为什么要有它?其实我们虽然有http协议,但是它有一个缺 ...

  9. WebSocket 网页聊天室的实现(服务器端:.net + windows服务,前端:Html5)

    websocket是HTML5中的比较有特色一块,它使得以往在客户端软件中常用的socket在web程序中也能轻松的使用,较大的提高了效率.废话不多说,直接进入题. 网页聊天室包括2个部分,后端服务器 ...

随机推荐

  1. P1251 递推专练3

    递推专练3 描述 Description 圆周上有N个点.连接任意多条(可能是0条)不相交的弦(共用端点也算相交)共有多少种方案? 输入格式 Input Format 读入一个数N.<=N< ...

  2. NOIp2017真题模拟赛 By cellur925

    果然我还是最菜的==不接受反驳 (先考了day2喵喵喵) Day2 T1:奶酪 期望得分:100分 实际得分:100分 考察:并查集 思路:这题其实之前做过了==.思路还是比较清晰的,读入时预处理出可 ...

  3. Mantis优化改造(功能篇)

    共分为两篇,功能篇和技术篇. 时间大约是2016年冬天. 考虑搭一个用于Bug管理和追踪的系统. 综合比较下,选择了小巧的开源工具,Mantis. 在源码基础上,做代码修改,完成了定制版的优化改造. ...

  4. Educational Codeforces Round 46 (Rated for Div. 2) C. Covered Points Count

    Bryce1010模板 http://codeforces.com/problemset/problem/1000/C 题意:问你从[l,r]区间的被多少条线覆盖,列出所有答案. 思路:类似括号匹配的 ...

  5. Error: IO_ERROR : java.io.IOException: Error while connecting Oozie server. No of retries = 5. Exception = Connection refused (Connection refused)解决办法(图文详解)

    不多说,直接上干货! 问题详情 解决办法 Copy/Paste oozie.services property tag set from oozie-default.xml to oozie-site ...

  6. iOS面试题之runloop

    本文围绕以下几个部分展开对runloop的叙述. 1.runloop是什么/runloop的概念? 2.NSRunLoop 和 CFRunLoopRef? 3.runloop和线程的关系? 4.run ...

  7. bootstrap CSS表单、按钮和字体图标

    基础表单   <form role="form">     <div class="form-group">         <l ...

  8. iOS 利用UIWebView与JavaScript交互的最简单办法

    这里说的是针对iOS的!并且方法很简单!!并且验证可行的!!! 1, UIWebView调用 JavaScript 的函数: NSString* strValue = [webView stringB ...

  9. 毕业设计:HomeFragment(二)

    一.长按item时的响应 在长按item时,我希望能让CheckBox显示出来,并且呼出全选.反选.取消菜单,以及下载.删除.移动.复制操作菜单. 我在具体实现的时候发现处理item布局是一个很大的问 ...

  10. OCP 11g 第四章练习

    练习 4-1 配置Oracle Net 在本练习中, 将使用图形化工具和命令行工具来建立一个完整的Oracle Net 环境. 由此, 读者可看出在Windows 和 Linux 系统中的区别. 1. ...