項目功能-消息推送 (重點)


  • RPC和消息隊列的對比
    • 如果需要服務端立即返回結果, 最好使用RPC(效率高, 不需要中轉)
    • 如果不需要服務端返回結果 或者 需要減輕生產者壓力, 可以使用消息隊列(消費者可以執行異步任務, 減輕同一時間服務器的並發壓力)

將推送消息放入消息隊列中


獲取用戶身份

IM服務器從消息隊列中獲取數據

IM

- 當用戶連接IM時, 取出user_id, 並進入其user_id對應的房間
- 從消息隊列中取出關注通知

# 需求: 讓用戶id 和 sid進行綁定
# 1.獲取用戶id: 傳遞jwt
# 2.綁定用戶身份
from server import sio, JWT_SECRET
from flask import Request


def _get_user_id(token):  # 取出用戶id
    # 取出jwt中的數據
    from jwt_util import verify_jwt
    payload = verify_jwt(token, secret=JWT_SECRET)
    if payload:
        return payload.get('user_id')
    else:
        return None

@sio.on('connect')
def on_connect(sid, envrion):
    request = Request(envrion)
    token = request.args.get('token')
    user_id = _get_user_id(token)
    # 用戶一連接im服務器, 就讓其進入自己的用戶id對應的房間  room="2"
    print("進入房間: %s" % user_id)
    sio.enter_room(sid, str(user_id))

@sio.on('disconnect')
def on_disconnect(sid):
    rooms = sio.rooms(sid)
    for room in rooms:  # 斷開連接, 離開所有的房間
        sio.leave_room(sid, room)

web服務器

- 將關注通知放入消息隊列, 消息發送給作者的user_id對應的房間

  • 細節
    • 測試 web應用必須使用生產模式,否則消息隊列管理器會報錯
  • RabbitMQ amqp://guest:guest@192.168.105.128:5672
上線收到通知的邏輯
1. 用戶一旦連接IM, 
1> 需要讓user_id和sid建立關系
2> 一旦離線就刪除關系  
3> 關系可以存在redis中

2.web應用
1> 從redis中取user_id對應的sid
2> 如果能取出, 說明在線, 直接往消息隊列中添加消息
3> 如果不能取出, 說明離線, 將消息保存到redis中 

3. im應用
1> 一旦建立連接, 先從redis中查詢是否有消息被保存
2> 如果有,取出並發給客戶端, 取出后從redis中刪除數據
3> 同時還需要從消息隊列中實時取出消息數據


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM