天天看點

什麼是webSocket?怎麼使用webSocket中的第三方socket.io包什麼是webSocket?怎麼使用webSocket中的第三方socket.io包

什麼是webSocket?怎麼使用webSocket中的第三方socket.io包什麼是webSocket?怎麼使用webSocket中的第三方socket.io包

什麼是webSocket?怎麼使用webSocket中的第三方socket.io包

http 協定

  1. http中文意思: 超文本傳輸協定, 定義伺服器和用戶端的傳送格式
  2. 請求發送的資料包, 叫請求封包, 格式如下
什麼是webSocket?怎麼使用webSocket中的第三方socket.io包什麼是webSocket?怎麼使用webSocket中的第三方socket.io包
  1. 響應回來的資料包, 叫響應封包, 格式如下
什麼是webSocket?怎麼使用webSocket中的第三方socket.io包什麼是webSocket?怎麼使用webSocket中的第三方socket.io包

HTTP 協定:用戶端與伺服器建立通信連接配接之後,伺服器端隻能被動地響應用戶端的請求,無法主動給用戶端發送消息。

一次請求才能對應一次響應

由于 http 是一次請求對應一次響應,無法達到即時通信的效果,是以在後面的 html5 中提出了一個新的協定 websocket 來實作即時通信的效果

什麼是 websocket

websocket 是一種網絡通信協定,是 HTML5 開始提供的一種在單個 TCP 連接配接上進行全雙工通 信的協定,這個對比着 HTTP 協定來說,HTTP 協定是一種無狀态的、無連接配接的、單向的應 用層協定,通信請求隻能由用戶端發起,服務端對請求做出應答處理。HTTP 協定無法實作 伺服器主動向用戶端發起消息,websocket 連接配接允許用戶端和伺服器之間進行全雙工通信, 以便任一方都可以通過建立的連接配接将資料推送到另一端。websocket 隻需要建立一次連接配接, 就可以一直保持連接配接狀态

socket.io包使用

1. 安裝socket.io包

npm install [email protected] -D
//
yarn add [email protected] -D
           

2. 在元件内引入包

// 導入 socket.io-client 包
import { io } from 'socket.io-client'

// 定義變量,存儲 websocket 執行個體
let socket = null
           

3. 建立socket服務

created() {
    // ...
    
    // 建立用戶端 websocket 的執行個體
    socket = io('http://位址', {
        query: {
            token: this.token
        },
        transports: ['websocket']
    })
}
           

4. 監聽是否連接配接成功

隻有連接配接内置事件執行了, 才能進行後續操作
created() {
  // 建立連接配接的事件
  socket.on('connect', () => {
    console.log('與伺服器建立了連接配接')
  })
}
           

5. 在元件銷毀前, 關閉服務

// 元件被銷毀之前,清空 sock 對象
beforeDestroy() {
  // 關閉連接配接
  socket.close()

  // 銷毀 websocket 執行個體對象
  socket = null
},
           

6. 在created監聽socket的消息

created() {
    // ...

    // 接收到消息的事件
    socket.on('message', data => {
      // 把伺服器發送過來的消息,存儲到 list 數組中
      this.list.push({
        name: 'xs',
        msg: data.msg
      })
    })
},
           

7. 在 send事件中, 把伺服器發來的資料裝到數組裡

sendFn () {
    // 判斷内容是否為空
    if (!this.word) return

    // 添加聊天消息到 list 清單中
    this.list.push({
        name: 'me',
        msg: this.word
    })
}
           

8. 用戶端調用

socket.emit('message', 消息内容)

方法把消息發送給 websocket 伺服器

// 向服務端發送消息
sendFn () {
    // 判斷内容是否為空
    if (!this.word) return

    // 添加聊天消息到 list 清單中
    this.list.push({
        name: 'me',
        msg: this.word
    })

    // 把消息發送給 websocket 伺服器
    socket.emit('message', {
        msg: this.word,
        timestamp: new Date().getTime()
    })

    // 清空文本框的内容
    this.word = ''
}
           

客服小思機器人

<template>
  <div class="container">
    <!-- 固定導航 -->
    <van-nav-bar fixed left-arrow @click-left="$router.back()" title="小思同學"></van-nav-bar>

    <!-- 聊天主體區域 -->
    <div class="chat-list">
      <div v-for="(item, index) in list" :key="index">
        <!-- 左側是機器人小思 -->
        <div class="chat-item left" v-if="item.name === 'xs'">
          <van-image fit="cover" round src="https://img.yzcdn.cn/vant/cat.jpeg" />
          <div class="chat-pao">{{ item.msg }}</div>
        </div>

        <!-- 右側是目前使用者 -->
        <div class="chat-item right" v-else>
          <div class="chat-pao">{{ item.msg }}</div>
          <van-image fit="cover" round :src="$store.state.photo" />
        </div>
      </div>
    </div>

    <!-- 對話區域 -->
    <div class="reply-container van-hairline--top">
      <van-field placeholder="說點什麼..." v-model="word">
        <template #button>
          <span style="font-size:12px;color:#999" @click="sendFn">送出</span>
        </template>
      </van-field>
    </div>
  </div>
</template>

<script>
import store from '@/store/index.js'
import { io } from 'socket.io-client'
export default {
  name: 'Chat',
  data() {
    return {
      word: '',
      socket: null,
      list: [
        // 隻根據 name 屬性,即可判斷出這個消息應該渲染到左側還是右側
        { name: 'xs', msg: 'hi,你好!我是小思' },
        { name: 'me', msg: '我是程式設計小王子' }
      ]
    }
  },
  methods: {
    sendFn() {
      this.socket.emit('message', {
        msg: this.word,
        timestamp: Date.now()
      })
      this.list.push({ name: 'me', msg: this.word })
      this.word = ''
      // 聊天内容置底
      this.$nextTick(() => {
        const height1 = document.querySelector('.chat-list').clientHeight
        const height = document.querySelector('.chat-list').scrollHeight
        document.querySelector('.chat-list').scrollTop = height - height1
      })
    }
  },
  created() {
    this.socket = io('http://url位址', {
      query: {
        token: store.state.token
      },
      transports: ['websocket']
    })
    // 建立連接配接的事件
    this.socket.on('connect', () => {
      console.log('與伺服器建立了連接配接')
    })
    this.socket.on('message', data => {
      // console.log(data)
      this.list.push({ name: 'xs', msg: data.msg })
      // 聊天内容置底
      this.$nextTick(() => {
        const height1 = document.querySelector('.chat-list').clientHeight
        const height = document.querySelector('.chat-list').scrollHeight
        document.querySelector('.chat-list').scrollTop = height - height1
      })
    })
  }
}
</script>

<style lang="less" scoped>
.container {
  height: 100%;
  width: 100%;
  position: absolute;
  left: 0;
  top: 0;
  box-sizing: border-box;
  background: #fafafa;
  padding: 46px 0 50px 0;
  .chat-list {
    height: 100%;
    overflow-y: scroll;
    .chat-item {
      padding: 10px;
      .van-image {
        vertical-align: top;
        width: 40px;
        height: 40px;
      }
      .chat-pao {
        vertical-align: top;
        display: inline-block;
        min-width: 40px;
        max-width: 70%;
        min-height: 40px;
        line-height: 38px;
        border: 0.5px solid #c2d9ea;
        border-radius: 4px;
        position: relative;
        padding: 0 10px;
        background-color: #e0effb;
        word-break: break-all;
        font-size: 14px;
        color: #333;
        &::before {
          content: '';
          width: 10px;
          height: 10px;
          position: absolute;
          top: 12px;
          border-top: 0.5px solid #c2d9ea;
          border-right: 0.5px solid #c2d9ea;
          background: #e0effb;
        }
      }
    }
  }
}
.chat-item.right {
  text-align: right;
  .chat-pao {
    margin-left: 0;
    margin-right: 15px;
    &::before {
      right: -6px;
      transform: rotate(45deg);
    }
  }
}
.chat-item.left {
  text-align: left;
  .chat-pao {
    margin-left: 15px;
    margin-right: 0;
    &::before {
      left: -5px;
      transform: rotate(-135deg);
    }
  }
}
.reply-container {
  position: fixed;
  left: 0;
  bottom: 0;
  height: 44px;
  width: 100%;
  background: #f5f5f5;
  z-index: 9999;
}
</style>
text-align: left;
  .chat-pao {
    margin-left: 15px;
    margin-right: 0;
    &::before {
      left: -5px;
      transform: rotate(-135deg);
    }
  }
}
.reply-container {
  position: fixed;
  left: 0;
  bottom: 0;
  height: 44px;
  width: 100%;
  background: #f5f5f5;
  z-index: 9999;
}
</style>
           

效果

什麼是webSocket?怎麼使用webSocket中的第三方socket.io包什麼是webSocket?怎麼使用webSocket中的第三方socket.io包

繼續閱讀