基于Web的网络聊天平台

qq_37028741 2022-01-18 18:29:10

1 项目介绍

本项目实现了一个仿WebQQ的网页聊天平台。本平台具有登陆功能,指定用户进行私聊功能,平台用户之间进行群聊的功能。用到的技术有:HTML、JavaScript、socket.io、jQuery、Nodejs。

1.1 jQuery

jQuery是一个轻量的、免费开源的JS函数库,本质上是一个JS文件,其中封装了许多JavaScript原生代码,将各种方法、属性简化,减少我们进行javas编程的复杂度。

1.2 socket.io

socket.io是一个面向实时web应用的JavaScript库,使得服务器和客户端之间实现通信成为可能。socket.io不等价于websocket,websocket只是socket.io实现即时通讯的其中一种技术依赖。socket.io会自动选择合适的双向通信协议,仅仅需要程序员对套接字的概念有所了解。

1.3 Nodejs

Nodejs是一个开源和跨平台的JavaScript运行时环境,开发人员可以使用JavaScript创建各种服务端工具和应用程序,此运行时环境主要用于浏览器上下文之外。Nodejs是单线程+非阻塞I/O模型,适合高并发,适合I/O密集型应用,不适合CPU密集型应用。

 

2 核心代码实现

连接socket.io服务

var socket = io('http://localhost:8000')

 服务端注册socket.io服务

const express = require('express');
const app = express();
const http = require('http');
const server = http.createServer(app);
const io = require('socket.io')(server)
server.listen(8000, () => {
  console.log('服务器运行中')
})

点击登陆按钮触发事件,将用户名和头像通过socket.io发给服务端

// 监听按钮点击事件
$('#loginBtn').on('click', function () {
  // 从input获取用户名
  var username = $('#username').val()
  if (!username) {
    window.alert('请输入用户名')
    return
  }
  if (username === '群聊') {
    window.alert('用户名已存在')
    return
  }
  // 从选中的头像中获取头像图片文件
  var touxiangImage = $('#loginTouXiangImage li.now img').attr('src')
  console.log(username, touxiangImage)
  // 给服务端socket.io发送消息
  socket.emit('login', {
    username,
    touxiangImage
  })
})

服务端接收浏览器传来信息,并更新页面信息:提示有新用户上线、增加用户列表下的用户项。

socket.on('login', data => {
    console.log(data)
    // 如果有用户请求登录,找已登录户列表看是否已经登陆
    const user = users.find(item => item.username === data.username)
    // 如果已经登陆过,提示登陆失败
    if (user) {
      socket.emit('failLogin', { msg: '登录失败' })
    } else {
      // 加入新用户信息:用户名和头像
      users.push(data)
      socket.emit('successLogin', data)
      console.log('登录成功')
      // 发送数据给newUser事件,提醒有新用户上线
      io.emit('newUser', data)
      // 发送数据给newItem事件,往页面用户列表中添加新用户
      io.emit('newItem', users)
      socket.username = data.username
      socket.touxiangImage= data.touxiangImage
    }
  })

新用户上线提醒事件

socket.on('newUser', data => {
  // 发送一条用户上线消息
  $('.onlineMessage').append(`
    <div class="system">
      <p class="message_system">
        <span class="content">${data.username} 已上线</span>
      </p>
    </div>
  `)
})

用户列表添加新用户

socket.on('newItem', data => {
  //根据服务端传来的用户信息,将所有用户的信息添加到用户列表中
  data.forEach(item => {
    $('.user-list ul').append(`
      <li class="user">
        <div class="touxiangImage"><img src="${item.touxiangImage}" alt=""></div>
        <div class="name">${item.username}</div>
      </li>
    `)
  })
})

 将聊天框的内容发送给服务端

$('#buttonSend').on('click', () => {
  var content = $('#content').html().trim()
  $('#content').html('')
  if 
  if (nameSend ==(!content) {
    return window.alert('请输入内容')
  }= '群聊') {
  // 发送群聊消息给服务端
    socket.emit('groupChat', {
      msg: content,
      username,
      touxiangImage,
      toUser
    })
  } else {
    // 发送私聊消息给服务端
    socket.emit('personalChat', {
      msg: content,
      username,
      touxiangImage,
      toUser: toUser
    })
  }
})

服务端将接收到的用户消息进行转发 


  //私聊
  socket.on('personalChat', data => {
    // 广播给指定用户
    var toSocket = null
    for (const key in io.sockets.sockets) {
      if (io.sockets.sockets[key].username === data.toUser) {
        toSocket = key
        break
      }
    }
    if (toSocket) {
      // 发送给指定用户
      socket.to(toSocket).emit('message', data)
      // 发送给自己
      socket.emit('message', data)
    }
  })

客户端将接收到的信息添加到页面上:区分自己的消息或是他人的消息


  socket.on('message', data => {
  if (data.toUser === '群聊') {
    if (username === data.username) {
      // 自己发的消息显示在聊天框右边
      $('.messageContainer').append(`
        <div class="message-box">
          <div class="my message">
            <img src="${data.touxiangImage}" alt="" class="avatar">
            <div class="content">
              <div class="roll">
                <div class="rolling">${data.msg}</div>
              </div>
            </div>
          </div>
        </div>
      `)
    } else {
      // 别人发的消息显示在聊天框左边
      $('.messageContainer').append(`
        <div class="message-box">
          <div class="other message">
            <img src="${data.touxiangImage}" alt="" class="avatar">
            <div class="nickname">${data.username}</div>
            <div class="content">
              <div class="roll">
                <div class="rolling">${data.msg}</div>
              </div>
            </div>
          </div>
        </div>
      `)
    }
  }
  //如果是私聊 
  else {
    if (username === data.username) {
      // 自己发的消息显示在聊天框右边
      $('.messageContainer').append(`
        <div class="message-box">
          <div class="my message">
            <img src="${data.touxiangImage}" alt="" class="avatar">
            <div class="content">
              <div class="roll">
                <div class="rolling">${data.msg}</div>
                <div class="rollingToUser">私聊</div>
              </div>
            </div>
          </div>
        </div>
      `)
    } else {
        // 别人发的消息显示在聊天框左边
      $('.messageContainer').append(`
        <div class="message-box">
          <div class="other message">
            <img src="${data.touxiangImage}" alt="" class="avatar">
            <div class="nickname">${data.username}</div>
            <div class="content">
              <div class="roll">
                <div class="rolling">${data.msg}</div>
                <div class="rollingToUser">私聊</div>
              </div>
            </div>
          </div>
        </div>
      `)
    }
  }
})

3 效果展示

登陆界面

 输入用户名登陆

 发送群聊消息

 

私聊

 

 

4 总结

花了半个月学习了HTML、JavaScript和CSS相关知识,通过网络程序设计这门课学到了Nodejs和websocket相关知识。本次课程项目对于没学过前端相关知识的我来说具有一定挑战难度,最后还是通过学习文档、观看教学视频完成了项目的基本功能,虽说不是做的很好。

 

 作者:NP400

 

...全文
242 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

571

社区成员

发帖
与我相关
我的任务
社区描述
软件工程教学新范式,强化专项技能训练+基于项目的学习PBL。Git仓库:https://gitee.com/mengning997/se
软件工程 高校
社区管理员
  • 码农孟宁
加入社区
  • 近7日
  • 近30日
  • 至今

试试用AI创作助手写篇文章吧