Skip to content

WebSocket 的概念与使用场景

WebSocket 是一种在单个 TCP 连接上进行全双工通信的协议。

WebSocket 的优点是

  1. 具有较低的延迟,从而可以实现更快的通信

  2. 可以在客户端和服务端之间保持长时间的连接,从而减少 HTTP 请求的数量

使用演示

vue
<template>
  <button v-if="!socketLink" @click="openConnectWS">点我建立连接</button>
  <button v-else @click="closeConnectWS">点我断开连接</button>

  <div v-if="socketLink">
    <ul class="list">
      <li :class="['message', item.type]" v-for="item in messages">
        <div :class="['item', item.type]">{{ item.content }}</div>
      </li>
    </ul>
    <div class="input-area">
      <input
        v-model="inputVal"
        placeholder="输入任意内容"
        @keyup.enter="sendWSMessage"
      />
      <button @click="sendWSMessage">点我发送消息</button>
    </div>
  </div>
</template>

<script setup>
import { ref } from 'vue'
const messages = ref([])
const inputVal = ref('')
let socket = null
let socketLink = ref(false)
const openConnectWS = () => {
  socket = new WebSocket('ws://localhost:3000')

  socket.addEventListener('open', event => {
    console.log('WebSocket connection opened:', event)
    socketLink.value = true

    // 发送消息到服务器
    // socket.send('Hello, server!');
  })

  socket.addEventListener('message', event => {
    console.log('Received message:', event.data)
    messages.value.push({
      type: 'receive',
      content: event.data
    })
  })

  socket.addEventListener('close', event => {
    console.log('WebSocket connection closed:', event)
    socket = null
    socketLink.value = false
  })
}
const sendWSMessage = () => {
  if (!socket || !inputVal.value) return

  messages.value.push({
    type: 'send',
    content: inputVal.value
  })
  socket.send(inputVal.value)
  inputVal.value = ''
}
const closeConnectWS = () => {
  socket.close()
}
</script>

<style lang="less" scoped>
.list {
  list-style: none;
}
.message {
  list-style: none;
  display: flex;
  &.send {
    justify-content: flex-end;
  }

  .item {
    background-color: #fff;
    color: #333;
    padding: 12px 24px;
    border-radius: 999px;
  }
}
.input-area {
  display: flex;
  input {
    flex: 1;
    height: 32px;
    line-height: 32px;
  }
}
</style>
<template>
  <button v-if="!socketLink" @click="openConnectWS">点我建立连接</button>
  <button v-else @click="closeConnectWS">点我断开连接</button>

  <div v-if="socketLink">
    <ul class="list">
      <li :class="['message', item.type]" v-for="item in messages">
        <div :class="['item', item.type]">{{ item.content }}</div>
      </li>
    </ul>
    <div class="input-area">
      <input
        v-model="inputVal"
        placeholder="输入任意内容"
        @keyup.enter="sendWSMessage"
      />
      <button @click="sendWSMessage">点我发送消息</button>
    </div>
  </div>
</template>

<script setup>
import { ref } from 'vue'
const messages = ref([])
const inputVal = ref('')
let socket = null
let socketLink = ref(false)
const openConnectWS = () => {
  socket = new WebSocket('ws://localhost:3000')

  socket.addEventListener('open', event => {
    console.log('WebSocket connection opened:', event)
    socketLink.value = true

    // 发送消息到服务器
    // socket.send('Hello, server!');
  })

  socket.addEventListener('message', event => {
    console.log('Received message:', event.data)
    messages.value.push({
      type: 'receive',
      content: event.data
    })
  })

  socket.addEventListener('close', event => {
    console.log('WebSocket connection closed:', event)
    socket = null
    socketLink.value = false
  })
}
const sendWSMessage = () => {
  if (!socket || !inputVal.value) return

  messages.value.push({
    type: 'send',
    content: inputVal.value
  })
  socket.send(inputVal.value)
  inputVal.value = ''
}
const closeConnectWS = () => {
  socket.close()
}
</script>

<style lang="less" scoped>
.list {
  list-style: none;
}
.message {
  list-style: none;
  display: flex;
  &.send {
    justify-content: flex-end;
  }

  .item {
    background-color: #fff;
    color: #333;
    padding: 12px 24px;
    border-radius: 999px;
  }
}
.input-area {
  display: flex;
  input {
    flex: 1;
    height: 32px;
    line-height: 32px;
  }
}
</style>