introduce

Because one of my classmates asked me how to write and chat in Rongyun, I learned about such a thing as Rongyun and tried to learn it. The main introduction of vUE in the use of VUE-CLI access rong cloud instant communication related information, this article through the example code to introduce very detailed, with a certain reference value, need friends can refer to… Personal blog

This article Demo source star oh take down can run directly

Project STAR of Flutter Oh, this is a project I plan to update for a long time

To prepare

Register rongyun to get APPKEY and TOKEN

Before writing the code, we first need to register rongyun, and then get the token provided by AppKey and Rongyun

Keep the appkey and token after you get them

Install the Vue CLI

You can install the new package using any of the following commands:

$ npm install -g @vue/cli
# OR
$ yarn global add @vue/cli
Copy the code

Create a project

Run the following command to create a new project:

$ vue create hello-world
# OR$vue UI // UI interface to create a projectCopy the code

You will be prompted to select a PreSE because we are using VUEX in this project so we chose to manually select features to select the required features to avoid further trouble

In addition to the default options we need to select Router and Vuex

This is what the project will look like when it’s created

Start writing our code

In the meantime, I encourage you to go through the official documentation and read my article

Web SDK Development Guide

Introduce rongyun Web SDK

First we go to the root directory of the public directory under the index. HTML location to introduce rongyun SDK


      
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="Width = device - width, initial - scale = 1.0">
    <link rel="icon" href="<%= BASE_URL %>favicon.ico">
    <title>im</title>
  </head>
  <body>
    <noscript>
      <strong>We're sorry but im doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
    </noscript>
    <div id="app"></div>

    <script src="https://cdn.ronghub.com/RongIMLib-2.5.0.min.js"></script>
    <! -- built files will be auto injected -->
  </body>
</html>
Copy the code

Let’s start in the root directorysrcI’m going to create a couple of files with whatever names you want and you can create them yourself

  • Create a js fileutils.js
  • createscssDirectory Creates one in this directoryutils.scss(This file is not important just for adaptive purposes)
  • inscrDirectory creationinit.vue
  • insrcDirectory creationRongCloud.vue
  • insrcDirectory creationMessage.vue

Start coding

Utils. Js This file is the initialization operation of Rongyun

export const init = (params, addPromptInfo) = > {
  var appkey = params.appkey
  var token = params.token
  RongIMClient.init(appkey)
  RongIMClient.setConnectionStatusListener({
    onChanged: function (status) {
      switch (status) {
        case RongIMLib.ConnectionStatus['CONNECTED'] :case 0:
          addPromptInfo('Connection successful')
          break

        case RongIMLib.ConnectionStatus['CONNECTING'] :case 1:
          addPromptInfo('Connecting')
          break

        case RongIMLib.ConnectionStatus['DISCONNECTED'] :case 2:
          addPromptInfo('Current user disconnects actively')
          break

        case RongIMLib.ConnectionStatus['NETWORK_UNAVAILABLE'] :case 3:
          addPromptInfo('Network unavailable')
          break

        case RongIMLib.ConnectionStatus['CONNECTION_CLOSED'] :case 4:
          addPromptInfo('Connection closed for unknown reason')
          break

        case RongIMLib.ConnectionStatus['KICKED_OFFLINE_BY_OTHER_CLIENT'] :case 6:
          addPromptInfo('User account logged in from another device, this opportunity will be kicked off')
          break

        case RongIMLib.ConnectionStatus['DOMAIN_INCORRECT'] :case 12:
          addPromptInfo('Currently running domain name error, please check secure domain name configuration')
          break}}})// Message listener
  RongIMClient.setOnReceiveMessageListener({
    // The received message
    onReceived: function (message) {
      // Determine the message type
      switch (message.messageType) {
        case RongIMClient.MessageType.TextMessage:
          // message.content.content => Text content
          addPromptInfo('New news' + message.targetId + ':' + JSON.stringify(message))
          break
        case RongIMClient.MessageType.VoiceMessage:
          // message.content.content => Audio base64 in AMR format
          break
        case RongIMClient.MessageType.ImageMessage:
          // message.content.content => Image thumbnail base64
          // message.content.imageuri => original image URL
          break
        case RongIMClient.MessageType.LocationMessage:
          // message.content.latiude => latitude
          / / the message. The content. Longitude = > longitude
          // message.content.content => Location image base64
          break
        case RongIMClient.MessageType.RichContentMessage:
          // message.content.content => Text message content
          // message.content.imageuri => Image base64
          // message.content.url => original url
          break
        case RongIMClient.MessageType.InformationNotificationMessage:
          // do something
          break
        case RongIMClient.MessageType.ContactNotificationMessage:
          // do something
          break
        case RongIMClient.MessageType.ProfileNotificationMessage:
          // do something
          break
        case RongIMClient.MessageType.CommandNotificationMessage:
          // do something
          break
        case RongIMClient.MessageType.CommandMessage:
          // do something
          break
        case RongIMClient.MessageType.UnknownMessage:
          // do something
          break
        default:
        // do something
      }
    }
  })

  RongIMClient.connect(token, {
    onSuccess: function (userId) {
      addPromptInfo('Connection successful, user ID:' + userId, userId)
    },
    onTokenIncorrect: function () {
      addPromptInfo('token is invalid')},onError: function (errorCode) {
      switch (errorCode) {
        case RongIMLib.ErrorCode.TIMEOUT:
          addPromptInfo('timeout')
          // restart the link when the link times out
          var callback = {
            onSuccess: function (userId) {
              console.log("Reconnect successfully." + userId);
            },
            onTokenIncorrect: function () {
              console.log('token is invalid');
            },
            onError: function (errorCode) {
              console.log(errorcode); }};var config = {
            // The default value is false, true Specifies whether to enable automatic reconnection
            auto: true.// Retry frequency [100, 1000, 3000, 6000, 10000, 18000] the unit is optional
            url: 'cdn.ronghub.com/RongIMLib-2.5.0.min.js'.rate: [100.1000.3000.6000.10000]}; RongIMClient.reconnect(callback, config);// Re-link end when the link times out
          break;
        case RongIMLib.ErrorCode.UNKNOWN_ERROR:
          addPromptInfo('Unknown error')
          break;
        case RongIMLib.ErrorCode.UNACCEPTABLE_PaROTOCOL_VERSION:
          addPromptInfo('Unacceptable Version of agreement')
          break;
        case RongIMLib.ErrorCode.IDENTIFIER_REJECTED:
          console.log('ddd')
          addPromptInfo('Appkey is not correct')
          break;
        case RongIMLib.ErrorCode.SERVER_UNAVAILABLE:
          addPromptInfo('Server unavailable')
          break;
      }
      addPromptInfo(errorCode)
    }
  }, null)}Copy the code

The file utils.scss is very simple

@function vw ($px) {@return $px / 750px * 100vw;
}
Copy the code

Init. vue initializes the connection using information entered by the user

<template>
  <div class="init">
    <van-nav-bar title="Connecting the Clouds" />
    <van-cell-group>
      <van-field v-model="appkey"
                 required
                 label="appkey"
                 placeholder="Please enter your Appkey" />
      <van-field v-model="token"
                 label="token"
                 placeholder="Please enter your token"
                 required />
      <van-field v-model="targetId"
                 label="targetId"
                 placeholder="Please enter targetId"
                 required />
    </van-cell-group>
    <van-button class="init-button"
                type="info"
                @click="initRongCloud">Initializing a connection</van-button>
    <div class="rong-show-box">
      <p v-for="data in showDatas"
         v-bind:key="data">
        {{data}}
      </p>
    </div>
  </div>
</template>

<script>
import { init } from '@/utils.js'

export default {
  data () {
    return {
      appkey: ' '.// This is the appKey we saved before
      token: ' '.// Tokens can be generated more than once
      targetId: ' '.// To whom you want to send the message target ID
      showDatas: [], // Initialize information}},methods: {
    addPromptInfo (prompt, userId = null) {
      const _this = this

      const avatarList = [
        'https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=4100987808, & FM = 26 & gp = 0. 2324741924 JPG'.'https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=2988245209, & FM = 26 & gp = 0. 2476612762 JPG'.'https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=4259300811, & FM = 26 & gp = 0. 497831842 JPG'.'https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=3684587473, & FM = 26 & gp = 0. 1286660191 JPG'.'https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=2884107401, & FM = 26 & gp = 0. 3797902000 JPG'
      ]
      
      // The real environment is the user information obtained through the token returned by the login background interface
      const avatar = avatarList[Math.floor(Math.random() * (3 + 1))] 
      _this.showDatas.push(prompt)
      const timer = setInterval((a)= > {
        if (userId) {
          clearInterval(timer) // Destroy the timer after a route jump
          _this.$store.commit('SET_MEMBER', {   // Save the user information
            userId: userId,
            avatar: avatar
          })
          _this.$store.commit('SET_TARGETID', _this.targetId)  // Save the target ID
          _this.$router.push({ name: 'RongCloud'})}},500)
    },
    initRongCloud () {
      var appkey = this.appkey
      var token = this.token
      if(! appkey || ! token) { alert('AppKey and Token cannot be empty')}else {
        // This init is the 'utils.js' from our previous init
        init({
          appkey: appkey,
          token: token
        }, this.addPromptInfo)
      }
    }
  }
}
</script>

<style lang="scss" scoped>
@import "~@/scss/utils";
.init-button {
  position: fixed ! important;
  bottom: vw(30px);
  left: 50%;
  transform: translateX(50%); }.rong-show-box {
  margin-top: vw(100px);
  text-align: center;
}
</style>
Copy the code

Rongcloud.vue sends a message

<template>
  <div id='rongcloud'>
    <van-nav-bar title="Cloud Chat"
                 fixed
                 left-text="Return"
                 left-arrow
                 @click-left="onClickLeft" />
    <div class="wrapper">
      <Message v-for="(item, index) in answer"
               :key="index"
               :data='item' />
    </div>
    <div class="send-message">
      <van-field v-model="say"
                 class="message-textarea"
                 type="textarea"
                 placeholder="Please enter..." />
      <van-button class="send-button"
                  type="info"
                  size="small"
                  @click="sendMessage">send</van-button>
    </div>
  </div>
</template>

<script>
import { mapState } from 'vuex'
import Message from './Message'
export default {
  components: {
    Message 
  },
  data () {
    return {
      say: ' '  / / message
    }
  },
  created () {
    this.$nextTick((a)= > {
      const list = document.getElementById('rongcloud')
      document.documentElement.scrollTop = list.scrollHeight
      // If not, try -> list.scrollTop = list.scrollHeight})},watch: {
    answer () {
      this.$nextTick((a)= > {
        const list = document.getElementById('rongcloud')
        document.documentElement.scrollTop = list.scrollHeight
        // If not, try -> list.scrollTop = list.scrollHeight})}},computed: {
    ...mapState({
      answer: 'answer'.// Message list
      memberInfo: 'memberInfo'.// User information
      targetId: 'targetId'      / / target ID})},methods: {
    onClickLeft () {
      this.$router.go(- 1)
    },
    sendMessage () {
      const _this = this

      var msg = new RongIMLib.TextMessage({ content: _this.say, extra: _this.memberInfo.avatar });
      var conversationType = RongIMLib.ConversationType.PRIVATE // Select the corresponding message type for other sessions
      var targetId = this.targetId / / target Id
      RongIMClient.getInstance().sendMessage(conversationType, targetId, msg, {
        onSuccess: function (message) {
          // message is the sent message object and contains the unique Id of the message returned by the server and the timestamp of the sent message
          const say = {
            css: 'right'.txt: message.content.content,
            headImg: _this.memberInfo.avatar
          }
          _this.answer.push(say)
          _this.say = ' '
        },
        onError: function (errorCode, message) {
          var info = ' '
          switch (errorCode) {
            case RongIMLib.ErrorCode.TIMEOUT:
              info = 'timeout'
              break
            case RongIMLib.ErrorCode.UNKNOWN:
              info = 'Unknown error'
              break
            case RongIMLib.ErrorCode.REJECTED_BY_BLACKLIST:
              info = 'In blacklist, unable to send message'
              break
            case RongIMLib.ErrorCode.NOT_IN_DISCUSSION:
              info = 'Not in a discussion group'
              break
            case RongIMLib.ErrorCode.NOT_IN_GROUP:
              info = 'Not in group'
              break
            case RongIMLib.ErrorCode.NOT_IN_CHATROOM:
              info = 'Not in the chat room'
              break
          }
          console.log('Send failed:' + info + errorCode)
        }
      })
    }
  }
}
</script>

<style lang="scss" scoped>@import "~@/scss/utils"; .wrapper { padding-top: vw(92px); padding-bottom: vw(200px); } .send-message { width: 100vw; height: vw(200px); position: fixed ! important; bottom: 0; left: 0; .message-textarea { height: 100%; } .send-button { position: fixed; right: vw(30px); bottom: vw(30px); }}</style>
Copy the code

Message.vue displays the Message logic, which is relatively simple

<template>
  <div>
    <div v-if="data.css === 'left'">
      <div class="message left">
        <van-image round
                   fit="cover"
                   width="2rem"
                   height="2rem"
                   :src="data.headImg" />
        <span>{{data.txt}}</span>
      </div>
    </div>
    <div v-if="data.css === 'right'">
      <div class="message right">
        <span>{{data.txt}}</span>
        <van-image round
                   fit="cover"
                   width="2rem"
                   height="2rem"
                   :src="data.headImg" />
      </div>
    </div>
  </div>
</template>

<script>
export default {
  props: ['data']}</script>

<style lang="scss" scoped>@import "~@/scss/utils"; .message { display: flex; align-items: center; padding: vw(10px); } .left { justify-content: flex-start; span { margin-left: vw(20px); } } .right { justify-content: flex-end; span { margin-right: vw(20px); }}</style>
Copy the code

Store.js Some state management data for this demo

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

const state = {
  memberInfo: undefined.// User information
  targetId: undefined./ / target ID
  answer: []              // Message list
}
const mutations = {
  SET_MEMBER (state, memberInfo) {
    state.memberInfo = memberInfo
  },
  SET_TARGETID (state, targetId) {
    state.targetId = targetId
  },
  SET_ANSWER (state, playload) {
    let say = {
      css: 'left'./ / CSS styles
      txt: playload.content,  // Text content
      headImg: playload.extra / / avatar
    }
    state.answer.push(say)
  },
};

export default new Vuex.Store({
  state,
  mutations,
  actions
})
Copy the code

The last step we need to do isutils.jsThe file store is introduced to save messages sent toanswer

import store from './store'

exportconst init = (params, addPromptInfo) => { ... / / message listener RongIMClient. SetOnReceiveMessageListener ({/ / messages received onReceived:functionSwitch (message.messageType) {caseRongIMClient. MessageType. TextMessage:. / / the message content. The content = > text MIT (store.com'SET_ANSWER', message.content) ... }}})... }Copy the code

At the end

Personal blog this demo is to give you a basic idea, just to achieve a one-to-one chat function. For more functions, please understand, thank you

This article Demo source Flutter project