<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                ## **websocket** > WebSocket 是 HTML5 開始提供的一種在單個 TCP 連接上進行全雙工通訊的協議。 現在,很多網站為了實現推送技術,所用的技術都是 Ajax 輪詢。輪詢是在特定的的時間間隔(如每1秒),由瀏覽器對服務器發出HTTP請求,然后由服務器返回最新的數據給客戶端的瀏覽器。這種方式是讓瀏覽器不斷的向服務器發送請求,因為HTTP請求可能包含較長的頭部,其中真正有效的數據可能只是很小的一部分,顯然這樣會浪費很多的帶寬等資源。 ![](https://img.kancloud.cn/37/92/379278605a69626b3915c6829b1a2cb5_834x444.png) Websocket的處理方式是讓瀏覽器通過 JavaScript 向服務器發出建立 WebSocket 連接的請求,連接建立以后,客戶端和服務器端就可以通過 TCP 連接直接交換數據。 當你獲取 Web Socket 連接后,你可以通過`send()`方法來向服務器發送數據,并通過`onmessage`事件來接收服務器返回的數據。 ## **聊天功能原理** 由客戶端發送Http(`Ajax`)請求,請求后端TP框架。通過TP框架來鑒定客戶端的身份(驗證Token或數據合法性),GatewayWorker只是實現了一個單向推送功能,不會去接收用戶的任何信息(除了綁定之外),復雜的邏輯使用TP框架處理的。 ![](https://box.kancloud.cn/238d9394e0bbe3e03fe72cc73b3f61b6_439x352.png) > GatewayWorker是通過`sendToClient`接口發送某一條信息到客戶端 ``` void Gateway::sendToClient(string $client_id, string $send_data); ``` ## **前端聊天原理流程** ![](https://img.kancloud.cn/7c/43/7c4375995eeeac44e10685f411729d68_670x453.jpg) > 連接websocket需要socket地址,因為在服務器上配置了wss,所以此處域名后面不再接入端口號,而是已經配置好的wss ``` // websocket地址 websocketUrl:"wss://ltkf.gxyuchi.com/wss", ``` ## 配置websocket的信息 ``` // socket地址 url:Config.websocketUrl, // 連接狀態 IsOpen:false, // SocketTask SocketTask:false, // 是否上線(會員id綁定客戶端id,驗證用戶身份,通過則綁定) IsOnline:false, // 當前聊天對象(進入聊天頁面獲取) CurrentToUser:{ userid:0, // 通過判斷userid是否為0,當前用戶處在什么場景下 username:"", userpic:"" ``` ## 連接和關閉websocket 連接websocket,連接時使用`connectSocket`方法需要傳入`url`路徑和`complete`。 傳入`complete`的目的是為了返回一個[socketTask](https://uniapp.dcloud.io/api/request/socket-task)對象 ``` this.SocketTask = uni.connectSocket({ url:this.url, complete: (e)=> { }, }); ``` ## 監聽關閉websocket 關閉websocker連接 ``` // 關閉連接 Close(){ if (this.IsOpen){ this.SocketTask.close(); return uni.removeTabBarBadge({ index:Config.TabbarIndex }); } }, ``` 設置連接狀態為false,并清空`socketTask` ``` this.IsOpen = false; this.SocketTask = false; ``` 當連接成功時,進行用戶綁定,并判斷用戶綁定結果 ``` $http.post('/chat/bind',{ type:'bind', client_id:client_id },{ token:true }).then(data=>{ let [err,res] = data; console.log(res) // 錯誤處理 if (!$http.errorCheck(err,res)) { // 退出登錄,重新鏈接等處理 return; } // 成功 return this.resultUserBind(res.data.data); }); ``` 當通過判斷`bind`來確認用戶綁定成功時,將狀態改為上線并初始化讀取未讀信息方法 判斷條件 ``` res.status && res.type == 'bind' ``` 調用方法 ``` // 獲取總未讀數,并且渲染到tabbar的badge this.initTabbarBadge(); // 獲取未讀信息 this.getChatMessages(); ``` 綁定失敗則斷開連接 ``` uni.showToast({ title: res.msg, icon:"none" }); this.SocketTask.close(); ``` ## **處理未讀信息** ``` // 初始化tabbarBadge initTabbarBadge(){ // 獲取總未讀數 let noreadnum = uni.getStorageSync('noreadnum'+User.userinfo.id); this.__UpdateTabbarBadge(noreadnum); }, ``` ## 存儲到chatdetail 存儲到chatdetail的目的是保存用戶與用戶之間的歷史聊天記錄,通過`issend `來判斷場景是否是發送信息場景,當用戶發送信息成功后,開始保存歷史記錄 ``` res,issend = false ``` 保存歷史記錄時,要考慮舊數據和新數據的同時保存 ``` let userid = issend ? this.CurrentToUser.userid : res.from_id; // 獲取舊數據( chatdetail_[當前用戶id]_[聊天對象id] ) let list = uni.getStorageSync('chatdetail_'+User.userinfo.id+'_'+userid); list = list ? JSON.parse(list) : []; // 追加 list.push(this.__format(res,{ type:"chatdetail", isme:issend, olddata:list, })); ``` ## **更新chatlist** 更新chatlist的目的是將當前會話置頂,修改chatlist中當前會話的data和time顯示。值得注意的是要進行一個判斷,判斷當前會話是否存在,存在:將當前會話置頂;不存在:追加至頭部 ``` // 判斷是否已存在該會話,存在:將當前會話置頂;不存在:追加至頭部 let index = chatlist.findIndex((item)=>{ return item.userid == res.to_id || item.userid == res.from_id; }) // 不存在 if (index == -1) { let obj = this.__format(res,{ type:"chatlist" }); // 忽略本人發送 if (res.from_id !== User.userinfo.id) { obj.noreadnum = 1; } chatlist.unshift(obj); }else{ // 存在:將當前會話置頂,修改chatlist中當前會話的data和time顯示 chatlist[index].data = res.data; chatlist[index].type = res.type; chatlist[index].time = res.time; // 當前聊天對象不是該id,未讀數+1(排除本人發送消息) if (res.from_id !== User.userinfo.id && this.CurrentToUser.userid !== chatlist[index].userid) { chatlist[index].noreadnum++; } // 置頂當前會話 chatlist = this.__toFirst(chatlist,index); } ``` ``` // 數組置頂 __toFirst(arr,index){ if (index != 0) { arr.unshift(arr.splice(index,1)[0]); } return arr; } ``` ## **發送消息** 發送消息的格式分為不同種情況 ``` // 發送的格式 let senddata = this.__format(data,{type:"send"}); ``` 發送時,要對消息的數據字段進行一個轉換 ``` return { to_id:this.CurrentToUser.userid, from_id:User.userinfo.id, from_username:User.userinfo.username, from_userpic:User.userinfo.userpic, type:data.type, data:data.data, time:new Date().getTime() } ``` 之后將已發消息進行歷史記錄保存和置頂操作 ``` // 存儲到chatdetail this.__UpdateChatdetail(senddata,true); // 存儲到chatlist(將當前會話置頂,修改chatlist中當前會話的data和time顯示) this.__UpdateChatlist(senddata); // 發送到服務器(交由頁面去做) return senddata; ``` ## 讀取當前會話 讀取當前會話時,通過用戶發送消息的最后時間來拿到最新的消息 ``` // 拿到當前會話的索引 let index = chatlist.findIndex((value)=>{ return value.userid == item.userid; }); let oldnoreadnum = chatlist[index].noreadnum; // 如果會話存在 if (index !== -1) { chatlist[index].noreadnum = 0; // 存儲 uni.setStorage({ key:"chatlist"+User.userinfo.id,data:JSON.stringify(chatlist) }) // 更新tabbar的badge this.__UpdateNoReadNum({ type:"read",num:oldnoreadnum }); } ```
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看