現(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 操作初探
解決問題了,目前問題解決有兩種方法!
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ā)起消息,建議采用后面一種方法
北大青鳥APTECH成立于1999年。依托北京大學(xué)優(yōu)質(zhì)雄厚的教育資源和背景,秉承“教育改變生活”的發(fā)展理念,致力于培養(yǎng)中國IT技能型緊缺人才,是大數(shù)據(jù)專業(yè)的國家
達(dá)內(nèi)教育集團(tuán)成立于2002年,是一家由留學(xué)海歸創(chuàng)辦的高端職業(yè)教育培訓(xùn)機(jī)構(gòu),是中國一站式人才培養(yǎng)平臺、一站式人才輸送平臺。2014年4月3日在美國成功上市,融資1
北大課工場是北京大學(xué)校辦產(chǎn)業(yè)為響應(yīng)國家深化產(chǎn)教融合/校企合作的政策,積極推進(jìn)“中國制造2025”,實(shí)現(xiàn)中華民族偉大復(fù)興的升級產(chǎn)業(yè)鏈。利用北京大學(xué)優(yōu)質(zhì)教育資源及背
博為峰,中國職業(yè)人才培訓(xùn)領(lǐng)域的先行者
曾工作于聯(lián)想擔(dān)任系統(tǒng)開發(fā)工程師,曾在博彥科技股份有限公司擔(dān)任項(xiàng)目經(jīng)理從事移動互聯(lián)網(wǎng)管理及研發(fā)工作,曾創(chuàng)辦藍(lán)懿科技有限責(zé)任公司從事總經(jīng)理職務(wù)負(fù)責(zé)iOS教學(xué)及管理工作。
浪潮集團(tuán)項(xiàng)目經(jīng)理。精通Java與.NET 技術(shù), 熟練的跨平臺面向?qū)ο箝_發(fā)經(jīng)驗(yàn),技術(shù)功底深厚。 授課風(fēng)格 授課風(fēng)格清新自然、條理清晰、主次分明、重點(diǎn)難點(diǎn)突出、引人入勝。
精通HTML5和CSS3;Javascript及主流js庫,具有快速界面開發(fā)的能力,對瀏覽器兼容性、前端性能優(yōu)化等有深入理解。精通網(wǎng)頁制作和網(wǎng)頁游戲開發(fā)。
具有10 年的Java 企業(yè)應(yīng)用開發(fā)經(jīng)驗(yàn)。曾經(jīng)歷任德國Software AG 技術(shù)顧問,美國Dachieve 系統(tǒng)架構(gòu)師,美國AngelEngineers Inc. 系統(tǒng)架構(gòu)師。