websocket搭建简单的网页聊天室框架
http
协议,是客户端每发送一个request
,服务器返回一个response
,无法做到服务器主动向客户端发送数据。我们要做一个网页版的聊天室,当一个人发送了消息时,其他人怎么能看到这条信息呢?有一个做法就是在网页中不断的运行js
,发送request
给服务器,服务器不断返回response
,当有新的消息时显示在页面上。这样做毫无疑问会产生大量的http
连接,对服务器的性能和带宽都有影响。而websocket
协议可以做到由服务器主动向客户端发送数据,当有新消息时就主动发送给浏览器,浏览器将内容更新到页面上。更多关于这个协议的详细内容和介绍,可以网上自行搜索。
为了学习websocket
,我们来实现一个超级简单的网页聊天室,建立一个html
文件,页面显示效果如下,用一个大的div
框架用来显示聊天记录,一个input
输入内容,一个button
用于发送信息:
前端使用js
的socket.io
,代码如下:
<script type="text/javascript" src="https://cdn.bootcss.com/socket.io/1.7.4/socket.io.min.js"></script> <script type="text/javascript" charset="utf-8"> var socket = io.connect('http://' + document.domain + ':' + location.port); var send = function () { var msg = document.querySelector("input").value; socket.emit('my event', {data: msg}); }; socket.on('res', function (msg) { document.querySelector(".content").insertAdjacentHTML( "beforeend", "<div class='message-div'><span class='message-content'>" + msg.data + "</span></div>" ) }) </script>
上段代码首先使用cdn
引用socket.io.min.js
,然后与后端建立连接,接着定义了一个send
方法(在html
的button
中使用onclikc
绑定),该方法首先获取input
中的内容,然后使用emit
方法将其发送到后端,后端(python+Flask-SocketIO)
对应的代码是:
from flask import Flask, render_template from flask_socketio import SocketIO import config app = Flask(__name__) app.config.from_object(config) socketio = SocketIO(app) @app.route('/') def index(): return render_template('websocket.html') @socketio.on('my event') def handle_my_custom_namespace_event(data): socketio.emit("res", data) if __name__ == "__main__": socketio.run(app)
代码中使用@socketio.on('my event')
注册一个my event
事件(与前端socket.emit('my event', {data: msg})
一致),然后再使用socketio.emit("res", data)
将数据返回前端,前端又通过socket.on('res', callback)
进行接收,所有建立了webscoket连接的客户端都会收到。此时整个流程就已经很明确了,再梳理一遍就是:点击button
后,触发send
函数,获取到input
中的内容,然后将数据(准确来说是将携带数据的事件)发送给后端,后端对应这个事件的函数(即使用@socketio.on('my event')
注册的函数,类似路由的注册)就会执行,该后端函数向前端发送携带同样数据的res
事件,前端socket.on('res', callback)
收到'req'事件后,使用callback
回调函数处理(即向网页中添加内容)。
开两个浏览器窗口,就可以看出效果了,如下: