web vue+IM即时通讯
web vue+IM即时通讯
·
1.web即时通讯
https://cloud.tencent.com/document/product/269/75319(文档)
https://web.sdk.qcloud.com/im/doc/zh-cn/TIM.html(API)
2.main中引入
// 从v2.11.2起,SDK 支持了 WebSocket,推荐接入;v2.10.2及以下版本,使用 HTTP
// v2.24.0起,SDK 支持使用本地审核插件
import TIM from 'tim-js-sdk';
import TIMUploadPlugin from 'tim-upload-plugin';
import TIMProfanityFilterPlugin from 'tim-profanity-filter-plugin';
let options = {
SDKAppID: 1400793822 // 接入时需要将0替换为您的即时通信 IM 应用的 SDKAppID
};
// 创建 SDK 实例,`TIM.create()`方法对于同一个 `SDKAppID` 只会返回同一份实例
let tim = TIM.create(options); // SDK 实例通常用 tim 表示
// 设置 SDK 日志输出级别,详细分级请参见 setLogLevel https://web.sdk.qcloud.com/im/doc/zh-cn/SDK.html#setLogLevel 接口的说明</a>
tim.setLogLevel(0); // 普通级别,日志量较多,接入时建议使用
// tim.setLogLevel(1); // release 级别,SDK 输出关键信息,生产环境时建议使用
// 注册腾讯云即时通信 IM 上传插件
tim.registerPlugin({'tim-upload-plugin': TIMUploadPlugin});
// 注册腾讯云即时通信 IM 本地审核插件
tim.registerPlugin({'tim-profanity-filter-plugin': TIMProfanityFilterPlugin});
Vue.prototype.TIM = TIM
Vue.prototype.tim = tim
3.引入下载好debug
4.在需要的页面
import { genTestUserSig } from '@/debug/GenerateTestUserSig'
首先要登录
login(){
let userSig=genTestUserSig(this.userName).userSig
let promise = this.tim.login({userID: this.userName, userSig: userSig});
promise.then(function(imResponse) {
console.log(imResponse.data); // 登录成功
if (imResponse.data.repeatLogin === true) {
// 标识帐号已登录,本次登录操作为重复登录。v2.5.1 起支持
console.log(imResponse.data.errorInfo);
}
}).catch(function(imError) {
console.warn('login error:', imError);
});
},
登录成功后需要加入群组
joinGrop(){
let promise = this.tim.joinGroup({ groupID: '10012345' });
promise.then(function(imResponse) {
console.log(imResponse.data.status)
switch (imResponse.data.status) {
case this.TIM.TYPES.JOIN_STATUS_WAIT_APPROVAL: // 等待管理员同意
break;
case this.TIM.TYPES.JOIN_STATUS_SUCCESS: // 加群成功
console.log(imResponse.data.group); // 加入的群组资料
break;
case this.TIM.TYPES.JOIN_STATUS_ALREADY_IN_GROUP: // 已经在群中
break;
default:
break;
}
}).catch(function(imError){
console.warn('joinGroup error:', imError); // 申请加群失败的相关信息
});
},
发送文字
sendMessage(){
let message = this.tim.createTextMessage({
to: '10012345',
conversationType: this.TIM.TYPES.CONV_GROUP,
payload: {
text: this.message
},
needReadReceipt: true
});
let promise = this.tim.sendMessage(message);
let _this=this
promise.then(function(imResponse) {
_this.message=''
_this.msglist=[..._this.msglist,...[imResponse.data.message]]
}).catch(function(imError) {});
},
然后就是监听
mounted() {
let onMessageReceived = function(event) {
this.msglist=[...this.msglist,...event.data]
};
this.tim.on(this.TIM.EVENT.MESSAGE_RECEIVED, onMessageReceived,this);
},
<template>
<div class="detail">
<div class="box_title">
<div class="box_title_left">
{{ name }}
</div>
<div class="box_title_right">
<div class="title">
<span class="el-icon-location-outline" style="color:#E23430"></span> 当前位置:
<router-link :to="path"><span style="color:#333333" @click="handleClick()">首页</span> </router-link> / {{ name }}
</div>
<img src="@/assets/static/news/back.png" @click="handleBack()" />
</div>
</div>
<div class="content_box">
<div class="studyInfo_box">
<div class="title">{{DetailInfo.title}}</div>
</div>
<div class="video_box">
<div class="left">
<video id="videoElement" class="study_video" src="http://zb.dangjian.link/live/3935.flv" controls autoplay></video>
</div>
<div class="right">
<div class="user_box">
<div class="tab_item" v-for="(item, index) in tabList" :key="index"
:class="TabCur == index ? 'activeItem' : '' " @click="TabClick(item, index)">
{{ item }}
</div>
</div>
<div class="mulu_box" v-if="TabCur==1">
<div class="top">
<div class="avatar">
<img src="../../assets/static/index/tu3.png">
</div>
<div class="username">主讲人: {{ DetailInfo.assistanName }}</div>
</div>
<div class="desc" v-html="DetailInfo.content"></div>
</div>
<div class="pinglun_box" v-if="TabCur==0">
<div class="danmu" ref="QAContent">
<div class="initmessage">
欢迎来到直播间!直播间内严禁出现违法违规、低俗色情、吸烟、熏酒、人身伤害等内容。请大家注意财产安全
,谨防网络诈骗!
</div>
<div class="pinglun_item" v-for="(item,index) in msglist" :key="index">
<i class="el-icon-s-custom" style="color: #a5a5a5;"></i>
<span class="name">{{item.from}}:</span>
<span class="count">{{item.payload.text}}</span>
</div>
</div>
<div style="margin-top: 15px;">
<el-input placeholder="请输入内容" v-model="message" class="input-with-select" @keyup.enter.native="keyDown">
<el-button slot="append" type="danger" style="background-color: #e40b0b;color: #fff;" @click="sendMessage">发 送</el-button>
</el-input>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import { mapGetters } from "vuex"
import { genTestUserSig } from '@/debug/GenerateTestUserSig'
import flvjs from "flv.js"
export default {
data() {
return {
name: "直播",
TabCur: 0,
tabList: ["直播间互动", "直播间简介"],
DetailInfo:{},
message:'',
flvPlayer: null,
msglist:[],
}
},
computed: {
...mapGetters(['token','userName']),
path(){
return localStorage.getItem("manageActive")
},
playId () {
return Number( this.$route.params.id)
},
},
created() {
this.login()
},
mounted() {
this.getplayInit()
this.Grop()
let onMessageReceived = function(event) {
this.msglist=[...this.msglist,...event.data]
this.scrollToBottom()
};
this.tim.on(this.TIM.EVENT.MESSAGE_RECEIVED, onMessageReceived,this);
},
methods: {
login(){
let userSig=genTestUserSig(this.userName).userSig
let promise = this.tim.login({userID: this.userName, userSig: userSig});
promise.then(function(imResponse) {
if (imResponse.data.repeatLogin === true) {
console.log(imResponse.data.errorInfo);
}
})
},
Grop(){
let promise = this.tim.joinGroup({ groupID: '10012345' });
promise.then(function(imResponse) {
switch (imResponse.data.status) {
case this.TIM.TYPES.JOIN_STATUS_WAIT_APPROVAL: // 等待管理员同意
break;
case this.TIM.TYPES.JOIN_STATUS_SUCCESS: // 加群成功
console.log(imResponse.data.group); // 加入的群组资料
break;
case this.TIM.TYPES.JOIN_STATUS_ALREADY_IN_GROUP: // 已经在群中
break;
default:
break;
}
})
},
sendMessage(){
let message = this.tim.createTextMessage({
to: '10012345',
conversationType: this.TIM.TYPES.CONV_GROUP,
payload: {
text: this.message
},
needReadReceipt: true
});
let promise = this.tim.sendMessage(message);
let _this=this
promise.then(function(imResponse) {
_this.message=''
_this.msglist=[..._this.msglist,...[imResponse.data.message]]
_this.scrollToBottom()
}).catch(function(imError) {});
},
scrollToBottom() {
this.$nextTick(() => {
let scrollElem = this.$refs.QAContent;
console.log('scrollHeight: ', scrollElem.scrollHeight);
scrollElem.scrollTo({
top: scrollElem.scrollHeight,
behavior: 'smooth'
});
});
},
TabClick ( item, index ) {
this.TabCur = index
},
keyDown(e) {
if(this.message) this.sendMessage();
},
handleClick(){
localStorage.setItem("tabActive", 0)
this.$store.commit("setabActive", 0 )
},
handleBack(){
this.$router.go(-1)
},
async getplayInit() {
let { token, playId } = this
let res = await this.$axios.post("/lencon/pc/zhiBo/zhiboDetail", { token, id:playId })
if ( res.data.code == 1 ) {
this.DetailInfo=res.data
if( this.DetailInfo.llUrl) this.play()
}
},
play(){
var videoElement = document.getElementById('videoElement');
this.flvPlayer = flvjs.createPlayer({
type: 'flv',
url: this.DetailInfo.llUrl
});
this.flvPlayer.attachMediaElement(videoElement);
this.flvPlayer.load();
this.flvPlayer.play();
},
scrollTop () {
document.documentElement.scrollTop = 0
},
},
beforeDestroy(){
this.tim.destroy();
if(this.flvPlayer){
this.flvPlayer.pause();
this.flvPlayer.unload();
this.flvPlayer.detachMediaElement();
this.flvPlayer.destroy();
this.flvPlayer = null;
}
}
}
</script>
<style lang="scss" scoped>
@import "../../assets/css/main.scss";
.detail {
width: 1200px;
min-height: 700px;
margin: 20px auto;
.box_title {
color: #E23430;
display: flex;
align-items: center;
justify-content: space-between;
padding-left: 20px;
border-left: 4px solid #E23430;
margin: 20px 0;
.box_title_left {
font-size: 24px;
font-weight: bold;
}
.box_title_right {
font-size: 16px;
color: #333333;
font-family: Microsoft YaHei;
font-weight: 400;
display: flex;
align-items: center;
img{
width: 70px;
margin-left: 10px;
cursor: pointer;
}
}
}
.content_box {
width: 1200px;
padding: 40px;
background-color: #fff;
position: relative;
left: 0;
top: 0;
.fixed_box {
position: fixed;
box-shadow: 0 0 10px 2px #eee;
top: 370px;
left: 200px;
background-color: #fff;
width: 100px;
border-radius: 5px;
// border: 1px solid #EDEDED;
overflow: hidden;
.item {
padding: 20px 10px;
text-align: center;
cursor: pointer;
.red {
color: #d30000;
}
.gray {
color: #b3b3b3 ;
}
}
.active {
background-color: #d30000;
color: #ffffff !important;
.icon {
color: #fff;
}
}
}
.studyInfo_box {
width: 100%;
.title {
width: 100%;
font-size: 24px;
line-height: 60px;
text-align: left;
}
}
.video_box {
width: 100%;
display: flex;
.left{
width: 70%;
video {
width: 100%;
height: 440px;
}
}
.right {
width: 30%;
height: 440px;
background: rgb(74, 74, 74);
.user_box {
width: 100%;
display: flex;
.tab_item {
width: 50%;
text-align: center;
line-height: 40px;
cursor: pointer;
font-size: 16px;
background:#969696;
color:#dedede;
}
.activeItem {
background:#000000;
color: #ffffff;
}
}
.pinglun_box{
padding: 10px;
.danmu{
height: 330px;
font-size: 14px;
overflow-y: scroll;
&::-webkit-scrollbar {
display: none;
}
.initmessage{
color: #e6a23c;
margin-bottom: 10px;
}
.pinglun_item{
margin: 6px 0;
.name{
color: #a5a5a5;
margin: 0 8px 0 2px;
}
.count{
color: #fff;
}
}
}
}
.mulu_box {
width: 100%;
max-height: 300px;
overflow-y: scroll;
&::-webkit-scrollbar {
display: none;
}
.top {
width: 100%;
padding: 20px;
display: flex;
align-items: center;
.avatar {
width: 60px;
height: 60px;
border-radius: 50%;
overflow: hidden;
img {
width: 60px;
height: 60px;
}
}
.username {
color: #ffffff;
width: 50%;
margin-left: 20px;
}
}
.desc {
padding: 10px;
font-size: 14px;
color: #B9B8B8;
span {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
}
}
}
.biref {
width: 100%;
.b_title {
width: 100%;
color: #d30000;
font-size: 24px;
line-height: 60px;
border-bottom: 1px solid #D91717;
font-weight: bold;
}
.user {
width: 100%;
display: flex;
align-items: center;
padding: 20px;
.left {
width: 60px;
height: 60px;
border-radius: 50%;
overflow: hidden;
img {
width: 60px;
height: 60px;
}
}
.right {
margin-left: 20px;
font-size: 16px;
.username {
line-height: 30px;
}
}
}
}
.bottom_box {
width: 100%;
margin-top: 50px;
.tuijian_title {
font-size: 24px;
font-weight: bold;
color: #d30000;
padding-bottom: 10px;
border-bottom: 1px solid #d30000;
}
.list_content {
margin-top: 40px;
width: 100%;
display: flex;
align-items: center;
.list_item {
width: 270px;
margin-right: 10px;
cursor: pointer;
img {
width: 270px;
height: 160px;
}
.item_title {
font-size: 16px;
padding: 10px;
}
.item_bar {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px;
font-size: 14px;
color: #9B9B9B;
}
}
}
}
}
}
</style>
文件路径在下载中心
更多推荐

所有评论(0)