首先说声抱歉,在上一篇帖子中,我没有把问题和代码描述清楚,现在我把两个不同版本的代码,发出来,大佬们帮我看下是因为什么(本来是想把运行结果截图也上传的,但是网站提示新用户只能上传一张截图)
版本一:不借助登录,直接将username传递给后端,保存用户的sid
前端代码如下:
<html>
<head>
<title>Chat Room</title>
<br>
<br>
<h3>模拟登录</h3>
Username: <input type="text" id="username" autocomplete="off">
<button id="login">Login</button>
<br>
<br>
<div id="send_msg_area" style="display: none">
<h3>发送消息</h3>
recipient: <input type="text" id="recipient">
sender : <input type="text" id="sender">
Message: <input type="text" id="message">
<button id="send">Send</button>
</div>
</head>
<body>
<script type="text/javascript" src="{{ url_for('static', filename='js/jquery-3.5.1.min.js') }}"></script>
<script type="text/javascript" src="{{ url_for('static', filename='js/socket.io.js') }}"></script>
<script type="text/javascript">
$(document).ready(function () {
var socket = io('http://127.0.0.1:9000');
$('#login').on('click', function () {
if ($('#username').val() === '') {
alert('用户名不能为空');
} else {
socket.emit('store_sid', {'username': $('#username').val()});
}
});
$('#send').on('click', function () {
socket.emit('new_message', {
'recipient': $('#recipient').val(),
'sender': $('#sender').val(),
'message': $('#message').val()
});
});
socket.on('store_resp', function (data) {
if (data.code === 200) {
$('#send_msg_area').show();
}
});
socket.on('message_resp', function (data) {
alert(data.message);
});
});
</script>
</body>
</html>
后端代码如下:
from flask import Flask, render_template, request
from flask_socketio import SocketIO, emit
app = Flask(__name__)
app.config["SECRET_KEY"] = "secret key"
socketio = SocketIO(app, cors_allowed_origins='*')
all_sid = {}
@app.route('/chat')
def chat():
return render_template('chat.html')
@socketio.on('store_sid')
def store_sid(data):
all_sid[data['username']] = request.sid
print('username added! all_sid: ', all_sid)
emit('store_resp', {'code': 200})
@socketio.on('new_message')
def new_message(data):
recipient = data['recipient']
sender = data['sender']
message = data['message']
print(all_sid[recipient])
emit('message_resp', {'message': message}, room=all_sid[recipient])
if __name__ == "__main__":
socketio.run(app, host="0.0.0.0", port=9000, debug=True)
说明:通过这种方式是可以实现利用socketio转发消息的功能
版本二:在版本一的基础上,加上登录功能,登录之后,将登录成功的username传递给后端,保存其sid
前端代码如下:
登录页面代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>demo1-login</title>
</head>
<body>
<h3>模拟登录</h3>
Username: <input type="text" id="username" autocomplete="off">
<button id="login">Login</button>
</body>
<script type="text/javascript" src="{{ url_for('static', filename='js/jquery-3.5.1.min.js') }}"></script>
<script type="text/javascript" src="{{ url_for('static', filename='js/socket.io.js') }}"></script>
<script type="text/javascript">
var socket = io('http://127.0.0.1:2323');
$('#login').click(function () {
if ($('#username').val() === ''){
alert('用户名不能为空')
} else{
$.ajax({
url: '/login',
type: 'POST',
contentType: 'application/json',
data: JSON.stringify({
username: $('#username').val(),
}),
success: function (data) {
if (data.code === 200) {
socket.emit('store_sid', {'username': data.username});
window.location = '/chat'
}
},
error: function (data) {
console.log(data.code)
}
})
}
})
</script>
</html>
发送消息页面:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>demo1-chat</title>
</head>
<body>
<h3>模拟转发聊天</h3>
<h3>hello, {{ username }}</h3>
<a href="/login">重新登录</a><br><br>
recipient: <input type="text" id="recipient">
sender: <input type="text" id="sender">
message: <input type="text" id="message">
<button id="send">Send</button>
</body>
<script type="text/javascript" src="{{ url_for('static', filename='js/jquery-3.5.1.min.js') }}"></script>
<script type="text/javascript" src="{{ url_for('static', filename='js/socket.io.js') }}"></script>
<script type="text/javascript">
var socket = io('http://127.0.0.1:2323');
$('#send').on('click', function () {
socket.emit('new_message', {
'recipient': $('#recipient').val(),
'sender': $('#sender').val(),
'message': $('#message').val()
})
});
socket.on('message_resp', function (data) {
console.log(data);
alert(data.new_message)
})
</script>
</html>
后端代码如下:
from flask import Flask, render_template, request, jsonify, session
from flask_socketio import SocketIO, emit
app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret key'
socketio = SocketIO(app, cors_allowed_origins='*')
all_sid = {}
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
username = request.json.get('username')
if username:
session['username'] = username
return jsonify({'code': 200, 'username': username})
return jsonify({'code': 500})
return render_template('login.html')
@app.route('/chat')
def chat():
return render_template('chat.html', username=session['username'])
@socketio.on('store_sid')
def store_sid(data):
all_sid[data['username']] = request.sid
print('username added! all_sid: ', all_sid)
@socketio.on('new_message')
def new_message(data):
recipient = data['recipient']
sender = data['sender']
message = data['message']
print('message: ', message)
emit('message_resp', {'message': message}, room=all_sid[recipient])
if __name__ == '__main__':
socketio.run(app, host='0.0.0.0', port=2323, debug=True)
运行结果截图如下:
说明:通过IED的打印可以看到,后端是已将收到了前端发送的message内容,但是前端并没有alert弹窗,这就很奇怪,不知道是怎么回事。有没有大佬帮忙看看是因为什么造成的
环境版本:
Flask-SocketIO==4.3.1
Python==3.7.8