美文网首页
vue集成leancloud实时通信开发指南JavaScript

vue集成leancloud实时通信开发指南JavaScript

作者: Ann_l | 来源:发表于2018-04-25 14:11 被阅读0次

    leancloud实时通信开发指南JavaScript 简易通信demo-github地址:
    https://github.com/walk-liuyan/simple-leancloud-realtime-demo

    leancloud demo没有用vue的例子。只有原生和angular。但公司项目使用vue,那就自己根据文档撸一个简易的通信(拉取聊天记录,发、收信息),模式属于N个用户找公司客服唠嗑。此文章仅作为了解leancloud im允许流程作为出发点的例子。具体扩展,请自行拓展,也可留言 互相学习。
    

    我对leancloud Im了解的奔跑流程:
    1、引入leancloud real sdk
    2、配置key appid
    3、拉取所有会话
    4、根据会话,拉取初始聊天记录
    5、建立接收信息
    6、发送信息

    <template>
      <div>
     <div class="messageBox p-l-20 p-r-20">
          <div v-for="(item,index) in messages" :key="index" class="itemMessageBox">
            <div class="sendTime tc fz34">{{item.updatedAt|dateFormat('YYYY-MM-DD  hh:mm:ss')}}</div>
            <div class="sendMsgBox"
            :class="{'mineMsg':item.from === curUserChatId }">
              <div class="itemMsg fz36">{{item._lctext}}</div>
            </div>
          </div>
           <div id="messageViewBottom" ref="messageViewBottom"></div>
        </div>
        <div class="sendMsgBtnBox bg-white w-100 p-l-10 p-r-10">
          <div class="leftInput">
           <textarea class="w-100"
                     v-model="draft"
                     placeholder="说点什么……"
                     @keyup.enter="sendMsg(draft)"
           ></textarea>
          </div>
          <div class="sendBtn text-middle fz36" @click="sendMsg(draft)">
            <img src="/static/chat/chatSend.png" style="width: 50%;">
          </div>
        </div>
          </div>
    </template>
    <script type="text/babel">
    /* 引入要使用的东西 */
    import { Realtime, TextMessage } from "leancloud-realtime";
    import { ImageMessage } from "leancloud-realtime-plugin-typed-messages";
    import AV, { Object } from "leancloud-storage";
    import { TypingStatusMessage } from "./js/typing-indicator";
    import StickerMessage from "./js/sticker-message";
    import userService from "./js/user.service";
    import FilterMixins from "@/assets/js/filters-mixins";
    import FnMixins from "@/assets/js/fn-mixins";
    import _ from "lodash";
    import { setTimeout } from "timers";
    export default {
      components: {},
      data() {
        return {
          curUserChatId: "", // 当前用户的chatId
          curChatWidthUserId: this.$route.query.id, // 和谁聊天的chatId
          draft: "",
          messages: [],
          LeanRTImClient: null,
          pageYOffset: 0,
          messageIterator: null
        };
      },
      computed: {},
      methods: {
          // 发送信息
           sendMsg(draft) {
          const that = this;
          console.log("send this.curConversation", this.curConversation);
          this.curConversation
            .send(new TextMessage(draft))
            .then(function(message, conversation) {
              console.log("用户  & 环球理事 ", "发送成功!", message, conversation);
              that.messages.push(message);
              that.draft = "";
              that.scrollToBottom();
            })
            .catch(console.error);
            /*
             realtime
              .createIMClient("环球理事")
              .then(function(tom) {
                console.log("tom imclinet", tom);
                return tom.createConversation({
                  members: [`${that.curUserChatId}`],
                  name: `环球理事 => ${that.curUserChatId}`
                });
              })
              .then(function(conversation) {
                console.log("conversation", conversation);
                return conversation.send(new TextMessage(draft));
              })
              .then(function(message, conversation) {
                console.log("环球理事 & 用户", "发送成功!", message);
                that.msgToConversation(message);
                that.draft = "";
                that.scrollToBottom();
              })
              .catch(console.error);
            */
        },
          // 接收信息
        acceptMsg() {
          console.log("acceptMsg");
          const that = this;
          this.LeanRTImClient.then(function(jerry) {
            console.log("用户", jerry);
            jerry.on("message", function(message, conversation) {
              that.messageIterator = conversation.createMessagesIterator({
                limit: 10
              });
              that.messageIterator
                .next()
                .then(function(result) {
                  console.log("cur-result", result);
                  that.messages = result.value;
                })
                .catch(console.error.bind(console));
              // 第一次调用 next 方法,获得前 10 条消息,还有更多消息,done 为 false
              that.loadMoreChatMsg();
    
              console.log("Message received: " + message, conversation);
              console.log("received", message.text);
              that.scrollToBottom();
            });
          }).catch(console.error);
        },
          // init当前对话的历史记录
        initChatMsg() {
          const that = this;
          that.messageIterator
            .next()
            .then(function(result) {
              that.messages = result.value.concat(that.messages);
              console.log("init data", result.value);
              setTimeout(() => {
                that.scrollToBottom();
              }, 100);
            })
            .catch(console.error.bind(console));
        },
          // 加载更多的聊天记录
        loadMoreChatMsg() {
          const that = this;
          that.messageIterator
            .next()
            .then(function(result) {
              that.messages = result.value.concat(that.messages);
              console.log("laqu data", result.value);
            })
            .catch(console.error.bind(console));
        },
        getNormalConvs(imClient) {
          return imClient
            .getQuery()
            .withLastMessagesRefreshed()
            .containsMembers([imClient.id])
            .find();
        },
    //  拉取对话
        getConversations(imClient) {
          const that = this;
          return Promise.all([this.getNormalConvs(imClient)]).then(datas => {
            console.log("_createdAt", _.orderBy(datas[0], ["_createdAt"], ["asc"]));
            console.log(datas[0]);
            if (datas[0].length === 0) {
              that.curConversation = this.LeanRTImClient.then(function(imClient) {
                console.log("创建会话", imClient);
                return imClient.createConversation({
                  members: ["环球理事"],
                  name: `${that.curUserChatId} => 环球理事 `
                });
              });
            } else {
              that.curConversation = datas[0][0];
              console.log("promise that.curConversation", that.curConversation);
            }
            that.messageIterator = that.curConversation.createMessagesIterator({
              limit: 10
            });
            that.initChatMsg(); // 拉去初始历史数据
          });
        },
    // 滚动到底部
        scrollToBottom() {
          const elBottom = document.getElementById("messageViewBottom");
          const pageYOffset = elBottom.offsetTop;
          setTimeout(() => {
            window.scroll(0, pageYOffset);
          }, 0);
        }
      },
      mounted() {
    // 监听页面的滚动,如果上拉到头部,就加载历史记录
        window.onscroll = () => {
          this.pageYOffset = window.pageYOffset;
          if (this.pageYOffset < 30) {
            /* 加载更多数据 */
            this.loadMoreChatMsg(); // 上拉加载历史数据
          }
        };
      },
      created() {
        this.setHtmlTitle(this.curChatWidthUserId);
    // 这是我自己写的方法,用于设置html title
        const curBrowser = this._curBrowser();// 这是我自己写的方法,用于判断当前环境
        const curUserInfo = JSON.parse(window.localStorage.getItem("curUserInfo"));
        if (curUserInfo) {
    // 获取当前用户的ChatID
          this.curUserChatId = curUserInfo.binding_chat_id;
        } else {
    // 这是我自己写的方法,如果没有用户信息,就去微信授权等
          if (curBrowser === "wechat") {
            this._setUserStatus;
          }
        }
        this.LeanRTImClient = realtime.createIMClient(this.curUserChatId);
        this.LeanRTImClient.then(function(imClient) {
            // 拉取历史会话
          that.getConversations(imClient);
        });
        this.acceptMsg();
        console.log("from", this.curUserChatId, "to", this.curChatWidthUserId);
      },
      mixins: [FilterMixins, FnMixins]
    };
    </script>
    <style lang='scss' scoped>
    h1,
    h2 {
      font-weight: normal;
    }
    
    ul {
      list-style-type: none;
      padding: 0;
    }
    
    li {
      display: inline-block;
      margin: 0 10px;
    }
    
    a {
      color: #42b983;
    }
    
    $arrow-size: 8px;
    $background: #f6f6f6;
    
    .messageBox {
      margin-bottom: 1.5rem;
      .itemMessageBox {
        margin: 0.7rem 0;
        .sendTime {
        }
        .sendMsgBox {
          display: flex;
          justify-content: flex-start;
          .itemMsg {
            position: relative;
            max-width: 5rem;
            min-height: 37px;
            padding: 0.1rem;
            margin: 0.06rem 0 0;
            background: #f6f6f6;
            word-wrap: break-word;
            &:after {
              content: "";
              display: block;
              position: absolute;
              top: -$arrow-size;
              left: 0;
              border: $arrow-size solid transparent;
              border-width: 0 $arrow-size $arrow-size 0;
              border-bottom-color: $background;
            }
          }
        }
        .mineMsg {
          display: flex;
          justify-content: flex-end;
          .itemMsg {
            background: #2c97e8;
            color: white;
            &:after {
              border-bottom-color: #f6f6f6;
              top: auto;
              left: auto;
              bottom: -8px;
              right: 0;
              border: 8px solid transparent;
              border-width: 8px 0 0 8px;
              border-top-color: #2c97e8;
            }
          }
        }
      }
    }
    
    .sendMsgBtnBox {
      position: fixed;
      bottom: 0px;
      height: 1.2rem;
      display: flex;
      .leftInput {
        flex: 1;
        textarea {
          font-size: 0.32rem;
          max-height: 1.6rem;
          min-height: 0.56rem;
          -ms-flex-preferred-size: auto;
          resize: none;
          overflow-y: scroll;
          color: rgba(0, 0, 0, 0.87);
          border-color: rgba(0, 0, 0, 0.12);
          -ms-flex-order: 2;
          order: 2;
          display: block;
          margin-top: 0;
          background: none;
          padding: 0.04rem;
          border-width: 0 0 0.01rem 0;
          line-height: 0.52rem;
          -ms-flex-preferred-size: 0.52rem;
          border-radius: 0;
          border-style: solid;
          width: 100%;
          box-sizing: border-box;
          float: left;
        }
      }
      .sendBtn {
        width: 1.5rem;
      }
    }
    </style>
    
    
    

    实现效果

    image.png

    之前公司是用网易云信IM,我就写了一个自定义形式的IM(vue+ webpack+iview + im)
    文章地址如下:
    https://www.jianshu.com/p/3914f1a8e1ef
    https://www.jianshu.com/p/d56de7ea9736
    网易云信demo地址如下:https://github.com/walk-liuyan/vue-im

    相关文章

      网友评论

          本文标题:vue集成leancloud实时通信开发指南JavaScript

          本文链接:https://www.haomeiwen.com/subject/xtwelftx.html