【背景】
疫情期间公司原有的沟通方式变得少了,由于行业特殊性又不太好在社交媒体或者第三方聊天工具上沟通信息,所以想自己快速构建一个聊天室供业务的同事们使用。
【设计】
考虑到发布的便利性和ID管理,聊天记录等功能的追加,我选择用Flask+SocketIO的方式完成核心聊天室功能的搭建。至于保存数据到Log,做查询页面等,原本更是Flask能力范围内的事情,驾轻就熟,后续再追加即可。
【代码】
用Pycharm新建一个项目,暂时用不到DB这些,所以文件夹只需要一个简单的templates用来放唯一的页面模板即可,命名为index.html,py主程序命名为server.py
index.html:
<!DOCTYPE HTML>
<html>
<head>
<title>Socket-Test</title>
<script src="//code.jquery.com/jquery-1.12.4.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/socket.io/2.2.0/socket.io.js"></script>
<script type="text/javascript" charset="utf-8">
$(document).ready(function() {
namespace = '/test';
var socket = io(namespace);
socket.on('connect', function() {
socket.emit('my_event', {
data: 'connected to the SocketServer...'});
});
socket.on('my_response', function(msg, cb) {
$('#log').append('<br>' + $('<div/>').text('logs #' + msg.count + ': ' + msg.data).html());
if (cb)
cb();
});
$('form#emit').submit(function(event) {
socket.emit('my_event', {
data: $('#emit_data').val()});
return false;
});
$('form#broadcast').submit(function(event) {
socket.emit('my_broadcast_event', {
data: $('#broadcast_data').val()});
return false;
});
$('form#disconnect').submit(function(event) {
socket.emit('disconnect_request');
return false;
});
});
</script>
</head>
<body style="background-color:white;">
<h1 style="background-color:white;">Socket</h1>
<form id="emit" method="POST" action='#'>
<input type="text" name="emit_data" id="emit_data" placeholder="Message">
<input type="submit" value="Send Message">
</form>
<form id="broadcast" method="POST" action='#'>
<input type="text" name="broadcast_data" id="broadcast_data" placeholder="Message">
<input type="submit" value="Send Broadcast Message">
</form>
<form id="disconnect" method="POST" action="#">
<input type="submit" value="Disconnect Server">
</form>
<h2 style="background-color:white;">Logs</h2>
<div id="log" ></div>
</body>
</html>
server.py:
from flask import Flask, render_template, session, copy_current_request_context
from flask_socketio import SocketIO, emit, disconnect
from threading import Lock
async_mode = None
app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret!'
socket_ = SocketIO(app, async_mode=async_mode)
thread = None
thread_lock = Lock()
@app.route('/')
def index():
return render_template('index.html', async_mode=socket_.async_mode)
@socket_.on('my_event', namespace='/test')
def test_message(message):
session['receive_count'] = session.get('receive_count', 0) + 1
emit('my_response',
{
'data': message['data'], 'count': session['receive_count']})
@socket_.on('my_broadcast_event', namespace='/test')
def test_broadcast_message(message):
session['receive_count'] = session.get('receive_count', 0) + 1
emit('my_response',
{
'data': message['data'], 'count': session['receive_count']},
broadcast=True)
@socket_.on('disconnect_request', namespace='/test')
def disconnect_request():
@copy_current_request_context
def can_disconnect():
disconnect()
session['receive_count'] = session.get('receive_count', 0) + 1
emit('my_response',
{
'data': 'Disconnected!', 'count': session['receive_count']},
callback=can_disconnect)
if __name__ == '__main__':
socket_.run(app, debug=True,host="192.168.3.106",port="5100")
可以看见,除了index是正常路由,其他都是socket修饰方法。