码迷,mamicode.com
首页 > 其他好文 > 详细

flask-sockiet+Gunicorn+Nginx实战

时间:2020-09-17 21:50:16      阅读:37      评论:0      收藏:0      [点我收藏+]

标签:off   enter   params   new   list   tor   ase   type   def   

  在flask框架下,服务端和客户端通过websocket的通信方式主要有两种,一种是原生的websocket通信,通过引入flask-websockets来实现,这个包只是简单的对websocket协议进行了简单的封装;另外一种就是本文主要讲的flask-socketio方式。

  先谈谈自己遇到的坑,因为项目需要websocket通信,起初为了前后端通用性选择了flask-websockets,但是好不容易测试通过可以互传信息了,结果发现只要启动通信,flask框架下的其他接口统统用不了,响应超时,后来想到的原因可能是因为websocket通信使用了和flask接口同样的端口,导致端口阻塞造成的。于是根据网上建议改用flask-socketio。

服务端

  首先是安装,通过命令行完成:

pip install flask-socketio

  然后,在你的flask项目中引入,并初始化:

from flask import Flask, render_template
from flask_socketio import SocketIO

app = Flask(__name__)
app.config[SECRET_KEY] = secret!
socketio = SocketIO(app)

if __name__ == __main__:
    socketio.run(app)

注意:这里的程序启动方式要更改为socket特有的模式,用socketio.run(app)代替app.run()。

socketio还支持init_app的初始化方式,可以在创建socketio对象时,先不传入app实例,启动程序前再调用init_app进行初始化。

客户端

客户端可以用网页前端连接

<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/socket.io/1.3.6/socket.io.min.js"></script>
<script type="text/javascript" charset="utf-8">
    var socket = io.connect(http:// + document.domain + : + location.port);
    socket.on(connect, function() {
        socket.emit(my event, {data: I\‘m connected!});
    });
</script>

也可用python客户端连接

#-*-coding:utf-8-*-
from socketIO_client import SocketIO, BaseNamespace
import time


class MonitorNamespace(BaseNamespace):

    def on_connect(self):
        print([Connected])

    def on_reconnect(self):
        print([Reconnected])

    def on_disconnect(self):
        print([Disconnected])


socketIO = SocketIO(http://127.0.0.1, 5000)
monitor_namespace = socketIO.define(MonitorNamespace, /your_namespace)
monitor_namespace.emit(join, {room: your room})
for i in range(30):
    monitor_namespace.emit(new_log, {data: info ---{}.format(i)})
    time.sleep(1)
monitor_namespace.emit(leave, {room: your room})

注意场景send() 用于匿名事件; emit()用于自定义事件。发送参数支持广播broadcast=True和room=‘room_name‘两种。指定room后,只有加入到room的客户端才能接收到消息。加入room的方法:

from flask_socketio import join_room, leave_room
send(username + ‘ has entered the room.‘, room=room)

访问Flask全局变量

在调用事件函数前,应用上下文就已经被推入栈,以此确保current_app 和g在事件函数中可用,在socket连接之前,或者发送消息之前:

        with app.app_context():
            init_database()
            self.db = g.db

另外,request 多了sid成员,用于为连接设定的session ID,其默认值为客户端房间号。连接事件函数可以选择返回False来拒接连接请求。实际应用中,可以通过这种方式来验证用户权限。

部署

最简单的部署方式,就是安装eventlet或gevent,然后调用socketio.run(app)

gunicorn部署

gunicorn --worker-class eventlet -w 1 module:app

由于gunicorn算法的问题,服务器启动只能使用一个worker进程。因此,必须加上 -w 1

使用nginx作为WebSocket反向代理

server {
    listen 80;
    server_name _;

    location / {
        include proxy_params;
        proxy_pass http://127.0.0.1:5000;
    }

    location /socket.io {
        include proxy_params;
        proxy_http_version 1.1;
        proxy_buffering off;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "Upgrade";
        proxy_pass http://127.0.0.1:5000/socket.io;
    }
}

上述的ip和端口地址根据自己gunicorn设置的来定。

如果服务端启用了ssl,socket连接时端口号要改为443。

 

flask-sockiet+Gunicorn+Nginx实战

标签:off   enter   params   new   list   tor   ase   type   def   

原文地址:https://www.cnblogs.com/python-xuehb/p/13651060.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!