Websocket 之flask_socketio和Python socketio

1、falsk_socket与前端

(1)测试版

前端

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>


   <!--
    <script type="text/javascript" src="https://cdn.bootcdn.net/ajax/libs/socket.io/2.3.0/socket.io.js"></script>
-->

  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js" integrity="sha512-bLT0Qm9VnAYZDflyKcBaQ2gg0hSYNQrJ8RilYldYQ1FxQYoCLtUjuuRuZo+fjqhx/qtq/1itJ0C2ejDxltZVFg==" crossorigin="anonymous"></script>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/3.0.4/socket.io.js" integrity="sha512-aMGMvNYu8Ue4G+fHa359jcPb1u+ytAF+P2SCb+PxrjCdO3n3ZTxJ30zuH39rimUggmTwmh2u7wvQsDTHESnmfQ==" crossorigin="anonymous"></script>



</head>
<body>

 <div><button onclick="ws()">连接服务端</button></div>
 <div><button onclick="clos_con()">断开连接</button></div>
 <div><button onclick="send_msg()">发送消息给服务端</button></div>
<script type="text/javascript">
    windw_socket=null


    function ws(){
      
      
	namespace = '/websocket';
	var websocket_url = location.protocol+'//' + document.domain + ':' + location.port + namespace;
	var socket=io.connect(websocket_url);
	// socket.emit('connect2', {'param':'value'});	//发送消息
	// socket.close()
	socket.on('connect',function(data){
      
      
		console.log('connecte:'+data);
		alert("建立连接成功")
		windw_socket=socket
	});

	socket.on('disconnect',function(data){
      
      
		alert("连接已断开")
		console.log('disconnecte:'+data);
	});

	socket.on('my_response_message',function(data){
      
      
		console.log('my_response_message:'+data);
		alert("收到服务端的回复:"+data)
	});
}



    function clos_con(){
      
      
	    if(windw_socket!=null){
      
      
	        windw_socket.close()
        }
    }



    window.onbeforeunload= function(event) {
      
      
	if (windw_socket!=null && !windw_socket.closed){
      
      
		// confirm(windw_socket.closed)
		windw_socket.close()
	}
    }


    window.onunload= function(event) {
      
      
	if (windw_socket!=null && !windw_socket.closed){
      
      
		//confirm(windw_socket.closed)
		windw_socket.close()
	}
    }


    function send_msg(){
      
      
	    if(windw_socket!=null){
      
      
	        windw_socket.emit('message', "这里是客户端");
        }
    }


</script>
</body>
</html>

后端

import json
from flask import Flask, render_template, request, redirect, sessions
from flask_socketio import SocketIO, emit  # 导入socketio包

name_space = '/websocket'
app = Flask(__name__)
app.secret_key = 'jzw'
socketio = SocketIO(app)
client_query = []


@socketio.on('connect', namespace=name_space)  # 有客户端连接会触发该函数
def on_connect():
    # 建立连接 sid:连接对象ID
    client_id = request.sid
    client_query.append(client_id)
    # emit(event_name, broadcasted_data, broadcast=False, namespace=name_space, room=client_id)  #指定一个客户端发送消息
    # emit(event_name, broadcasted_data, broadcast=True, namespace=name_space)  #对name_space下的所有客户端发送消息
    print('有新连接,id=%s接加入, 当前连接数%d' % (client_id, len(client_query)))


@socketio.on('disconnect', namespace=name_space)  # 有客户端断开WebSocket会触发该函数
def on_disconnect():
    # 连接对象关闭 删除对象ID
    client_query.remove(request.sid)
    print('有连接,id=%s接退出, 当前连接数%d' % (request.sid, len(client_query)))


# on('消息订阅对象', '命名空间区分')
@socketio.on('message', namespace=name_space)
def on_message(message):
    """ 服务端接收消息 """
    print('从id=%s客户端中收到消息,内容如下:' % request.sid)
    print(message)
    emit('my_response_message', "我收到了你的信息", broadcast=False, namespace=name_space, room=client_id)  # 指定一个客户端发送消息
    # emit('my_response_message', broadcasted_data, broadcast=True, namespace=name_space)  #对name_space下的所有客户端发送消息


@app.route('/')  # 初始化页面
def a():
    return render_template("socketv5.html")


if __name__ == '__main__':
    socketio.run(app, host='0.0.0.0', port=5000, debug=False)
    # app.run()

(2)完整版

前端

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>SocketIO Demo</title>

<!--
    <script type="text/javascript" src="//cdn.bootcss.com/jquery/3.1.1/jquery.min.js"></script>
    <script type="text/javascript" src="//cdn.bootcss.com/socket.io/1.5.1/socket.io.min.js"></script>
-->

    <!--
     <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js" integrity="sha512-bLT0Qm9VnAYZDflyKcBaQ2gg0hSYNQrJ8RilYldYQ1FxQYoCLtUjuuRuZo+fjqhx/qtq/1itJ0C2ejDxltZVFg==" crossorigin="anonymous"></script>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/3.0.4/socket.io.js" integrity="sha512-aMGMvNYu8Ue4G+fHa359jcPb1u+ytAF+P2SCb+PxrjCdO3n3ZTxJ30zuH39rimUggmTwmh2u7wvQsDTHESnmfQ==" crossorigin="anonymous"></script>

<script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>

-->

     <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js" integrity="sha512-bLT0Qm9VnAYZDflyKcBaQ2gg0hSYNQrJ8RilYldYQ1FxQYoCLtUjuuRuZo+fjqhx/qtq/1itJ0C2ejDxltZVFg==" crossorigin="anonymous"></script>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/3.0.4/socket.io.js" integrity="sha512-aMGMvNYu8Ue4G+fHa359jcPb1u+ytAF+P2SCb+PxrjCdO3n3ZTxJ30zuH39rimUggmTwmh2u7wvQsDTHESnmfQ==" crossorigin="anonymous"></script>



</head>
<body>

<h2>Demo of SocketIO</h2>
<div id="t"></div>

<button onclick="myconet()">建立连接</button> <br>
<button onclick="send()">发送信息</button> <br>
<button onclick="getTest()">点ajax请求</button> <br>
<button onclick="getTest2()">点server服务端关闭连接</button> <br>
<button onclick="clos_con()">点client客户端关闭连接</button> <br>




<script>

    namespace = '/dcenter';
    var socket=null;

    {
      
      #var socket = io.connect(location.protocol + '//' + document.domain + ':' + location.port + namespace);#}

    socket = io.connect(location.protocol + '//' + document.domain + ':' + location.port + namespace);


    socket.on('dcenter', function (res) {
      
      
        var t = res.data;
         console.log("dcenter test:");
         console.log(t);
        if (t) {
      
      
            $("#t").append(t).append('<br/>');
        }

    });

    socket.on('my_response', function (res) {
      
      
        var t = res.data;
         console.log(t);
        if (t) {
      
      
            $("#t").append(t).append('<br/>');
        }

    });

    socket.on('disconnect',function(data){
      
      
		alert("连接已断开")
		console.log('disconnecte:'+data);
	});

    function myconet() {
      
      
        {
      
      #socket=null;#}
        socket = io.connect(location.protocol + '//' + document.domain + ':' + location.port + namespace);

     {
      
      #location.reload(true);#}
    window.location.reload(true) // 刷新窗口
    console.log('my connecte:');

    };


    function send(){
      
      
            socket.emit('my_event', {
      
       'data': 'I\'m a buttun ok !' });
             console.log('button click')
        };

    function getTest(){
      
      
        socket.emit('my_event', {
      
       'data': 'I\'m a ajax go go !' });
             console.log('button click')

	};

	 function getTest2(){
      
      
        socket.emit('leav', {
      
       'data': 'I\'m a leav !' });
             console.log('button click')

	};

	function getTest3(){
      
      
        socket.emit('disconnect', {
      
       'data': 'I\'m a leav !' });
             console.log('disconnect click')

	};

	function clos_con(){
      
      
	    if(socket!=null){
      
      
	        socket.close()
        }
    }


</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()

socketio.init_app(app, cors_allowed_origins='*')

name_space = '/dcenter'


@app.route('/')
def index():
    return render_template('socketv4.html')


@app.route('/push')
def push_once():
    event_name = 'dcenter'
    broadcasted_data = {
    
    'data': "test message!"}
    socketio.emit(event_name, broadcasted_data, broadcast=False, namespace=name_space)
    return 'done!'


@socketio.on('connect', namespace=name_space)
def connected_msg():
    print('client connected.')


@socketio.on('disconnect', namespace=name_space)
def disconnect_msg():
    print('client disconnected.')


@socketio.on('my_event', namespace=name_space)
def mtest_message(message):
    print(message)

    # socketio.emit('my_response',
    #      {'data': message['data'], 'count': 1},broadcast=False, namespace=name_space)

    socketio.emit('my_response',{
    
    'data': 'i am server you kow'},broadcast=False, namespace=name_space)


@app.route('/push2')
def push_once2():
    event_name = 'dcenter'
    broadcasted_data = {
    
    'data': "test message!"}
    socketio.emit(event_name, broadcasted_data, broadcast=False, namespace=name_space)
    return 'done!'



@socketio.on('leav', namespace=name_space)
def receive_message(msg):
    print('i leav pre')
    socketio.close_room(None,name_space)
    print('i leav you')


# @socketio.on('disconnect', namespace=name_space)  # 有客户端断开WebSocket会触发该函数
# def on_disconnect():
#     # 连接对象关闭 删除对象ID
#
#     print('有连接,id=%s接退出当前连接' % (request.sid))





if __name__ == '__main__':

    socketio.run(app,host='127.0.0.1',port=5000, debug=True) #端口在配置文件中配置 --port=8080,默认为5000

2、client与serve(socket)

(1)python的socketio实现

client

import socketio

sio = socketio.Client()

@sio.event
def connect():
    print('connection established')


@sio.event
def my_message(data):
    print('message received with ', data)
    # sio.emit('my response', {'response': 'my response'})

@sio.event
def disconnect():
    print('disconnected from server')

sio.connect('http://127.0.0.1:5000')

# sio.connect('http://127.0.0.1:5000', namespaces=['/chat'])

print("000")

sio.emit('my_message', {
    
    'response': 'my response'})

sio.sleep(10)

sio.emit('my_message', {
    
    'response': 'my response22222222'})

# sio.emit('myname', {'foo': 'a name space test'}, namespace='/chat')

print("222")

sio.wait()

server

import eventlet
import socketio

sio = socketio.Server()
app = socketio.WSGIApp(sio, static_files={
    
    
    '/': {
    
    'content_type': 'text/html', 'filename': 'index.html'}
})

@sio.event
def connect(sid, environ):
    print('connect ', sid)


@sio.event
def disconnect(sid):
    print('disconnect ', sid)

@sio.event
def my_message(sid, data):    #没名称空间用方法名
    print('message ', data)
    sio.emit('my_message', {
    
    'response': 'my response'})
    # sio.emit('my message', {'response': 'my response'})
    # sio.emit('my event', {'data': 'foobar'})

# @sio.on('myname', namespace='/chat')
# def my_custom_event(sid, data):
#     print('message ', data)

if __name__ == '__main__':
    eventlet.wsgi.server(eventlet.listen(('127.0.0.1', 5000)), app)

(2)flask和socketio客户端实现

client

import socketio

sio = socketio.Client()

@sio.event
def connect():
    print('connection established')


@sio.event
def disconnect():
    print('disconnected from server')



@sio.event
def my_message(data):
    print('message received with ', data)
    # sio.emit('my response', {'response': 'my response'})


@sio.event(namespace='/dcenter')
def my_response(data):
    print('message received with ', data)
    # sio.emit('my response', {'response': 'my response'})



@sio.on('test_event', namespace='/dcenter')
def test_event(data):
    print(data)
    print("I'm connected to the /chat namespace!")


# sio.connect('http://127.0.0.1:5000')

sio.connect('http://127.0.0.1:5000', namespaces=['/dcenter'])


print("000")
sio.emit('my_event', {
    
    'foo': 'a name space test'}, namespace='/dcenter')

sio.sleep(2)
sio.emit('my_event', {
    
    'foo': 'a name space2222'}, namespace='/dcenter')

print("222")
sio.sleep(2)
sio.emit('test_event', {
    
    'event': 'a serve test event'}, namespace='/dcenter')

print('3333')
# print("000")
#
# sio.emit('my_message', {'response': 'my response'})
#
# sio.sleep(10)
#
# sio.emit('my_message', {'response': 'my response22222222'})
#
# # sio.emit('myname', {'foo': 'a name space test'}, namespace='/chat')
#
# print("222")

sio.wait()

Flask server

from flask import Flask, render_template,request
from flask_socketio import SocketIO, emit


app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret_key'

socketio = SocketIO()

socketio.init_app(app, cors_allowed_origins='*')

name_space = '/dcenter'


@app.route('/')
def index():
    return render_template('socketv4.html')


@app.route('/push')
def push_once():
    event_name = 'dcenter'
    broadcasted_data = {
    
    'data': "test message!"}
    socketio.emit(event_name, broadcasted_data, broadcast=False, namespace=name_space)
    return 'done!'


@socketio.on('connect', namespace=name_space)
def connected_msg():
    print('client connected.')


@socketio.on('disconnect', namespace=name_space)
def disconnect_msg():
    print('client disconnected.')


@socketio.on('my_event', namespace=name_space)
def mtest_message(message):
    print(message)

    # socketio.emit('my_response',
    #      {'data': message['data'], 'count': 1},broadcast=False, namespace=name_space)

    socketio.emit('my_response',{
    
    'data': 'i am server you kow'},broadcast=False, namespace=name_space)


@socketio.on('test_event', namespace=name_space)
def test_event(message):
    print(message)

    # socketio.emit('my_response',
    #      {'data': message['data'], 'count': 1},broadcast=False, namespace=name_space)

    socketio.emit('test_event',{
    
    'data': 'i am client test_event'},broadcast=False, namespace=name_space)



@app.route('/push2')
def push_once2():
    event_name = 'dcenter'
    broadcasted_data = {
    
    'data': "test message!"}
    socketio.emit(event_name, broadcasted_data, broadcast=False, namespace=name_space)
    return 'done!'



@socketio.on('leav', namespace=name_space)
def receive_message(msg):
    print('i leav pre')
    socketio.close_room(None,name_space)
    print('i leav you')


# @socketio.on('disconnect', namespace=name_space)  # 有客户端断开WebSocket会触发该函数
# def on_disconnect():
#     # 连接对象关闭 删除对象ID
#
#     print('有连接,id=%s接退出当前连接' % (request.sid))

if __name__ == '__main__':

    socketio.run(app,host='127.0.0.1',port=5000, debug=True) #端口在配置文件中配置 --port=8080,默认为5000

3、Python环境

bidict==0.22.1
certifi==2023.5.7
cffi==1.15.1
charset-normalizer==3.1.0
click==8.1.3
colorama==0.4.6
dnspython==2.3.0
eventlet==0.33.3
Flask==2.2.2
Flask-SocketIO==5.2.0
gevent==22.10.2
greenlet==2.0.2
h11==0.14.0
idna==3.4
itsdangerous==2.1.2
Jinja2==3.1.2
MarkupSafe==2.1.1
pip==23.1.2
pycparser==2.21
python-engineio==4.3.3
python-socketio==5.7.1
requests==2.31.0
setuptools==67.8.0
simple-websocket==0.7.0
six==1.16.0
urllib3==2.0.3
Werkzeug==2.2.2
wheel==0.38.4
wsproto==1.2.0
zope.event==4.6
zope.interface==6.0

版本问题参考:https://blog.csdn.net/weixin_44986037/article/details/131504760

猜你喜欢

转载自blog.csdn.net/weixin_44986037/article/details/131504631