架構說明
建立一個Component及Service,分別負責處理控制及服務。
cd src/appng g c agora-rtmng g s agora-rtm
App.component基本不動,只在App.component.html中將Component引入。
<app-agora-rtm></app-agora-rtm>
安裝SDK
npm install agora-rtm-sdk
import 進剛剛建的Service(agora-rtm.service.ts)
import AgoraRTM, { RtmChannel, RtmClient, RtmMessage } from ‘agora-rtm-sdk’;
核心程式碼(agora-rtm.service)
這邊要負責主要的邏輯,讓Component能控制。
我們需要建立的Function()為:
- 初始化對象變數
- 初始化本地端
- 建立頻道
- 登入使用者
- 對頻道發出訊息
- 對特定人發出訊息
- 離開頻道
以及其他像是
- 取得本地端資料
- 取得頻道資料
知道要做什麼之後,一步一步來。
1.初始化對象變數
private rtm: { client: RtmClient | null, channel: RtmChannel | null } = { client: null, //本地端資料 channel: null //頻道資料}
2.初始化本地端
initRTMClient(): RtmClient {if (!this.rtm.client) { this.rtm.client = AgoraRTM.createInstance
(
"<你的Agora項目 AppID>",
{ enableLogUpload: false }
); } return this.rtm.client;}
3.建立頻道
createRTMChannel(channelId: string): RtmChannel | undefined { if (!this.rtm.client) { return; } this.rtm.channel = this.rtm.client.createChannel(channelId); return this.rtm.channel}
4.登入使用者
先寫好Function,等等讓component控制,目的是只需要給UID(在該頻道內必須是唯一)以及該UID對應到的token
如何拿到UID跟其對應的TOKEN:到控制台輸入你想要的UID,然後會產生入一對應TOKEN。
async loginRTMClient(uid: string,token:string) { if (!this.rtm.client) { return; } const config = { uid: uid, token: token } await this.rtm.client.login(config);}
5.對頻道發出訊息
async sendChannelMessage(message: RtmMessage) { if (!this.rtm.channel) { return; } await this.rtm.channel.sendMessage(message);}
6.對特定人發出訊息
async sendPeerMessage(message: RtmMessage, toUserId: string) { if (!this.rtm.client) { return; } await this.rtm.client.sendMessageToPeer(message, toUserId);}
7.離開頻道
離開頻道
async leaveRTMChannel() { if (!this.rtm.channel) { return; } await this.rtm.channel.leave();}
登出
async logoutRTMClient() { if (!this.rtm.client) { return; } await this.rtm.client.logout();}
有了上面兩個後,可以再寫一個Function給ngDestory時呼叫
async destroyRTM() { await this.leaveRTMChannel(); await this.logoutRTMClient(); this.rtm.client = null; this.rtm.channel = null;}
其他
1.取得本地端資料
getRTMClient(): RtmClient | null { return this.rtm.client;}
2.取得頻道資料
getRTMChannel(): RtmChannel | null { return this.rtm.channel;}
控制部分(agora-rtm.component.ts)
上面Service已經都把邏輯寫好了,這邊只需要負責呼叫就行,不過這邊要額外再寫一個負責訂閱事件的功能。
這邊主要的流程及功能為:
0.建立HTML基礎樣式
1.初始化RTM
2.訂閱Client端訊息
3.訂閱頻道訊息
4.送出頻道訊息
5.送出密語
7.建立訊息的div 輸出到HTML上
8.Destory
知道要做什麼之後,一步一步來。
0.建立HTML基礎樣式
簡單做一個身分選擇、加入、送出輸入訊息的HTML
<p>選擇登入身分</p> <select #user> <option value=”0">Ray</option> <option value=”1">Dev</option> </select>
<br> <button (click)=”initRTM(user.value)”>加入頻道</button> <button (click)=”destoryRTM()”>離開頻道</button>
<br> <input #inputMsg id =”inputMsg”> <button (click)=”sendChannelMessage(inputMsg.value)”>送出</button>
<div
id = “log”
style=”display: flex; flex-direction: column-reverse;”
>
</div>
簡單說明:依照選擇的身分,將下拉選單所選的Index值傳給initRTM(),讓initRTM()知道要用什麼身分登入。
以及將Input的資料傳給sendChannelMessage(),將輸入的資料送出。這邊只是參考,沒有一定要照這樣做。
再來開始把上面的Function一個一個補上。
1.初始化RTM
(訂閱的Function在後面,第3及第4項)
async initRTM(index: string) {
if (index == ‘0’) { this.uid = “<UID>”; // 我上面的範例 這邊是Ray this.token = “<UID對應到的TOKEN>” } else { this.uid = “<UID>”; // 我上面的範例 這邊是Dev this.token = “<UID對應到的TOKEN>” }
this.agoraRTMService.initRTMClient(); this.subscribeRTMClientEvent(); await this.agoraRTMService.loginRTMClient(this.uid, this.token); const channel = this.agoraRTMService.createRTMChannel(‘Test’); this.subscribeRTMChannelEvent(); await channel?.join().then(() => { this.createChatLogDiv(“歡迎:” + this.uid + “加入”); })}
初始化的部分第一步是先根據下拉選單給出對應的UID以及TOKEN,正常來說應該是讓使用者輸入一個UID後呼叫API回傳TOKEN再拿這些資料做登入,這邊求方便先寫這樣。
再來是呼叫Service的initRTMClient()、登入、建立頻道、加入頻道,這個Component在initRTM()需要做的只有寫訂閱的Function。
2.訂閱Client端訊息
(createChatLogDiv在後面,第7項)
subscribeRTMClientEvent() {this.agoraRTMService.getRTMClient()!.on(‘MessageFromPeer’, (message, peerId) => { if (message.messageType === ‘TEXT’) { this.createChatLogDiv(`(密語) ${peerId} 對你說: ‘${message.text}’`); }});}
3.訂閱頻道訊息
subscribeRTMChannelEvent() { this.agoraRTMService.getRTMChannel()!.on(‘ChannelMessage’, (message, memberId) => { if (message.messageType === ‘TEXT’) { this.createChatLogDiv(memberId + “:” + message.text); }}); this.agoraRTMService.getRTMChannel()!.on(‘MemberJoined’, memberId => { this.createChatLogDiv(“歡迎:” + memberId + “加入”);});this.agoraRTMService.getRTMChannel()!.on(‘MemberLeft’, memberId => { this.createChatLogDiv(memberId + “離開”);});}
4.送出頻道訊息
sendChannelMessage(msg: string) {if (msg == "") { return; } this.agoraRTMService.sendChannelMessage({ text: msg }); this.createChatLogDiv(this.uid + ":" + msg);}
5.送出密語
sendPeerMessage(msg: string) { this.agoraRTMService.sendPeerMessage({ text: msg }, '<對方UID>');}
7.建立訊息的div 輸出到HTML上
createChatLogDiv(msg: string) {(<HTMLInputElement>document.getElementById("log")).appendChild(document.createElement('div')).append(msg)}
8.Destory
ngOnDestroy() { this.destoryRTM();}destoryRTM() { this.agoraRTMService.destroyRTM().then(() => { this.createChatLogDiv(this.uid + “離開”); });}