Skip to content

3_2 直播_聊天

SHLURENJIA edited this page Aug 19, 2020 · 5 revisions

1 关于"聊天"模块

1.1 简介

背景:聊天室模块在UI、交互、功能上,相较于其他模块,都会更复杂更庞大。因此设计、搭建、维护一个聊天室,也是一件较为费时费力的事情。我们推荐直接使用保利威封装好的聊天室模块,该部分代码完全开源,支持直接使用,以及二次开发。

1.2 源码引入

聊天室的相关的逻辑在demo/main/../cloudclassdemo/watch/chat目录下

2 基础使用

在此介绍快速集成聊天室SDK的方式,是比较基础的功能,更多的功能请直接引入demo的代码。

2.1 初始化

IPolyvChatManager chatManager = new PolyvChatManager();
//设置开发者userId
chatManager.setAccountId(userId);
//登录
chatManager.login(viewerId, channelId, viewerName);
//监听聊天室连接状态
chatManager.addConnectStatusListener { status, t ->
    //int STATUS_DISCONNECT = 1;断开连接
    //int STATUS_LOGINING = 2;登录中
    //int STATUS_LOGINSUCCESS = 3;登录成功
    //int STATUS_RECONNECTING = 4;重连中
    //int STATUS_RECONNECTSUCCESS = 5;连接成功
}

2.2 发送消息

  1. 发送群聊消息

    String msg = "群聊消息" ;
    PolyvLocalMessage localMessage = new PolyvLocalMessage(msg);
    chatManager.sendChatMessage(localMessage)
    
    //0.15.0 新增接口发送消息支持回调消息id,详细使用查看PolyvChatGroupFragment相关实现
    chatManager.sendChatMessage(localMessage, needIdCallback, ack)
  2. 发送提问(即私聊)消息

    String msg = "提问消息";
    chatManager.sendQuestionMessage(msg)

2.3 接收消息

以下代码演示如何解析群聊消息和私聊消息

IPolyvChatManager chatManager = new PolyvChatManager();
chatManager.addNewMessageListener(new PolyvNewMessageListener() {
    @Override
    public void onNewMessage(String message, String event) {
        //回调信息的线程为主线程
        switch (event) {
            //群聊消息
            case PolyvChatManager.EVENT_T_ANSWER:
                PolyvTAnswerEvent answerEvent = PolyvEventHelper.getEventObject(PolyvTAnswerEvent.class, message, event);
                if (answerEvent.getS_userId().equals(viewerId)) {
                    //观众id和自己的id相等,才是回答自己的
                    String msg = answerEvent.getContent();
                }
                break;
            //私聊消息
            case PolyvChatManager.EVENT_SPEAK:
                PolyvSpeakEvent speakEvent = PolyvEventHelper.getEventObject(PolyvSpeakEvent.class, message, event);
                //群聊文本消息
                String msg = speakEvent.getValues().get(0);
                break;
			//其他类型的消息和解析请看demo的PolyvChatGroupFragment
        }
    }
    @Override
    public void onDestroy() {
        //聊天室被销毁时调用
    }
});

如果需要在子线程回调信息,可以使用如下方法:

PolyvChatManager.getInstance().addNewMessageListener(newMessageListener2, true);

2.4 聊天室后台控制

//需要在登录成功后才能获取到
PolyvChatFunctionSwitchVO getChatFunctionSwitchVO()

2.5 销毁聊天室

//断开socket连接,移除所有监听器,不再收发消息。可在Activity的onDestroy()调用
chatManager.destroy()

以上是对聊天室的的基础使用,以下是对聊天室业务进一步说明


3 登录聊天室

PolyvChatManager chatManager = new PolyvChatManager();
//后台获取的唯一的开发者账号ID
chatManager.setAccountId(userId);
//设置用户类型
chatManager.userType = isNormalLive ? PolyvChatManager.USERTYPE_STUDENT : PolyvChatManager.USERTYPE_SLICE;
//登录接口参考javaDoc的IPolyvChatManager类,可以设置观看用户昵称,头像,头衔,这里例举一个:
 chatManager.login(studentUserId, channelId, studentNickName);

4 发言

4.1 群聊发言

IPolyvChatManager{
 	 **
     * 发送聊天信息至聊天室
     *
     * @param localMessage 聊天信息实体
     * @return {@link com.easefun.polyv.cloudclass.chat.PolyvLocalMessage.SendValue}
     */
    int sendChatMessage(PolyvLocalMessage localMessage);
}

可根据方法的返回值来判断发送消息是否成功,是否被禁言,踢出房间等。

demo中,该方法在PolyvGroupChatFragment中的sendLocalMessage()方法和sendChatMessageByDanmu(String sendMessage)方法被调用,分别表示群聊竖屏发送聊天消息,和通过横屏的发送弹幕输入框发送的弹幕一起同步到聊天室消息。

4.2 私聊提问

IPolyvChatManager{
    /**
     * 发送提问信息
     *
     * @param questionMessage
     * @return {@link com.easefun.polyv.cloudclass.chat.PolyvLocalMessage.SendValue}
     */
    int sendQuestionMessage(PolyvQuestionMessage questionMessage);
}

可根据方法的返回值来判断发送消息是否成功,是否被禁言,踢出房间等。

demo中,该方法在PolyvGroupChatFragment中的sendQuestionMessage()表示发送提问消息。

5 送花和点赞

在普通直播中,显示点赞;在三分屏直播中,显示送花。根据isNormalLive变量来控制两个View的visibility

送花和点赞两个按钮的实质都是用PolyvChatManager#sendLikes(String sessionId)向服务器发送了一个点赞的消息。只是两个功能的样式和交互不同。

送花和点赞都初始化在PolyvChatGroupFragment#initView()方法中,送花View是flower,点赞View是like,点赞的漂浮动画是PolyvLikeIconView liv_like

6 支持只看讲师聊天信息

在demo中,在PolyvChatGroupFragment中,只看讲师的开关是ImageView onlyHostSwitch。用了两个数据源,分别是:

//只看讲师信息的集合(讲师包括:管理员、讲师、助教)   在PolyvChatGroupFragment中声明
List<PolyvChatListAdapter.ChatTypeItem> teacherItems;
//所有的item,只看讲师时不是取这个数据				在PolyvChatBaseFragment中声明
List<PolyvChatListAdapter.ChatTypeItem> chatTypeItems;

onlyHostSwitch开关的点击事件监听器中,通过改变RecyclerView适配器的数据源,来达到只看讲师的效果。

还可以调用setOnlyHostCanSendMessage(boolean onlyHostCanSendMessage)来控制只看讲师后是否还能发送信息(关闭后,输入框都不能点击操作,包括:文字输入框,点赞,送花,更多(发送图片))

7 跑马灯公告

该公告指的是聊天室的管理员发出的消息,会以跑马灯的形式公告出来。

PolyvChatGroupFragment#startMarquee(CharSequence msg)方法中可以对跑马灯显示的逻辑进行自定义

8 欢迎语

PolyvChatGroupFragment#acceptEventMessage()方法中。

...
switch(event){
	//根据登录消息来获取欢迎语
    case PolyvChatManager.EVENT_LOGIN:
       //发送欢迎语
       break;
...

默认是用PolyvGreetingTextView类来实现的欢迎语。

PolyvChatGroupFragmentisShowGreeting变量用来记录后台是否打开欢迎语。

acceptLoginSuccessEvent()中对isShowGreeting写入。

9 回看历史聊天记录

聊天记录在demo是保存在服务器的,当初始化群聊界面PolyvChatGroupFragment的时候,在其initView()方法中调用了delayLoadHistory(long time)方法去加载服务器的聊天记录。

一次拉取聊天记录的条数由PolyvChatGroupFragment的变量int messageCount控制,默认是20。

10 删除聊天信息

在demo中,删除聊天记录是根据管理员、讲师或助教删除聊天记录来响应的。

PolyvChatGroupFragment#acceptEventMessage()方法中。

...
switch(event){
	//删除某条聊天记录
    case PolyvChatManager.EVENT_REMOVE_CONTENT:
       //..
       break;
    //清空聊天记录
     case PolyvChatManager.EVENT_REMOVE_HISTORY:
       //...
       break;
}
...

11 禁言

PolyvChatGroupFragment#acceptEventMessage()方法中。

...
switch(event){
	//禁言
    case PolyvChatManager.EVENT_BANIP:
       //..
       break;
    //解除禁言
     case PolyvChatManager.EVENT_UNSHIELD:
       //...
       break;
}
...

讲师对学员进行禁言,会在服务器就对消息进行拦截,而客户端可以收到自己被禁言和解禁的消息。

12 踢人

PolyvChatGroupFragment#acceptEventMessage()方法中。

...
switch(event){
	//踢人
    case PolyvChatManager.EVENT_KICK:
       //..
       break;
}
...

默认的行为是显示弹窗

PolyvBaseActivity中,用静态变量Map<String, Boolean> kickMap记录学员是否被踢,如果被踢后,需要结束应用后才能再次进来观看直播,这个逻辑可以更改。

13 公屏

PolyvChatGroupFragment

14 私聊

PolyvChatPrivateFragment

15 聊天消息可复制跳转

当消息包含链接消息时,可以触发链接跳转;长按消息可以实现复制粘贴。 对于消息包含链接的跳转在demo层用户可以自行修改: 发送消息 PolyvSendMessageHolder

sendMessage.setWebLinkClickListener(new GifSpanTextView.WebLinkClickListener() {
            @Override
            public void webLinkOnClick(String url) {
                // TODO: 2019/11/11 监听消息的链接点击回掉
                PolyvWebUtils.openWebLink(url,context);
            }
        });

        sendMessage.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                processItemLongClick(sendMessage,false,sendMessage.getText().toString());
                return true;
            }
        });

接收消息 PolyvReceiveMessageHolder

receiveMessage.setWebLinkClickListener(new GifSpanTextView.WebLinkClickListener() {
            @Override
            public void webLinkOnClick(String url) {
                // TODO: 2019/11/11 监听消息的链接点击事件
                PolyvWebUtils.openWebLink(url,context);
            }
        });

        receiveMessage.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                processItemLongClick(receiveMessage,true,receiveMessage.getText().toString());
                return true;
            }
        });

16 聊天回放

云课堂SDK支持回放视频中展示聊天数据。

通过调用方法:

PolyvChatApiRequestHelper.getInstance()
    .getChatPlaybackMessage(String vid, int limit, int second, int id, String origin, boolean isId)

可以获取回放视频实时的聊天数据。

具体的调用逻辑在PolyvChatPlaybackFragment中。

17 挤人

挤人事件用于实现登录唯一性:(同样viewerId的观众,后登录的会挤掉前一个登录的)。

//挤人
case PolyvChatManager.EVENT_RELOGIN:
	//...
    break;

18 看我

UI位于:

PolyvLookAtMeViewPolyvLinkMicBottomView

需要调用

PolyvChatManager#sendLookAtMeMessage();

来发送看我事件。

19 奖杯

监听奖杯事件:

PolyvChatManager.getInstance().addNewMessageListener(new PolyvNewMessageListener() {
    @Override
    public void onNewMessage(String message, String event) {
        if (PolyvChatManager.EVENT_SEND_CUP.equals(event)) {
        }
    }
    @Override
    public void onDestroy() {
    }
});
Clone this wiki locally