Socket 便利不用多说,python 支持原生socket tcp,udp;原生没有封装好的方法,都需要自己手动去实现,尤其是心跳; 基于socket,衍生出了多个三方包,WebSocket,socketio,flask-socketio,django-socketio,这里介绍flask-socketio和socketio
flask-socketio
1 flask_socketio是基于flask框架封装的一个包,如果只是搭建服务端,真的好用;前端请求,数据可以实时传输,长连接
```shell script pip flask-socketio
#### 2 服务端
```python
# coding=utf-8
import logging
import random
from threading import Lock
from . import api
from app import socketio,SocketIO
from flask_socketio import emit # 发送信息
from flask import request, jsonify, current_app, session,render_template
thread = None
thread_lock = Lock()
def background_thread(users_to_json):
"""Example of how to send server generated events to clients."""
while True:
users_to_json = [{'name': '王腾' + str(random.randint(1, 100))}]
socketio.sleep(5) # 每五秒发送一次
logging.info(users_to_json)
socketio.emit('user_response', {'data': users_to_json}, namespace='/websocket/user_refresh')
@socketio.on('connect',namespace='/websocket/user_refresh')
def connect():
"""服务端自动发送请求"""
global thread
user_to_json = ''
with thread_lock:
if thread is None:
thread = socketio.start_background_task(background_thread, (user_to_json,))
logging.info("----客户端连接---------")
emit('server_response', {'data': '试图连接客户端!'})
@socketio.on("connect_event",namespace='/websocket/user_refresh')
def refresh_message(message):
"""服务端接收客户端消息"""
logging.info("----------"+message["data"])
emit('server_response', {'data': message['data']})
@socketio.on("disconnect",namespace="/websocket/disconnect")
def disconnect():
logging.error('Client disconnected')
@api.route('/', methods=['GET'])
def index():
return render_template('index.html')
由于采用了manager,连接是放在__init__中了,目录结构如下
3 客户端 js
<script src="/static/js/jquery.slim.js"></script>
<!-- 新添加代码 start -->
<script src="/static/js/socket.io.dev.js"></script>
<script>
// 后台接口
var socket = io('http://127.0.0.1:8080/websocket/user_refresh');
socket.on('connect', function() { // 发送到服务器的通信内容
socket.emit('connect_event', {data: '我已连接上服务端!'});
});
socket.on('server_response', function(msg) {
//显示接受到的通信内容,包括服务器端直接发送的内容和反馈给客户端的内容
console.log(msg);
});
socket.on('user_response', function(msg) {
// 获取后端传过来的业务数据
var obj = eval(msg.data[0]);
console.log(obj);
$("#auto_num").empty();
$("#auto_num").append(obj['name']);
});
</script>
- 如果要是使用socket在后端实现客户端和服务端,原生socket很容易;如果服务端采用flask_socketio,客户端是没有如果服务端采用flask_socketio,如果采用socketIO_client你会发现,发送的接收不到, 客户端也不能收到服务端发送的消息,也不报错;换了websocket还是不行,网上说不配套,也有网友说都不维护了,在github上找到了socketio; socketio是分客户端和服务端,所以很好的能配套在一起使用.
python-socketio
1 安装python-socketio
```shell script pip install python-socketio
pip install “python-socketio[client]”
#### 2 服务端
```python
import socketio
from flask import Flask
sio = socketio.Server(async_mode='threading')
app = Flask(__name__)
app.wsgi_app = socketio.WSGIApp(sio, app.wsgi_app)
@sio.event
def my_event(sid, data):
print(sid, data)
@sio.on('my custom event')
def another_event(sid, data):
print(sid,data)
@sio.event
def connect(sid, environ):
print('connect ', sid, environ)
# 服务端在向客户端发送消息的时候,事件名称一定要一样
sio.emit('my message', {'data': 'foobar'})
# 客户端 my event,是收不到的
sio.emit('my event', {'data': 'foobar'})
print("-------------------------------")
@sio.event
def disconnect(sid):
print('disconnect ', sid)
if __name__ == '__main__':
app.run(host="0.0.0.0",port=8080,threaded=True)
3 客户端
import socketio
import json
sio = socketio.Client()
@sio.event
def message(data):
# message 是保留默认参数
print(data)
print('I received a message!')
@sio.on('my message')
def on_message(data):
print(data)
print('I received a on_message!')
@sio.event
def connect():
# emit 第一个是事件,要和服务端的事件名称一致,不然收不到
sio.emit('my_event', {"data": "200"})
print("I'm connected!")
print('my sid is', sio.sid)
@sio.event
def connect_error():
print("The connection failed!")
@sio.event
def disconnect():
print("I'm disconnected!")
@sio.event
def my_event(sid, data):
# handle the message
print(data)
return "OK", 123
sio.connect('http://127.0.0.1:8080')
sio.wait()