websocket+elementui+vue实现简易聊天室

搭建服务端环境

npm install socket.io

安装socket.io

服务端基于node,js的express框架生成,所以写成模块,引入至app.js中

const app = require('./app')
const http = require('http')
const socketIo = require('socket.io')
const httpServer = http.Server(app)
const io = socketIo(httpServer , {})
const users = {}
io.on('connection' , (socket)=>{
  socket.on('login' , (nikname)=>{
    if(users[nikname]){
      socket.emit('repeat' , '昵称重复')
      return 
    }
    socket.nikname = nikname
    users[nikname] = {
      name: nikname,
      socket : socket,
    }
    io.sockets.emit('logged' , {nikname , isLogin:true} )
  })
  socket.on("disconnecting", (reason) => {
    let nikname = socket?.nikname
    if(nikname && users[nikname]){
      delete users[nikname]
      io.sockets.emit('logout' , {nikname , isLogin: false} )
      delete socket[nikname]
    }
    console.log('断开连接')
  });
  socket.on('chat' , (data)=>{
    console.log(data , socket.nikname)
    socket.broadcast.emit('response_chat' , {
      nikname: socket.nikname,
      msg: data
    })
  })
  
})
httpServer.listen(8888)
module.exports = httpServer

其中,io.sockets.emit用于向所有建立连接的客户端发送信息,socket.broadcast.emit用于向除发送方之外的客户端发送信息。

客户端基于vue和elementui

<template>
  <div>
    <div class="talkView--content--body">
      <ul>
        <li v-for="(item, idx) in chatList" :key="idx">
          <div :class="item.style">
            <div v-if="item.style === right">
              <span>{{ item.msg }}</span>
            </div>
            <div v-else>
              <span v-show="item.nikname">{{ item.nikname }}:</span>
              <span>{{ item.msg }}</span>
            </div>
          </div>
        </li>
      </ul>
    </div>
    <div class="talkView--content--control">
      <el-input v-model="sendMsg" placeholder="请输入内容"></el-input>
      <el-button type="primary" @click="send" class="width100"
        >发送消息</el-button
      >
    </div>
    <el-dialog title="输入昵称" :visible="dialogVisible" width="30%">
      输入昵称:
      <el-input v-model="nikname"> </el-input>
      <span slot="footer" class="dialog-footer">
        <el-button type="primary" @click="login">确 定</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
import { io } from "socket.io-client";
export default {
  beforeDestroy() {
    // 断开连接
    this.socket.disconnect();
  },
  data() {
    return {
      socket: null,
      sendMsg: "",
      nikname: "",
      dialogVisible: false,
      chatList: [],
    };
  },
  created() {
    this.socket = io("ws://127.0.0.1:8888", {
      transports: ["websocket"],
    });
    this.getNikname();
    this.socket.on("connect", () => {
      console.log("建立连接"); // ojIckSD2jqNzOqIrAGzL
    });
    this.socket.on("response_chat", (data) => {
      this.severChat(data);
    });
    this.socket.on("logged", (data) => {
      this.severLog(data);
    });
    this.socket.on("logout", (data) => {
      this.severLog(data);
    });
  },
  mounted() {},

  methods: {
    severLog({ nikname, isLogin }) {
      let state = isLogin ? "进入" : "离开";
      let msg = `${nikname}${state}聊天室`;
      this.addChat({
        msg,
        style: "center",
      });
    },
    addChat({ msg = "xxx", nikname = "", style = "xxx" }) {
      this.chatList.push({
        nikname,
        msg,
        style,
      });
    },
    getNikname() {
      let nikname = this.$store.state.userInfor?.nikname;
      if (nikname) {
        this.dialogVisible = false;
        this.socket.emit("login", nikname);
      }
      this.dialogVisible = !nikname;
      this.nikname = nikname;
    },
    login() {
      if (!this.nikname) {
        this.$notify({
          message: "昵称不为空",
        });
        return;
      }
      this.socket.emit("login", this.nikname);
      this.dialogVisible = false;
    },
    send() {
      let msg = this.sendMsg;
      this.addChat({
        msg,
        nikname: this.nikname,
        style: "right",
      });
      this.socket.emit("chat", this.sendMsg);
      this.sendMsg = ''
    },
    severChat({ msg = "", nikname = "" }) {
      console.log(msg, nikname);
      this.addChat({
        nikname,
        msg,
        style: "left",
      });
    },
  },
};
</script>

<style lang="stylus" scoped>
ul
  list-style none
.talkView--content--body 
  width: 100%;
  height: 60vh;
  background-color: #fff;
  color: #333;
  .center
    text-align: center
  .left
    text-align: left
  .right
    text-align: right


.width100 {
  width: 100%;
  margin-top: 10px;
}
</style>

进入聊天页面后,先判断用户是否登录,如果登录,不必填写昵称,直接用用户昵称即可,反之,modal框会出现,必须填写昵称。之后,前端触发login事件,后端监听到login事件,io.sockets.emit向所有建立连接的客户端发送xxx登录信息,前端发送信息,触发chat事件,后端监听到事件之后,做出响应,触发response_chat事件。

涉及到的信息。存入chatList中,便于展示

例:

  • 7
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

热爱编程!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值