Browse Source

及时通信

warrior 4 months ago
parent
commit
f6d796c56c

BIN
projects/live-app/public/img/世界频道.png


+ 15 - 8
projects/live-app/src/moduls/live/chat/chat.component.html

@@ -6,7 +6,9 @@
         style="width: 6.4vw; height: 6.4vw; color: #000000"
       ></ion-icon>
     </ion-buttons>
-    <ion-title class="title">{{ targetUser?.get('nickname') }}</ion-title>
+    <ion-title class="title">{{
+      uid !== "global_room" ? targetUser?.get("nickname") || profile?.get("name") : "世界频道"
+    }}</ion-title>
     <ion-buttons slot="end" id="option-trigger">
       <ion-icon name="ellipsis-horizontal-outline"></ion-icon>
     </ion-buttons>
@@ -41,11 +43,11 @@
     </ng-template>
   </ion-popover>
 
-  <div id="container" style="overflow: hidden">
-    @for (item of msgServe.messageList; track $index) {
+  <div #scrollMsg id="scrollMsg" class="scroll">
+    @for (item of msgServe.messageMapList[uid]; track $index) {
     <div class="clearfix message-box">
-      @if ($index == 0 || item.create_time - msgServe.messageList[$index-1].create_time >
-      60) {
+      @if ($index == 0 || item.create_time -
+      msgServe.messageMapList[uid][$index-1].create_time > 600) {
       <div class="time-box">
         @if (item.istoday) {
         <div class="time">{{ item.timeStamp | date : "HH:mm" }}</div>
@@ -63,9 +65,14 @@
         <img class="avatar fl" mode="widthFix" src="{{ item.avatar }}" />
         <!-- 文字消息 msg_type == 1 || text -->
         @if (item.msg_type == 1 || item.msg_type == 'text') {
-        <div class="text-item fl text-item_left">
-          <p>{{ item.content }}</p>
-        </div>
+          <div class="msg-card">
+            @if(uid == 'global_room'){
+              <span class="text-item_status">{{ item.name || '新人' }}</span>
+            }
+            <div class="text-item fl text-item_left">
+              <p>{{ item.content }}</p>
+            </div>
+          </div>
         }
         <!-- 图片消息 msg_type == 2 || img -->
         @else if(item.msg_type == 2 || item.msg_type == 'img' || item.msg_type

+ 13 - 9
projects/live-app/src/moduls/live/chat/chat.component.scss

@@ -1,5 +1,9 @@
 .content {
-  padding-bottom: 50px;
+  // padding-bottom: 50px;
+  .scroll {
+    overflow: hidden;
+    padding-bottom: 50px;
+  }
   .avatar {
     width: 40px;
     height: 40px;
@@ -56,17 +60,17 @@
         border-left-color: #a2e65b;
       }
     }
-    .self{
+    .self {
       justify-content: end;
     }
-    .no_self{
+    .no_self {
       justify-content: start;
     }
     .text-item_status {
-      height: 40px;
+      // height: 40px;
       display: flex;
       align-items: center;
-      margin-right: 12px;
+      // margin-right: 12px;
       font-size: 12px;
       color: #888;
     }
@@ -107,22 +111,22 @@
     width: 100%;
     .emoji-item {
       width: 30px;
-      height:30px;
+      height: 30px;
       display: flex;
       justify-content: center;
       align-items: center;
-      .emoji-img{
+      .emoji-img {
         width: 20px;
         height: 20px;
       }
     }
     .emoji-item__del {
       width: 30px;
-      height:30px;
+      height: 30px;
       display: flex;
       justify-content: center;
       align-items: center;
-      .emoji-img{
+      .emoji-img {
         width: 20px;
         height: 20px;
       }

+ 43 - 31
projects/live-app/src/moduls/live/chat/chat.component.ts

@@ -27,16 +27,15 @@ import { MessageService } from '../../../services/message.service';
 export class ChatComponent implements OnInit {
   uid: string = '';
   profile?: Parse.Object; // 对方身份
-  targetUser?: Parse.Object;// 对方用户
- 
+  targetUser?: Parse.Object; // 对方用户
   text: string = '';
-
   showPreView: boolean = false; //预览图片
   viewImg: string = '';
   height: number = 0;
   showEmoji: boolean = false;
   emojis: Array<any> = [];
   isOpen: boolean = false;
+  timer: any;
   currentScroll: number = 0; //滚动条位置
   constructor(
     private http: HttpClient,
@@ -44,31 +43,51 @@ export class ChatComponent implements OnInit {
     public toastController: ToastController,
     private loadingCtrl: LoadingController,
     private activateRoute: ActivatedRoute,
-    public msgServe:MessageService,
-  ) {}
+    public msgServe: MessageService
+  ) {
+    msgServe.pageFun = this.updatePage;
+    msgServe.pageFun();
+  }
 
   ngOnInit() {
     this.activateRoute.paramMap.subscribe(async (params) => {
       let id: any = params.get('id');
       this.uid = id;
-      if(!this.uid){
+      if (!this.uid) {
         history.back();
-        return
+        return;
       }
       this.refresh();
     });
   }
+  updatePage() {
+    setTimeout(() => {
+      let dom = document.getElementById('scrollMsg');
+      if (dom) {
+        dom.scrollIntoView({
+          behavior: 'smooth',
+          block: 'end',
+          inline: 'nearest',
+        });
+      }
+    }, 500);
+  }
   async refresh() {
     const loading = await this.loadingCtrl.create({
       message: '加载中',
     });
     loading.present();
-    await this.getProfile()
+    await this.getProfile();
+    await this.msgServe.initRTM(this.uid)
+    await this.msgServe.subscribeMessage(this.uid,{message:true}) //订阅消息
     this.initEmoji();
     loading.dismiss();
   }
   /* 获取用户信息 */
-  async getProfile(){
+  async getProfile() {
+    if (this.uid === 'all') {
+      return;
+    }
     let queryProfile = new Parse.Query('Profile');
     queryProfile.equalTo('user', this.uid);
     queryProfile.notEqualTo('isDeleted', true);
@@ -83,6 +102,10 @@ export class ChatComponent implements OnInit {
       this.targetUser = await queryUser.first();
     }
   }
+  ngOnDestroy(): void {
+    this.msgServe.pageFun = () => {};
+    this.msgServe.unsubscribeMessage(this.uid)
+  }
   initEmoji() {
     let emojiChar =
       '☺-😋-😌-😍-😏-😜-😝-😞-😔-😪-😁-😂-😃-😅-😆-👿-😒-😓-😔-😏-😖-😘-😚-😒-😡-😢-😣-😤-😢-😨-😳-😵-😷-😸-😻-😼-😽-😾-😿-🙊-🙋-🙏-✈-🚇-🚃-🚌-🍄-🍅-🍆-🍇-🍈-🍉-🍑-🍒-🍓-🐔-🐶-🐷-👦-👧-👱-👩-👰-👨-👲-👳-💃-💄-💅-💆-💇-🌹-💑-💓-💘-🚲';
@@ -176,29 +199,32 @@ export class ChatComponent implements OnInit {
     }
     this.emojis = emojis;
   }
+  /* 开始滑动 */
   handleScrollStart() {
     // console.log('scroll start');
   }
+  /* 滑动中 */
   handleScroll(ev: CustomEvent<ScrollDetail>) {
-    // console.log('scroll', ev.detail);
     let srcollop = ev.detail.scrollTop;
-    // console.log(srcollop);
     this.currentScroll = srcollop;
   }
-
+  /* 结束滚动 */
   async handleScrollEnd() {
-    // console.log('scroll end');
     console.log(this.currentScroll);
-    if (this.currentScroll === 0){
+    if (this.currentScroll === 0) {
+      this.timer && clearTimeout(this.timer);
       const loading = await this.loadingCtrl.create({
         message: '消息加载中',
         duration: 1500,
       });
       loading.present();
+      this.timer = setTimeout(() => {
+
+      }, 500);
     }
   }
   //调起表情
-  changeShowEmoji(isClose?:boolean) {
+  changeShowEmoji(isClose?: boolean) {
     this.showEmoji = isClose ? false : !this.showEmoji;
     this.height = 0;
   }
@@ -224,24 +250,10 @@ export class ChatComponent implements OnInit {
       msg_type: 'text',
       content: this.text,
     });
-    this.text = ''
-
+    this.text = '';
   }
   async send(param: { msg_type: string; content: string }) {
-    let that = this;
-    // 2.开始发送消息
-    // let isLogin = JIMServ.checkLogin();
-    this.msgServe.messageList.push({
-      is_self: true,
-      avatar:
-        'https://file-cloud.fmode.cn/Qje9D4bqol/20241109/2t1lp0032258601.png',
-      msg_type: param.msg_type,
-      content: param.content,
-      create_time: new Date(),
-      istoday: true,
-      timeStamp: new Date(),
-    })
-    this.msgServe.publishMessage(param.content)
+    this.msgServe.publishMessage(param.content, this.uid);
   }
   dismiss(evt: any) {
     this.isOpen = false;

+ 16 - 3
projects/live-app/src/moduls/tabs/notice/notice.component.html

@@ -41,6 +41,22 @@
     <ion-segment-content id="notice">
       <div class="notice-list" (touchmove)="onMousemove($event)">
         <ion-list>
+          <ion-item class="li" (click)="toUrl('/live/chat/global_room')">
+            <ion-avatar slot="start">
+              <img src="img/世界频道.png" alt="avatar" />
+            </ion-avatar>
+            <div class="li-right">
+              <div class="name">
+                世界频道
+                <!-- <span class="time">{{
+                  msgServe.messageMapList['global_room'].slice(-1)[0].timeStamp | showDate
+                }}</span> -->
+              </div>
+              <div class="message-content">
+                {{ '点击进入频道聊天' }}
+              </div>
+            </div>
+          </ion-item>
           @for (item of noticeList; track $index) {
           <ion-item
             class="li"
@@ -48,7 +64,6 @@
             (touchstart)="startPress()"
             (mousemove)="stopPress()"
           >
-            <!-- <div class="li" (touchstart)="startPress()" (mousemove)="stopPress()"> -->
             <ion-avatar slot="start">
               <img [src]="item.avatar" alt="avatar" />
             </ion-avatar>
@@ -59,9 +74,7 @@
               </div>
               <div class="message-content">{{ item.content || "暂无" }}</div>
             </div>
-            <!-- </div> -->
           </ion-item>
-
           }
         </ion-list>
       </div>

+ 14 - 9
projects/live-app/src/moduls/tabs/notice/notice.component.ts

@@ -5,12 +5,13 @@ import { InfiniteScrollCustomEvent } from '@ionic/angular';
 import { Router } from '@angular/router';
 import { AiChatService } from '../../../services/aichart.service';
 import { SharedModule } from '../../shared.module';
+// import { MessageService } from '../../../services/message.service';
 @Component({
   selector: 'app-notice',
   templateUrl: './notice.component.html',
   styleUrls: ['./notice.component.scss'],
   standalone: true,
-  imports: [IonicModule,SharedModule],
+  imports: [IonicModule, SharedModule],
 })
 export class NoticeComponent implements OnInit {
   active: string = 'notice';
@@ -43,18 +44,22 @@ export class NoticeComponent implements OnInit {
   timer: any;
   showModal: boolean = false; //是否长按弹窗
   currentObject: any; //当前选择对象
-  constructor(private router: Router, private aiSer:AiChatService) {}
+  constructor(
+    private router: Router,
+    private aiSer: AiChatService,
+    // public msgServe: MessageService
+  ) {}
 
   ngOnInit() {
-    this.refresh()
+    this.refresh();
   }
-  async refresh(){
-    let uid:any = Parse.User.current()?.id
-    let resultFriends = await this.aiSer.getFriends(uid)
-    this.friends = resultFriends['data']
+  async refresh() {
+    let uid: any = Parse.User.current()?.id;
+    let resultFriends = await this.aiSer.getFriends(uid);
+    this.friends = resultFriends['data'];
     console.log(this.friends);
-    let resChat = await this.aiSer.getLinkUsers(uid)
-    resChat?.data && this.noticeList.push(...resChat.data)
+    let resChat = await this.aiSer.getLinkUsers(uid);
+    resChat?.data && this.noticeList.push(...resChat.data);
   }
   segmentChanged(e: any) {
     let { value } = e.detail;

+ 3 - 3
projects/live-app/src/moduls/tabs/tabs/tabs.component.ts

@@ -6,9 +6,9 @@ import { IonicModule } from '@ionic/angular';
 
 // 全局消息服务和JIM插件
 import { OnInit } from '@angular/core';
-// import { MessageService } from './chat/message.service';
 import { AlertController } from '@ionic/angular';
-import { MessageService } from '../../../services/message.service';
+// import { MessageService } from '../../../services/message.service';
+import { ConnectTaskService } from '../../../services/connectTask.service';
 
 @Component({
   selector: 'live-tabs',
@@ -24,7 +24,7 @@ export class TabsComponent implements OnInit {
   constructor(
     private router: Router,
     private alertController: AlertController,
-    private messageServ: MessageService
+    private connectTask: ConnectTaskService
   ) {
     this.active = Number(localStorage.getItem('active')) || 0
     this.presentAlert();

+ 11 - 0
projects/live-app/src/services/connectTask.service.ts

@@ -0,0 +1,11 @@
+import { Injectable } from '@angular/core';
+import { MessageService } from './message.service';
+@Injectable({
+  providedIn: 'root',
+})
+export class ConnectTaskService {
+  msChannelName: string = 'user_connect_room'; // 保存用户连接状态
+  constructor(private msgSer: MessageService) {
+    this.msgSer.initRTM(this.msChannelName);
+  }
+}

+ 218 - 113
projects/live-app/src/services/message.service.ts

@@ -9,169 +9,274 @@ declare const AgoraRTM: any;
 })
 export class MessageService {
   rtmClient: any; // RTM实例
+  // rtmClientMap: any = {};
+  channelNameList: any = {}; //订阅频道状态
   msChannelName: string = 'global_room'; // 全球频道
   options: any = {
-    appid: '',
-    userId: Parse.User.current()?.id,
-    token:
-      '007eJxTYGh7sUrIjKd9bl9ncuOq0mvLordY/r5dWv64Y3Wz5uVrNcwKDMmJBqbmJpaGickWliapFkYWBkYWqclp5sbmaSaphhYm+juD0hsCGRlOuFsyMDIwATEjA4jPxZBjkO5maeoU4OMEACaMIUE=',
+    connectState: false,
   };
+  appid?: string;
+  userId: string = Parse.User.current()?.id!;
+
+  pageFun?: Function; //页面传入的方法
   constructor(private liveService: LiveService, private http: HttpService) {
-    this.initRTM();
+    // this.initRTM(this.msChannelName);
   }
-  messageList: any = [
-    {
-      is_self: true,
-      avatar:
-        'https://file-cloud.fmode.cn/Qje9D4bqol/20241109/2t1lp0032258601.png',
-      msg_type: 1,
-      content: 'nihao',
-      create_time: new Date(),
-      istoday: true,
-      timeStamp: new Date(),
-      data: [
-        {
-          create_time: new Date(),
-        },
-      ],
-    },
-    {
-      is_self: true,
-      avatar:
-        'https://file-cloud.fmode.cn/Qje9D4bqol/20241109/2t1lp0032258601.png',
-      msg_type: 1,
-      content: `Use the pipe name to trace where the pipe is declared and used. To resolve this error: If the pipe is local to the NgModule, give it a unique name in the pipe's decorator and declared it in the NgModule. If the pipe is standalone or is declared in another NgModule, add it to the imports field of the standalone component or the current NgModule.`,
-      create_time: new Date(),
-      istoday: true,
-      timeStamp: new Date(),
-      data: [
-        {
-          create_time: new Date(),
-        },
-      ],
-    },
-    {
-      is_self: false,
-      avatar:
-        'https://file-cloud.fmode.cn/Qje9D4bqol/20241109/2t1lp0032258601.png',
-      msg_type: 1,
-      content: 'nihao',
-      create_time: new Date(),
-      istoday: true,
-      timeStamp: new Date(),
-      data: [
-        {
-          create_time: new Date(),
-        },
-      ],
-    },
-  ]; // 世界频道消息列表
+  messageMapList: any = {
+    global_room: [
+      // 世界频道消息列表
+      {
+        is_self: true,
+        avatar:
+          'https://file-cloud.fmode.cn/Qje9D4bqol/20241109/2t1lp0032258601.png',
+        msg_type: 1,
+        content: 'nihao',
+        create_time: new Date(),
+        istoday: true,
+        timeStamp: new Date(),
+      },
+      {
+        is_self: true,
+        avatar:
+          'https://file-cloud.fmode.cn/Qje9D4bqol/20241109/2t1lp0032258601.png',
+        msg_type: 1,
+        content: `Use the pipe name to trace where the pipe is declared and used. To resolve this error: If the pipe is local to the NgModule, give it a unique name in the pipe's decorator and declared it in the NgModule. If the pipe is standalone or is declared in another NgModule, add it to the imports field of the standalone component or the current NgModule.`,
+        create_time: new Date(),
+        istoday: true,
+        timeStamp: new Date(),
+      },
+      {
+        is_self: true,
+        avatar:
+          'https://file-cloud.fmode.cn/Qje9D4bqol/20241109/2t1lp0032258601.png',
+        msg_type: 1,
+        content: `Use the pipe name to trace where the pipe is declared and used. To resolve this error: If the pipe is local to the NgModule, give it a unique name in the pipe's decorator and declared it in the NgModule. If the pipe is standalone or is declared in another NgModule, add it to the imports field of the standalone component or the current NgModule.`,
+        create_time: new Date(),
+        istoday: true,
+        timeStamp: new Date(),
+      },
+      {
+        is_self: true,
+        avatar:
+          'https://file-cloud.fmode.cn/Qje9D4bqol/20241109/2t1lp0032258601.png',
+        msg_type: 1,
+        content: `Use the pipe name to trace where the pipe is declared and used. To resolve this error: If the pipe is local to the NgModule, give it a unique name in the pipe's decorator and declared it in the NgModule. If the pipe is standalone or is declared in another NgModule, add it to the imports field of the standalone component or the current NgModule.`,
+        create_time: new Date(),
+        istoday: true,
+        timeStamp: new Date(),
+      },
+      {
+        is_self: false,
+        avatar:
+          'https://file-cloud.fmode.cn/Qje9D4bqol/20241109/2t1lp0032258601.png',
+        msg_type: 1,
+        content: 'nihao',
+        create_time: new Date(),
+        istoday: true,
+        timeStamp: new Date(),
+      },
+    ],
+  };
+
   /* 获取token */
-  async getToken(channel: string) {
+  async getToken(channel?: string) {
     //获取频道token记录
     let uid = Parse.User.current()?.id;
     let baseurl = 'https://server.fmode.cn/api/webrtc/build_token';
     let reqBody = {
       company: this.liveService.company, // this.aiSer.company,
-      channelName: channel,
+      channelName: this.msChannelName,
       type: 'withrtm',
       account: uid,
     };
     let data: any = await this.http.httpRequst(baseurl, reqBody, 'POST');
     console.log(data);
     if (data.code == 200) {
+      // this.options[channel] = {
+      //   token: data.data.token,
+      // };
       this.options.token = data.data.token;
-      this.options.appid = data.data.appid;
+      this.appid = data.data.appid;
     }
   }
 
-  async initRTM() {
-    await this.getToken(this.msChannelName);
-    console.log();
-    this.rtmClient = new AgoraRTM.RTM(this.options.appid, this.options.userId);
+  async initRTM(channelName: string) {
+    // let states = ['CONNECTED', 'CONNECTING'];
+    //已连接,无需重复连接
+    // if (
+    //   this.rtmClientMap?.[channelName]?.connectState &&
+    //   states.includes(this.rtmClientMap[channelName].connectState)
+    // )
+    //   return;
+    // console.log('initRTM');
+
+    if (this.options.connectState) return;
+    await this.getToken(channelName);
+    this.rtmClient = new AgoraRTM.RTM(this.appid, this.userId);
+    // this.rtmClientMap[channelName] = {
+    //   rtmClient: new AgoraRTM.RTM(this.appid, this.userId),
+    // };
     this.joinReady();
     await this.loginRTM();
-    // await this.join();
-    this.subscribeMessage(this.msChannelName);
+    this.subscribeMessage(channelName);
   }
   /* 监听频道消息 */
-  joinReady() {
+  joinReady(channelName?: string) {
     this.rtmClient.addEventListener('message', (event: any) => {
-      this.showMessage(event.publisher, event.message);
+      console.log('message', event);
+      this.showMessage(event);
     });
-    console.log('initRTM');
-    // Pressence event handler.
     this.rtmClient.addEventListener('presence', (event: any) => {
-      console.log('presence event: ', event);
-      if (event.eventType === 'SNAPSHOT') {
-        this.showMessage('INFO', 'I Join');
-      } else {
-        this.showMessage('INFO', event.publisher + ' is ' + event.eventType);
-      }
+      console.log('频道人员状态变化 ', event);
+      this.pageFun?.();
     });
-    this.rtmClient.addEventListener('status', (event: any) => {
-      console.log('status event: ', event);
-      // The current connection state.
-      const currentState = event.state;
-      const changeReason = event.reason;
-      // this.showMessage('INFO', JSON.stringify(event));
+    this.rtmClient.addEventListener('linkState', (event: any) => {
+      console.log('连接状态: ', event);
+      // this.rtmClientMap[channelName].connectState = event.currentState;
     });
   }
   /* 加入频道 */
-  async join() {
-    const options = {
-      token: this.options.token,
-      withPresence: true,
-      withLock: true,
-      withMetadata: true,
-    };
+  // async join(channelName: string) {
+  //   const options = {
+  //     token: this.options[channelName].token,
+  //     withPresence: true,
+  //     withLock: true,
+  //     withMetadata: true,
+  //   };
+  //   try {
+  //     const streamChannel =
+  //       this.rtmClientMap[channelName].rtmClient.createStreamChannel(
+  //         channelName
+  //       );
+  //     const result = await streamChannel.join(options);
+  //   } catch (status) {
+  //     console.error('join channel failed: ', status);
+  //   }
+  // }
+  async loginRTM(channelName?: string) {
     try {
-      const streamChannel = this.rtmClient.createStreamChannel(
-        this.msChannelName
-      );
-      const result = await streamChannel.join(options);
-    } catch (status) {
-      console.error('join channel failed: ', status);
-    }
-  }
-  async loginRTM() {
-    // console.log(this.options.token);
-    try {
-      const result = await this.rtmClient.login({ token: this.options.token });
-      // console.log(result);
+      await this.rtmClient.login({
+        token: this.options.token,
+      });
+      this.options.connectState = true; // 登录成功
+      let userMateData = await this.getUserMetadata(this.userId);
+      if(!userMateData){
+        let user = Parse.User.current();
+        const metadata = [
+          {
+            key: 'nickname',
+            value: user?.get('nickname'),
+          },
+          {
+            key: 'avatar',
+            value:
+              user?.get('avatar') ??
+              'https://file-cloud.fmode.cn/DXNgcD6zo6/20221202/j6p8kb034039.png',
+          },
+        ];
+        const options = {
+          userId: this.userId,
+          addTimeStamp: true,
+          addUserId: true,
+        };
+        let result = await this.rtmClient.storage.setUserMetadata(
+          metadata,
+          options
+        );
+        console.log(JSON.stringify(result));
+      }
     } catch (status) {
       console.log(status);
     }
   }
-
-  subscribeMessage(channelId: string, callback?: any) {
-    this.rtmClient.subscribe(channelId);
+  logOutRTM() {
+    this.rtmClient.logout().then(() => {
+      console.log('logout success');
+      this.options.connectState = false
+    });
+  }
+  /* 订阅消息 */
+  subscribeMessage(channelName: string, param?: any, callback?: any) {
+    if (this.channelNameList[channelName]) return;
+    const options = {
+      withMessage: param?.message ?? false, // message 事件
+      withPresence: false, // presence 事件
+      beQuiet: false, // quiet 事件
+      withMetadata: false, // metadata 事件
+      withLock: false, // lock 事件
+    };
+    this.rtmClient
+      .subscribe(channelName, options)
+      .then((res: any) => {
+        console.log('subscribeMessage', res);
+        //订阅成功
+        this.channelNameList[channelName] = true;
+      })
+      .catch((err: any) => {
+        console.error('subscribeMessageErr', err);
+      });
+  }
+  /* 取消订阅 */
+  unsubscribeMessage(channelName: string) {
+    this.rtmClient
+      .unsubscribe(channelName)
+      .then((res: any) => {
+        console.log('unsubscribeMessage', res);
+        //订阅成功
+        this.channelNameList[channelName] = false;
+      })
+      .catch((err: any) => {
+        console.error('unsubscribeMessage', err);
+      });
   }
 
-  showMessage(user: any, msg: string) {
-    console.log(user, msg);
-    this.messageList.push({
-      user,
-      msg,
+  async showMessage(param: any) {
+    let userData = await this.getUserMetadata(param.publisher);
+    let is_self = param.publisher == this.userId;
+    // let r: any = Parse.User.current()!;
+    // if (!is_self) {
+    //   let queryUser = new Parse.Query('_User');
+    //   queryUser.equalTo('objectId', param.publisher);
+    //   queryUser.select('avatar', 'nickname');
+    //   r = await queryUser.first();
+    // }
+    console.log(userData);
+    let message = JSON.parse(param.message);
+    this.messageMapList[param.channelName].push({
+      is_self: is_self,
+      avatar:
+        userData.avatar.value ??
+        'https://file-cloud.fmode.cn/DXNgcD6zo6/20221202/j6p8kb034039.png',
+      msg_type: 1,
+      name: userData.nickname.value ?? '未知用户',
+      content: message?.message ?? '',
+      create_time: new Date(param.timeStamp),
+      istoday: true,
+      timeStamp: new Date(param.timeStamp),
     });
-    // const inputText = textInput.value;
-    // const newText = document.createTextNode(user + ": " + msg);
-    // const newLine = document.createElement("br");
-    // textDisplay.appendChild(newText);
-    // textDisplay.appendChild(newLine);
+    this.pageFun?.();
+  }
+  async getUserMetadata(uid: string) {
+    try {
+      const result = await this.rtmClient.storage.getUserMetadata({
+        userId: uid,
+      });
+      return result.metadata;
+    } catch (status) {
+      console.log(JSON.stringify(status));
+    }
   }
 
-  async publishMessage(message: string) {
+  async publishMessage(message: string, channelName: string) {
     const payload = { type: 'text', message: message };
     const publishMessage = JSON.stringify(payload);
     const publishOptions = { channelType: 'MESSAGE' };
     try {
       const result = await this.rtmClient.publish(
-        this.msChannelName,
+        channelName,
         publishMessage,
         publishOptions
       );
-      this.showMessage(this.options.userId, publishMessage);
       console.log(result);
     } catch (status) {
       console.log(status);