在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 問答/Python  HTML/ Flask-websocket Emit主動發(fā)送消息失敗

Flask-websocket Emit主動發(fā)送消息失敗

現(xiàn)在在用flask實(shí)現(xiàn)一個簡單的webserver,為了與前段進(jìn)行通信,加入了flask-socketio模塊,現(xiàn)在在處理前段發(fā)送過來的消息的函數(shù)中直接emit的話,前端可以收到消息。但是想主動發(fā)送消息的話失敗。具體如下:

在這邊的話前端是可以接收到emit發(fā)送的消息的。

@socketio.on('request_for_response')
def handle_request(request):
    print('received socket message:' + json.dumps(request))
    # 這里可以直接發(fā)送,如果單獨(dú)發(fā)送就不可以?
    emit('response', 'ok')
    msgTranslate(request)

如果在普通函數(shù)里直接調(diào)用就會失敗,這里的emit始終不能發(fā)送消息。

def recvThread():
    while True:
        # print("recvThread start---")
        msgNum = c_long(0)
        content = create_string_buffer(1024)
        if recvMsg(byref(msgNum), content) == 0:
            print(content)
            print("the content number is %d, the content is:%s" % (msgNum.value, content.value))
            # 必須要全局的才能調(diào)用
            d = dict(name='djj', age=26)
            print(json.dumps(d))
            # response(json.dumps(d))
            socketio.emit('response')

socketio定義如下

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

前端代碼如下:

 var $SCRIPT_ROOT = {{ request.script_root|tojson|safe }};
 var socket = io.connect($SCRIPT_ROOT);
                socket.on('connect',function()
                    {
                       socket.emit('connected');
                    });
                 socket.on('response', function(data)
                  {
                      console.log(data);
                      alert("receive response");
                      /*
                      if(data.code == '200'){
                          alert(data.param);
                      }
                      else
                      {
                          alert('Error:'+data.param);
                      }
                      */
                      //alert(data.param);

                  });

            $(document).ready(function(){
                $("#btn").click(function () {
                    socket.emit('request_for_response', JSON.stringify({
                            'ip': $("#ip").val(),
                            'cover': $("#cover").val(),
                            'gate': $("#gate").val(),
                    }));
                });
            });

發(fā)現(xiàn)一個問題:socketio.emit放在線程里就無法執(zhí)行,我現(xiàn)在的啟動的部分代碼是這樣的,

if __name__ == '__main__':
    loadDjjque()
    isInit = queInit()
    setCharacter(1)
    if isInit == 0:
        print("--queInit success--")
    t = threading.Thread(target=recvThread, name='recvThread')
    t.setDaemon(True)
    t.start()
    socketio.run(app, host='0.0.0.0', port=5555)

但是官方文檔寫的是:

但對于某些應(yīng)用程序,服務(wù)器需要作為消息的發(fā)起者。 這可以用于向客戶端發(fā)送在服務(wù)器中發(fā)起的事件的通知,例如在后臺線程中。 可以使用socketio.send()和socketio.emit()方法向所有連接的客戶端進(jìn)行廣播:

def some_function():

socketio.emit('some event', {'data': 42})

請注意,socketio.send()和socketio.emit()與上下文感知send()和emit()不同。 還要注意,在上面的用法中沒有客戶端上下文,所以broadcast=True,不需要指定。

作者:1994宅貓
鏈接:https://www.jianshu.com/p/411...
來源:簡書
著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請注明出處。

不知道為什么不可以發(fā)送出去??

回答
編輯回答
法克魷

如果沒有@socketio.on('request_for_response')這個裝飾器,你的程序就不完整。

建議看看看看我的這篇文章——基于 flask-socketio 的 CRUD 操作初探

2017年3月6日 07:19
編輯回答
愿如初

解決問題了,目前問題解決有兩種方法!
1、在web發(fā)送回來的消息中 通過set_background_tsk()來開啟新線程,但是要注意在這個線程中如果需要sleep,必須要用socketio.sleep()這樣Flask才會放開消息循環(huán),不然整個通信會阻塞。
代碼如下:

app = Flask(__name__)
socketio = SocketIO(app, ansyc_mode=None)

@socketio.on("connect")
def connect():
    socketio.start_background_task(threadFunc)
    
def threadFunc():
    while(True):
        emit("response")
        socketio.sleep(3)

實(shí)際上這種方法還是同步的,整個流程的發(fā)起還是web,并沒有實(shí)現(xiàn)正真意義上的互相通信。但是也可以解決現(xiàn)有問題。

2、使用app.app_context(),其實(shí)socketio.emit()沒有發(fā)送成功是因?yàn)?沒有找到app的上下文,使用with app.app_context()即可以找到app的上下文。但是要注意的是線程中的掛起方式還是得用socketio.sleep()
具體代碼如下:

from eventlet.green import threading
app = Flask(__name__)
socketio = SocketIO(app, ansyc_mode=None)

def report():
    while True:
        with app.app_context():
            socketio.emit('response')
        socketio.sleep(5)

t = threading.Thread(target=report, name='report')
t.setDaemon(True)
t.start()
socketio.run(app, host='0.0.0.0', port=5555)

在這個方法中可以做到真正意義上的server端主動發(fā)起消息,建議采用后面一種方法

2017年3月3日 09:33