我正在嘗試擁有一個 Flask 服務器,它允許我啟動一個 tweepy 流,并且在流偵聽器中接收到的每條訊息上,它都會將該訊息發送到 socketio 客戶端。Flask 服務器同時應該允許 Twilio 向它發布訊息,并將該訊息路由到客戶端——這樣客戶端就可以接收來自 Twilio 和 Twitter 的訊息。
我一直在嘗試讓服務器將訊息發送到客戶端以獲取從 twitter 傳入的資料,Twilio 的代碼作業得很好。它在收到訊息時將資料發送給客戶端。tweepy 中的主回圈也沒有鎖定程式——我可以測驗列印陳述句并查看推文和傳入的短信在handle_message(msg)函式中異步列印。我覺得一定有一些非常簡單的東西我在這里遺漏了,因為 SMS 被發送到客戶端,但傳入的推文不是,即使它們正在傳播到該handle_message(msg)函式。是什么賦予了?
服務器.py
from flask import Flask, json, request
from twilio.twiml.messaging_response import Message, MessagingResponse
from flask_socketio import SocketIO
import tweepy
import json
PATH = '/path/to/credentials/'
with open(PATH, "r") as file:
credentials = json.load(file)
app = Flask(__name__)
app.debug = True
app.config['SECRET_KEY'] = 'abc123'
sio = SocketIO(app, cors_allowed_origins="*")
auth = tweepy.OAuthHandler(credentials['CONSUMER_KEY'], credentials['CONSUMER_SECRET'])
auth.set_access_token(credentials['ACCESS_TOKEN'], credentials['ACCESS_SECRET'])
api = tweepy.API(auth)
class MyListener(tweepy.StreamListener):
def on_status(self, status):
print('status')
def on_data(self, data):
handle_message(data)
def on_error(self, status):
print('error')
print(status)
stream_listener = MyListener()
# twilio sms route
@app.route('/sms', methods=['POST'])
def sms():
number = request.form['From']
message_body = request.form['Body']
message_data = {"number": number, "msg": message_body}
resp = MessagingResponse()
resp.message('Hello {}, you said: {}'.format(number, message_body))
handle_message(message_data)
return str(resp)
# flask-socketio stuff
@sio.on('connect')
def connect():
print('connected')
sio.emit('client_connected', "you connected")
search_term = "#mysearchterm"
stream = tweepy.Stream(auth=api.auth, listener=stream_listener)
stream.filter(track=[search_term], is_async=True)
sio.emit('client_connected', "the search term is {}".format(search_term))
@sio.on('disconnect')
def disconnect():
print('Client Diconnected')
@sio.event
def handle_message(message):
print("This is the message received: ", message)
sio.emit('handle_message', message)
if __name__ == '__main__':
sio.run(app)
客戶端.py
import socketio
client = socketio.Client()
@client.on('client_connected')
def on_connect(message):
print(message)
@client.on('handle_message')
def message(data):
print(data)
client.connect('http://localhost:5000/')
uj5u.com熱心網友回復:
Twilio 開發人員布道者在這里。
您已經裝飾了該handle_message函式,@sio.event但就我在檔案中看到的而言,您應該只這樣做以使該handle_message方法回應名為“handle_message”的套接字上的事件。
我會開始移除@sio.event裝飾器。
我不是 Python 專家,但我也想知道這里是否存在范圍問題。MyListener在定義handle_message方法之前定義類并創建它的實體。只是為了測驗,您可以嘗試直接在on_data方法中發射到套接字:
def on_data(self, data):
sio.emit('handle_message', data)
如果可行,請考慮將 的定義移至 的定義handle_message之上MyListener。
uj5u.com熱心網友回復:
我解決了我的問題!正如我在此評論中指出的,問題在于多執行緒和執行緒之間的資訊傳遞。使用 tweepy,引數is_async=True,在 4.1.0 中是threading=True,一旦流運行,就會打開一個新執行緒。
我沒有嘗試處理傳遞資訊,而是通過使用本地 redis 服務器作為訊息佇列來利用現有的 flask-socketio 功能(如果您是第一次設定,請從“使用多個作業執行緒”部分開始,也一定要安裝redis)。
這是更新的server.py代碼。該client.py代碼基本上保持不變:
import eventlet
eventlet.monkey_patch()
from flask import Flask, json, request
from twilio.twiml.messaging_response import Message, MessagingResponse
from flask_socketio import SocketIO
import tweepy
import json
PATH = '/PATH/TO/CREDENTIALS'
with open(PATH, "r") as file:
credentials = json.load(file)
app = Flask(__name__)
app.debug = True
app.config['SECRET_KEY'] = 'abc123'
sio = SocketIO(app, message_queue='redis://', cors_allowed_origins="*")
class MyStream(tweepy.Stream):
def __init__(self, consumer_key, consumer_secret, access_token, access_secret):
super(MyStream, self).__init__(consumer_key, consumer_secret, access_token, access_secret)
self.stream_sio = SocketIO(message_queue='redis://')
def on_status(self, status):
print('status')
def on_data(self, data):
json_data = json.loads(data)
self.stream_sio.emit('handle_message', json_data['text'])
# TODO: Send along all necessary information
@app.route('/sms', methods=['POST'])
def sms():
number = request.form['From']
message_body = request.form['Body']
message_data = {"number": number, "msg": message_body}
resp = MessagingResponse()
resp.message('Hello {}, you said: {}'.format(number, message_body))
handle_message(message_data)
return str(resp)
@sio.on('connect')
def connect():
print('connected')
sio.emit('client_connected', "you connected")
search_term = "#testingtesting123"
stream = MyStream(credentials['CONSUMER_KEY'], credentials['CONSUMER_SECRET'],
credentials['ACCESS_TOKEN'], credentials['ACCESS_SECRET'])
stream.filter(track=[search_term], threaded=True)
sio.emit('client_connected', "the search term is {}".format(search_term))
@sio.on('disconnect')
def disconnect():
print('Client disconnected')
def handle_message(message):
sio.emit('handle_message', message)
if __name__ == '__main__':
sio.run(app)
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/343848.html
