Resumen de la práctica del proyecto uniapp (15) Uso de websocket para implementar una sala de chat simple

Introducción: En algunos software sociales, a menudo se puede ver la interfaz de varias salas de chat. A continuación, resumiremos los principios y métodos de implementación de las salas de chat. Finalmente, crearemos una sala de chat simple, que incluye iniciar/cerrar sesión, unirse/ salir de la sala, enviar y recibir mensajes de chat y otras funciones.

Tabla de contenido

  • Preparación
  • Análisis de principios
  • Implementación de componentes
  • Ejercicios practicos
  • Construcción del lado del servidor
  • Exhibición de casos

Preparación

  • Cree un nuevo componente nombrado en pages/indexla carpeta ;chat
  • De acuerdo con la estructura de la página mencionada en el artículo anterior, escriba la página de chat programada;

Análisis de principios

parte frontal

El front-end de esta sala de chat utiliza varias implementaciones de API proporcionadas por uniapp, que incluyen:

  • uni.connectSocket:Conéctese al servidor websocket;
  • SocketTask.onOpen: Escuche la apertura de la conexión del servidor;
  • SocketTask.onClose:La conexión del servidor de monitoreo está cerrada;
  • SocketTask.onError: Supervisar errores de conexión del servidor;
  • SocketTask.onMessage:Escuche los mensajes del servidor;
  • SocketTask.send:Enviar un mensaje al servidor;
  • SocketTask.close:Cerrar la conexión del servidor;

parte trasera

Este servidor de sala de chat wsse construye utilizando la biblioteca npm y la parte de carga de avatar utiliza nodeuna implementación nativa. El método de implementación se presentará en detalle más adelante.

Implementación de componentes

Una vez completado el trabajo de preparación y el análisis de principios, a continuación escriba una página simple. A continuación se muestra principalmente el contenido principal.

Sección de plantilla

  • sección de inicio de sesión

Incluye páginas y funciones para ingresar nombre de usuario y cargar avatar.

<view class="chat-login" v-if="!wsInfo.isLogin">
  <view class="chat-login-item">
    <input
      v-model="userInfo.name"
      class="chat-login-ipt"
      type="text"
      :maxlength="10"
      placeholder="请输入用户名" />
  </view>
  <view class="chat-login-item">
    <button class="chat-login-ipt" @click="uploadAvatar">上传头像</button>
  </view>
  <view class="chat-login-item">
    <button class="chat-login-btn" type="primary" @click="wsLogin">用户登录</button>
  </view>
</view>
  • Agregar sección de habitación

Incluyendo la página y función para cerrar sesión en la habitación seleccionada.

<view class="chat-login" v-if="wsInfo.isLogin && !wsInfo.isJoin">
  <view class="chat-login-item">
    <picker mode="selector" :range="roomInfo.list" :value="roomInfo.id" @change="changeRoom">
      请选择房间号:{
  
   
   {roomInfo.name}}
    </picker>
  </view>
  <view class="chat-login-item">
    <button class="chat-login-btn" type="primary" @click="joinRoom">进入房间</button>
  </view>
  <view class="chat-login-item">
    <button type="warn" @click="wsLogout">退出登录</button>
  </view>
</view>
  • Interfaz de sala de chat

Incluyendo visualización de números de sala, salida de salas, listas de usuarios en línea, áreas de mensajes de chat y páginas y funciones para ingresar contenido de chat y enviar mensajes.

<view class="chat-room" v-if="wsInfo.isLogin && wsInfo.isJoin">
  <view class="chat-room-set">
    <text class="chat-room-name">房间{
  
   
   { roomInfo.id }}</text>
    <button class="chat-room-logout" size="mini" type="warn" @click="leaveRoom">退出房间</button>
  </view>
  <view class="chat-room-users">
    在线人数({
  
   
   {userInfo.users.length}}人):{
  
   
   { userInfo.usersText }}</view
  >
  <scroll-view
    :scroll-y="true"
    :scroll-top="roomInfo.scrollTop"
    @scroll="handlerScroll"
    class="chat-room-area">
    <view
      :class="{'chat-room-area-item': true, 'active': item.name == userInfo.name}"
      v-for="(item, index) in msg.list"
      :key="`msg${index+1}`">
      <view class="chat-room-user">
        <text
          v-if="roomInfo.mode == 'name'"
          :class="{'chat-room-username': true, 'active': item.name == userInfo.name}"
          >{
  
   
   { item.name }}</text
        >
        <text v-if="roomInfo.mode == 'name'" class="chat-room-time"> ({
  
   
   {item.createTime}}): </text>
      </view>
      <image
        v-if="roomInfo.mode == 'avatar'"
        class="chat-room-avatar"
        :src="item.name == userInfo.name ? userInfo.avatar : item.avatar"></image>
      <view class="chat-room-content"> {
  
   
   {item.content}} </view>
    </view>
    <view id="chat-room-area-pos"></view>
  </scroll-view>
  <view class="chat-room-bot">
    <input
      class="chat-room-bot-ipt"
      type="text"
      placeholder="请输入内容"
      :maxlength="100"
      v-model="msg.current" />
    <button class="chat-room-bot-btn" size="mini" type="primary" @click="sendMsg">发送</button>
  </view>
</view>

parte de estilo

  • Inicia sesión y únete a estilos de sala
.chat-login {
  .chat-login-item {
    margin-bottom: 20rpx;
    height: 80rpx;
    .chat-login-ipt,
    uni-picker {
      box-sizing: border-box;
      padding: 10rpx 30rpx;
      height: 100%;
      font-size: 26rpx;
      border: 1rpx solid $e;
      border-radius: 10rpx;
      color: var(--UI-BG-4);
    }
    uni-picker {
      display: flex;
      align-items: center;
    }
    .chat-login-btn {
      background: $mainColor;
    }
  }
}
  • Estilo de página de la sala de chat
.chat-room {
  display: flex;
  flex-direction: column;
  height: 100%;
  .chat-room-set {
    display: flex;
    justify-content: space-between;
    align-items: center;
    width: 100%;
    font-size: 31rpx;
    font-weight: bold;
    .chat-room-name {
      padding: 10rpx;
    }
    .chat-room-logout {
      margin: 0;
    }
  }
  .chat-room-users {
    margin: 20rpx 0;
    padding: 20rpx 0;
    font-size: 28rpx;
    line-height: 1.5;
    border-bottom: 2rpx solid $e;
    word-break: break-all;
  }
  .chat-room-area {
    box-sizing: border-box;
    padding: 20rpx;
    height: calc(100% - 280rpx);
    background: $f8;
    .chat-room-area-item {
      display: flex;
      flex-direction: row;
      justify-content: flex-start;
      align-items: flex-start;
      margin-bottom: 20rpx;
      padding-bottom: 20rpx;
      .chat-room-user {
        .chat-room-username {
          color: $iptBorColor;
          font-size: 31rpx;
          line-height: 2;
          &.active {
            color: $mainColor;
          }
        }
      }
      .chat-room-avatar {
        width: 68rpx;
        height: 68rpx;
        background: $white;
        border-radius: 10rpx;
      }
      .chat-room-time {
        font-size: 26rpx;
        color: $iptBorColor;
      }
      .chat-room-content {
        box-sizing: border-box;
        margin-left: 12rpx;
        padding: 15rpx;
        max-width: calc(100% - 80rpx);
        text-align: left;
        font-size: 24rpx;
        color: $white;
        border-radius: 10rpx;
        word-break: break-all;
        background: $mainColor;
      }
      &.active {
        flex-direction: row-reverse;
        .chat-room-content {
          margin-left: 0;
          margin-right: 12rpx;
          text-align: right;
          color: $uni-text-color;
          background: $white;
        }
      }
    }
  }
  .chat-room-bot {
    position: fixed;
    bottom: 0;
    left: 0;
    display: flex;
    justify-content: space-between;
    align-items: center;
    box-sizing: border-box;
    padding: 0 30rpx;
    width: 100%;
    height: 100rpx;
    background: $white;
    border-top: 3rpx solid $f8;
    .chat-room-bot-ipt {
      flex: 1;
      box-sizing: border-box;
      padding: 0 30rpx;
      height: 70rpx;
      font-size: 24rpx;
      border: 2rpx solid $iptBorColor;
      border-radius: 10rpx;
    }
    .chat-room-bot-btn {
      margin-left: 50rpx;
      width: 150rpx;
      height: 70rpx;
      line-height: 70rpx;
      font-size: 26rpx;
      color: $white;
      background: $mainColor;
    }
  }
}

parte del guión

Introducir paquetes de dependencia y configuraciones de propiedades.
  • información del socket web
// ws
let wsInfo = reactive({
   
    
    
  ws: null, // ws对象
  alive: false, // 是否连接
  isLogin: false, // 是否登录
  isJoin: false, // 是否加入
  lock: false, // 锁住重连
  reconnectTimer: null, // 重连计时
  reconnectTime: 5000, // 重连计时间隔
  clientTimer: null, // 客户端计时
  clientTime: 10000, // 客户端计时间隔
  serverTimer: null, // 服务端计时
  serverTime: 30000, // 服务端计时间隔
});
  • Información de usuario
// 用户信息
const userInfo = reactive({
   
    
    
  id: "1", // 用户id
  name: "", // 用户名称
  avatar: "", // 用户头像
  users: [], // 用户在线列表
  usersText: "", // 用户在线列表文本
});
  • información de la habitación
// 房间信息
const roomInfo = reactive({
   
    
    
  id: 1, // 房间id
  name: "房间1", // 房间名称
  list: ["房间1", "房间2", "房间3"], // 房间列表
  mode: "avatar", // 模式:avatar头像
  scrollTop: 0, // 滚动到顶部距离
  scrollHei: 0, // 滚动高度
  goBottomTimer: null, // 到底部计时
  goBottomTime: 500, // 到顶部计时间隔
});
  • Información de chat
// 聊天信息
const msg = reactive({
   
    
    
  current: "", // 输入框内容
  list: [], // 聊天消息列表
});

Ejercicios practicos

Una vez preparado el trabajo básico, el siguiente paso es implementar las funciones.

Conectar websocket

Después de ingresar a la página, primero conéctese al servidor websocket.

  • Conectar websocket
// 连接ws
function connectWs() {
   
    
    
  wsInfo.ws = null;
  wsInfo.ws = uni.connectSocket({
   
    
    
    url: proxy.$apis.urls.wsUrl,
    success() {
   
    
    
      wsInfo.alive = true;
      console.log("ws连接成功!");
    },
    fail() 

Supongo que te gusta

Origin blog.csdn.net/fed_guanqi/article/details/132865006
Recomendado
Clasificación