2017-11-18 31 views
0

我在Messenger平臺上製作了一個聊天機器人,並詢問用戶一系列的問題。但是,當用戶回答第一個問題時,它直接回到Api.AI中的回退意圖,我必須保持回答同樣的問題直到下一個問題。 我認爲設置一個sessionID將解決這個問題,但它沒有。燒瓶:如何在一定的時間內保留一個變量的值?

ai = ApiAI(os.environ["APIAI_TOKEN"]) 
req = ai.text_request() 
    req.session_id = str(uuid.uuid1(int(str(senderID)[0:15]))) 

事實證明的UUID1的輸出變化時,有時當一個新的請求(當用戶回答了這個問題),即使senderID是相同的(senderID是通過Facebook的發送的用戶ID)。所以,我試圖將uuid1的值保存到字典中,如果用戶回答第一個問題,新請求將首先檢查字典中的senderID,如果它已存在,則不會爲同一個senderID生成新的uuid。 但問題是有時當一個新的請求(來自同一用戶)遇到heroku時,字典中的值消失了。這不會每次都發生,但約90%的時間。 以下是新請求的日誌。

2017-11-18T09:43:03.784670+00:00 heroku[router]: at=info method=POST path="/" host=website.com request_id=ab6d6488-0343-4c68-9b2a-d6faf2ee2302 fwd="173.252.123.140" dyno=web.1 connect=0ms service=633ms status=200 bytes=161 protocol=https 

我該如何保留價值。還有其他方法嗎? 我是一個新手,我一直陷在這個問題一個星期。

回答

0

字典可能沒有綁定到會話,可能會超出範圍並從內存中清除。所以你存儲的任何東西都不會被可靠地持久化。有兩種方法可以解決這個問題。首先是使用像Redis這樣的獨立緩存服務器來存儲你的值,其次是在Flask本身中使用緩存工具。

如果你打算使用外部Redis的服務器,你可以不喜歡下面

import redis 

# instantiate the redis db 
REDIS_HOST = <REDIS_HOST> 
REDIS_PORT = <REDIS_PORT> 
redis_db = redis.StrictRedis(host=REDIS_HOST,port=REDIS_PORT) 

key = sender_id 
event = {} 
event["uuid"] = uuid1 
event["sender_id"] = sender_id 
redis_db.delete(key) #remove old keys 
redis_db.hmset(key, event) 
redis_db.expire(key, 259200) #3 days (you can set your own expire time in seconds 

代碼可以檢查高速緩存,看看是否存在某個值使用

key = sender_id 
if redis_db.exists(key): 
    event = redis_db.hgetall(key) 

第二方式是使用燒瓶的緩存工具與SimpleCache或LRUCache。下面是緩存值,以後可以用

key = sender_id 
event = cache.get(key) 

但是你需要記住retrived使用SimpleCache

from werkzeug.contrib.cache import SimpleCache 
cache = SimpleCache() 

key = sender_id 
event = {} 
event["uuid"] = uuid1 
event["sender_id"] = sender_id 

cache.set(key,event,timeout=259200) # 3 days 

的例子,如果你用使用的高速緩存工具的第二選擇相同的服務器,然後每次您的服務器重新啓動時,您將丟失值,但它們應該在整個會話期間都可用。

+0

當服務器重新啓動時我不會失去redis的值嗎? –

+0

如果你把它安裝在同一臺機器上,是的。但是大多數我認識的人,至少有一些新開發人員使用某種雲服務來進行redis(azure,aws等),因爲它運行在不同的服務器上,所以他們不會重置。 此外,如果答案幫助你,請接受它 – Akshay

相關問題