記錄開發(fā)整套前端flutter+后端go的聊天系統(tǒng)

這段時(shí)間項(xiàng)目不忙,想著搞點(diǎn)事情.于是花了大概一個(gè)月時(shí)間,寫了一套聊天系統(tǒng)。前端是用flutter寫的谅将,后臺(tái)服務(wù)用的go寫的。目前支持ios和安卓雙端運(yùn)行.前后端通訊采用的websocket.目前支持發(fā)送接收重慢。

服務(wù)端用到的技術(shù)
數(shù)據(jù)庫(kù):MySQL+Redis
通訊框架:GRPC
長(zhǎng)連接通訊協(xié)議:Protocol Buffers
日志框架:Zap
ORM框架:GORM

目前支持文字.語(yǔ)音.圖片.視頻消息.(語(yǔ)音圖片視頻存儲(chǔ)在阿里云oss服務(wù)器上)支持單聊饥臂。群聊以及上線拉取未讀離線消息。下面說說我整套設(shè)計(jì)思路(主要是服務(wù)端)以及其中遇到的難點(diǎn)似踱。

設(shè)計(jì)框架.png

已經(jīng)實(shí)現(xiàn)的功能

  • 登陸
  • 注冊(cè)
  • 單聊
  • 群聊
  • 發(fā)送文字
  • 發(fā)送語(yǔ)音
  • 發(fā)送圖片
  • 發(fā)送視頻
  • 離線消息獲取
  • 添加好友
  • 刪除好友
  • 加入群聊
  • 語(yǔ)音實(shí)時(shí)通話
  • 視頻實(shí)時(shí)通話
  • 群拉人(后臺(tái)接口已經(jīng)做好隅熙,剩余前臺(tái))
  • 群踢人(后臺(tái)接口已經(jīng)做好,剩余前臺(tái))
  • 創(chuàng)建群
  • 消息已讀未讀回執(zhí)

安卓端真機(jī)運(yùn)行效果

安卓端.gif

ios模擬器運(yùn)行效果

ios.gif

中間遇到的難點(diǎn)是如何獲取離線消息核芽,當(dāng)用戶端websocket處于離線狀態(tài)時(shí)囚戚,其他用戶發(fā)送的消息都不會(huì)收到,后來查閱資料轧简,目前的解決辦法是每次會(huì)話的message都增加自增seq的字段驰坊,客戶端上線后從本地?cái)?shù)據(jù)庫(kù)查詢每一條會(huì)話的最大的seq值上報(bào)給后端,后端查詢服務(wù)端數(shù)據(jù)哮独,將所有這個(gè)對(duì)象的每一個(gè)會(huì)話大于對(duì)于seq值的消息返回給客戶端拳芙。下面是服務(wù)端代碼

服務(wù)端處理離線消息的代碼

//接受客戶端最后一次的seq參數(shù)查詢離線消息
func (ctx *ConnContext) Sync(input defs.Input) {
    var sync defs.SyncInput
    err := json.Unmarshal([]byte(input.Data), &sync)
    if err != nil {
        log.Print(err)
        ctx.Release()
        return
    }
    seq, _ := strconv.ParseInt(sync.Seq, 10, 64)

    messageList, err := service.MessageService.ListByUserIdAndSeq(ctx.AppId, ctx.UserId, seq)
    var syncOutput defs.SyncOutput
    if err == nil {
        messageItems := make([]defs.MessageItem, 0, 5)
        for _, v := range *messageList {
            var messageItem defs.MessageItem
            messageItem.SenderId = strconv.FormatInt(v.SenderId, 10)
            messageItem.ReceiverId = strconv.FormatInt(v.ReceiverId, 10)
            messageItem.SendTime = util.FormatDatetime(v.SendTime, util.YYYYMMDDHHMMSS)
            messageItem.Type = defs.MessageType(v.Type)
            messageItem.Content = v.Content
            messageItem.Seq = strconv.FormatInt(v.Seq, 10)
            messageItem.Avatar = v.Avatar
            messageItems = append(messageItems, messageItem)
        }
        syncOutput = defs.SyncOutput{Messages: messageItems}
    }
    ctx.Output(defs.PackageType_SYNC, input.RequestId, err, &syncOutput)
}

func (ctx *ConnContext) Heartbeat(input defs.Input) {
    ctx.Output(defs.PackageType_HEARTBEAT, input.RequestId, nil, "PONG")
    log.Print("device_id:", ctx.DeviceId, " PING")
}
// 根據(jù)seq去查詢消息
func (*messageService) ListByUserIdAndSeq(appId, userId, seq int64) (*[]model.Message, error) {
    var err error
    if seq == 0 {
        seq, err = DeviceAckService.GetMaxByUserId(appId, userId)
        if err != nil {
            return nil, err
        }
    }
    messages, err := dao.MessageDao.ListBySeq(appId, model.MessageObjectTypeUser, userId, seq)
    if err != nil {
        return nil, err
    }
    return messages, nil
}

用戶端處理離線消息的代碼

  //從服務(wù)端獲取離線消息
  void getUnreadMessageFromServe(){
    DBService().queryLastMessageSeq().then((value){
      Map param = {
        "seq":value == null?"0":value["Seq"]
      };
      Map sendParam = {
        "type":2,
        "requestId":0,
        "data":convert.jsonEncode(param)
      };
      String sendParamString= convert.jsonEncode(sendParam);
      WebSocketUtility().sendMessage(sendParamString);
    });
  }
//DBService
  Future<Map> queryLastMessageSeq() async{
    await dbUtil.open();
    List<Map> data = await dbUtil.queryList("SELECT * FROM chat_flutter order by id desc");
    print('數(shù)據(jù)庫(kù)查詢的data:$data');
    await dbUtil.close();
    return data.length == 0?null:data[0];
  }
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市皮璧,隨后出現(xiàn)的幾起案子舟扎,更是在濱河造成了極大的恐慌,老刑警劉巖悴务,帶你破解...
    沈念sama閱讀 222,807評(píng)論 6 518
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件睹限,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡惨寿,警方通過查閱死者的電腦和手機(jī)乱凿,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,284評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門蝗砾,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事澡罚。” “怎么了眯牧?”我有些...
    開封第一講書人閱讀 169,589評(píng)論 0 363
  • 文/不壞的土叔 我叫張陵刻两,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我晕换,道長(zhǎng)午乓,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,188評(píng)論 1 300
  • 正文 為了忘掉前任闸准,我火速辦了婚禮益愈,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己蒸其,他們只是感情好敏释,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,185評(píng)論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著摸袁,像睡著了一般钥顽。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上靠汁,一...
    開封第一講書人閱讀 52,785評(píng)論 1 314
  • 那天蜂大,我揣著相機(jī)與錄音,去河邊找鬼蝶怔。 笑死奶浦,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的添谊。 我是一名探鬼主播财喳,決...
    沈念sama閱讀 41,220評(píng)論 3 423
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼斩狱!你這毒婦竟也來了耳高?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,167評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤所踊,失蹤者是張志新(化名)和其女友劉穎泌枪,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體秕岛,經(jīng)...
    沈念sama閱讀 46,698評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡碌燕,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,767評(píng)論 3 343
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了继薛。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片修壕。...
    茶點(diǎn)故事閱讀 40,912評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖遏考,靈堂內(nèi)的尸體忽然破棺而出慈鸠,到底是詐尸還是另有隱情,我是刑警寧澤灌具,帶...
    沈念sama閱讀 36,572評(píng)論 5 351
  • 正文 年R本政府宣布青团,位于F島的核電站,受9級(jí)特大地震影響咖楣,放射性物質(zhì)發(fā)生泄漏督笆。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,254評(píng)論 3 336
  • 文/蒙蒙 一诱贿、第九天 我趴在偏房一處隱蔽的房頂上張望娃肿。 院中可真熱鬧,春花似錦、人聲如沸咸作。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,746評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)记罚。三九已至,卻和暖如春壳嚎,著一層夾襖步出監(jiān)牢的瞬間桐智,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,859評(píng)論 1 274
  • 我被黑心中介騙來泰國(guó)打工烟馅, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留说庭,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,359評(píng)論 3 379
  • 正文 我出身青樓郑趁,卻偏偏與公主長(zhǎng)得像刊驴,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子寡润,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,922評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容

  • 我是黑夜里大雨紛飛的人啊 1 “又到一年六月捆憎,有人笑有人哭,有人歡樂有人憂愁梭纹,有人驚喜有人失落躲惰,有的覺得收獲滿滿有...
    陌忘宇閱讀 8,547評(píng)論 28 53
  • 信任包括信任自己和信任他人 很多時(shí)候,很多事情变抽,失敗础拨、遺憾、錯(cuò)過绍载,源于不自信诡宗,不信任他人 覺得自己做不成,別人做不...
    吳氵晃閱讀 6,195評(píng)論 4 8
  • 怎么對(duì)待生活,它也會(huì)怎么對(duì)你 人都是哭著來到這個(gè)美麗的人間曙痘。每個(gè)人從來到塵寰到升入天堂芳悲,整個(gè)生命的歷程都是一本書,...
    靜靜在等你閱讀 4,984評(píng)論 1 6