使用Python的Tornado框架實(shí)現(xiàn)一個一對一聊天的程序
按思路來聊:
類似微信,點(diǎn)擊用戶可以進(jìn)入一對一聊天頁面;另有聊天框列表包含所有存在聊天記錄的一對一聊天框,點(diǎn)擊進(jìn)入聊天頁面。
【數(shù)據(jù)結(jié)構(gòu)】
因?yàn)殡p方都有聊天記錄,所以每一個聊天實(shí)際上得儲存兩份,設(shè)計(jì)的數(shù)據(jù)結(jié)構(gòu)如下:
A :
user_a = {“id”:1,”name”:”A”}
B :
user_b = {“id”:2,”name”:”B”}
A的聊天記錄:
chat_a = { “id”:1, “user”:1, “who”:2, “name”:”B”, “new”:0, msg:[]}
B的聊天記錄:
chat_b = { “id”:2, “user”:2, “who”:1, “name”:”A”, “new”:0, msg:[]}
msg實(shí)際上是個list,結(jié)構(gòu)如下:msg = { “user”:發(fā)送者id, “name”:發(fā)送者name, “date”:發(fā)送時間, “content”:消息內(nèi)容 }
【業(yè)務(wù)邏輯】
當(dāng)A點(diǎn)擊好友列表中B的名字–>進(jìn)入聊天框(根據(jù)雙方id通過字段user、who找到對應(yīng)chat_a,chat = coll.find_one({“user”:user_a[‘id'], “who”:user_b[‘id']});如果該chat不存在,則利用雙方id創(chuàng)建chat_a)
發(fā)送消息(更新chat_a和chat_b,如果chat_b不存在則創(chuàng)建chat_b;如果chat_b不在線則更新chat_b[‘new'] = 1)
A刪除聊天框(刪除chat_a)
【記錄客戶端連接】
由于是多個一對一聊天,所以不能直接用教程里的set來記錄連接。
最后的決定是用一個 dict,用雙方用戶id拼接的字符串作為key,用list存客戶端連接。
...SocketHandler(...):
chats = dict() ... def on_open(self): ... #通過雙方id來生成一個獨(dú)一無二的字符串 min = user_a['id'] max = user_b['id'] if min >max: max = user_a['id'] min = user_b['id'] key = str(user_a['id'])+"_"+str(user_b['id']) #判斷當(dāng)前會話是否存在,存在則添加當(dāng)前用戶 if key in chats: SocketHandler.chats[key].append(self) #不存在則創(chuàng)建會話,并將當(dāng)前用戶添加進(jìn)去 else SocketHandler.chats[key] = [self]
【發(fā)送消息】
從客戶端調(diào)用send函數(shù),在服務(wù)端on_message函數(shù)中接受參數(shù)后更新雙方聊天記錄。之后調(diào)用send_to_all(key, message)來更新聊天窗口。
【發(fā)通知/更新聊天窗口】
更新數(shù)據(jù)庫里的聊天記錄后還要在聊天窗口更新html,所以需要通知該會話的連接者。
根據(jù)我們記錄連接者的方式,對應(yīng)的通知函數(shù)如下:
def send_to_all(key,message): for user in SocketHandler.chats[key]: user.write_message(json.dumps(message))
【關(guān)閉連接】
根據(jù)我們記錄連接者的方式,對應(yīng)的關(guān)閉函數(shù)如下:
def on_close(self): ... #用on_open函數(shù)中的方法構(gòu)造key if key in SocketHandler.chats: SocketHandler.chats[key].remove(self)#刪除當(dāng)前連接 if len(SocketHandler.chats[key]) == 0: del SocketHandler.chats[key]#當(dāng)會話無連接者則刪除會話
經(jīng)過上面的改造,就實(shí)現(xiàn)多個一對一聊天功能
相關(guān)文章
import?sklearn報(bào)錯正確安裝sklearn的解決方法
這篇文章主要介紹了import?sklearn報(bào)錯正確安裝sklearn的解決方法,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-04-04Python Pandas pandas.read_sql函數(shù)實(shí)例用法
在本篇文章里小編給大家整理的是一篇關(guān)于Python Pandas pandas.read_sql函數(shù)詳解內(nèi)容,有需要的朋友們可以學(xué)習(xí)下。2021-06-06實(shí)例講解Python爬取網(wǎng)頁數(shù)據(jù)
這篇文章給大家通過實(shí)例講解了Python爬取網(wǎng)頁數(shù)據(jù)的步驟以及操作過程,有興趣的朋友跟著學(xué)習(xí)下吧。2018-07-07Python內(nèi)建屬性getattribute攔截器使用詳解
這篇文章主要為大家介紹了Python內(nèi)建屬性getattribute攔截器使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-05-05實(shí)例詳解Python的進(jìn)程,線程和協(xié)程
這篇文章主要為大家詳細(xì)介紹了Python進(jìn)程,線程和協(xié)程,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助2022-03-03用python監(jiān)控服務(wù)器的cpu,磁盤空間,內(nèi)存,超過郵件報(bào)警
這篇文章主要介紹了如果用python監(jiān)控服務(wù)器的cpu,磁盤空間,內(nèi)存,超過郵件報(bào)警,幫助大家更好的理解和使用python,感興趣的朋友可以了解下2021-01-01詳解Python的多線程定時器threading.Timer
這篇文章主要為大家介紹了Python的多線程定時器,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助2022-01-01