最近没事儿看下Flask
,相比Django
简直小的不要不要的,单个文件几行代码就完成了路由视图,使用websocker
与之结合写一个自动回复聊天程序竟然也只用了15行代码。
线上效果图
这个小程序用到了flask
、websocket
、wsgi
,前端使用了html+css+vue
。因为只是演示,所以没考虑使用webpack
打包,代码包含简单注释,所以就不再详细解释每行代码了。依次附上代码:
注:本地ip
为:10.10.10.238
Flask
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| import json
from flask import Flask, request from geventwebsocket.handler import WebSocketHandler from gevent.pywsgi import WSGIServer
app = Flask(__name__)
@app.route('/msg') def msg(): user_socker = request.environ.get('wsgi.websocket') while 1: msg = user_socker.receive() res = {"id" : 0, "user" : 'https://pic.qqtn.com/up/2018-2/15175580434330335.gif', "msg" : '您刚才发送的消息为:【'+str(msg)+'】'} user_socker.send(json.dumps(res)) if __name__ == '__main__': http_server = WSGIServer(('0.0.0.0', 9687), app, handler_class=WebSocketHandler) http_server.serve_forever()
|
前端代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207
| <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>聊天窗口</title> <style> * { margin: 0; padding: 0; list-style: none; font-family: '微软雅黑' }
.container { width: 450px; height: 780px; background: #eee; margin: 80px auto 0; position: relative; box-shadow: 20px 20px 55px #777; }
.header { background: #000; height: 40px; color: #fff; line-height: 34px; font-size: 20px; padding: 0 10px; }
.footer { width: 430px; height: 50px; background: #666; position: absolute; bottom: 0; padding: 10px; }
.footer input { width: 275px; height: 45px; outline: none; font-size: 20px; text-indent: 10px; position: absolute; border-radius: 6px; right: 80px; }
.footer span { display: inline-block; width: 62px; height: 48px; background: #ccc; font-weight: 900; line-height: 45px; cursor: pointer; text-align: center; position: absolute; right: 10px; border-radius: 6px; }
.footer span:hover { color: #fff; background: #999; }
#user_face_icon { display: inline-block; background: red; width: 60px; height: 60px; border-radius: 30px; position: absolute; bottom: 6px; left: 14px; cursor: pointer; overflow: hidden; }
img { width: 60px; height: 60px; }
.content { font-size: 20px; width: 435px; height: 662px; overflow: auto; padding: 5px; }
.content li { margin-top: 10px; padding-left: 10px; width: 412px; display: block; clear: both; overflow: hidden; }
.content li img { float: left; }
.content li span { background: #7cfc00; padding: 10px; border-radius: 10px; float: left; margin: 6px 10px 0 10px; max-width: 310px; border: 1px solid #ccc; box-shadow: 0 0 3px #ccc; }
.content li img.imgleft { float: left; }
.content li img.imgright { float: right; }
.content li span.spanleft { float: left; background: #fff; }
.content li span.spanright { float: right; background: #7cfc00; } </style> </head> <body> <div id="app" class="container"> <div class="header"> <span style="float: left;">与机器人聊天中</span> <span style="float: right;">14:21</span> </div> <ul class="content"> <li v-for="(item,index) in messages_list" v-key="index"> <img v-bind:src="item.user" v-bind:class="{'imgright':item.id}"><span v-bind:class="{'spanright':item.id}">{{item.msg}}</span> </li> </ul> <div class="footer"> <div id="user_face_icon"> <img src="http://www.xttblog.com/icons/favicon.ico" alt=""> </div> <input id="text" v-model="sends" type="text" placeholder="说点什么吧..."> <span id="btn" v-on:click="sendMessage">发送</span> </div> </div> <script src="https://cdn.bootcss.com/vue/2.6.10/vue.min.js"></script> <script> ws = new WebSocket('ws://10.10.10.238:9687/msg') ws.onmessage = function (data) { app.messages_list.push(JSON.parse(data.data)) } var app = new Vue({ el: '#app', data: { sends: '', messages_list: [] }, watch: { messages_list: function (newQuestion, oldQuestion) { var content = document.getElementsByTagName('ul')[0]; content.scrollTop = content.scrollHeight; } }, methods: { sendMessage: function () { this.messages_list.push({ id: 1, user: 'https://pic.qqtn.com/up/2018-2/15175580428030394.gif', msg: this.sends }) ws.send(this.sends) this.sends = '' } } }) </script>
</body> </html>
|
结束
以上就是完整的前后端代码,使用时将ip
改为自己的代码就可以了,注聊天框中服务器与客户端消息显示位置以消息对象中id为表示,id为1代表客户端,0代表服务器。