原生前端与NodeJS服务端使用socket.io实现单聊的关键思想

先来展示我简单实现的单聊功能:
在这里插入图片描述
在这里插入图片描述
这是我在浏览器打开的两个聊天页面,实现的单聊功能,由于只是一个实验,所以就没太注意样式。

官方对socket.io的介绍:

使用LAMP (PHP)等流行的web应用程序堆栈编写聊天应用程序通常非常困难。它涉及到轮询服务器以查看更改、跟踪时间戳,而且它比应该的速度要慢得多。套接字在传统上是大多数实时聊天系统架构的解决方案,它提供客户机和服务器之间的双向通信通道。这意味着服务器可以向客户端推送消息。每当您编写一个聊天消息时,其思想是服务器将获得它并将其推给所有其他连接的客户机。

个人理解:

socket.io类似于WebSocket,同是一种在单个TCP连接上进行全双工通信的协议,socket使得客户端和服务端的数据交换变得更加简单,允许服务器主动向客户端推送信息。最重要的是,socket在前后端只需完成一次握手,两者就可以创建持久性的连接,也就是长连接,比如我这是在网页版实现的聊天,那么只有我关闭该浏览器页面,该连接才会断开,所谓的全双工,就是允许数据进行双向传输。

实现聊天功能通常都是使用socket实现,但也可以使用http实现,但不推荐,http是短链接,即完成一次交互就会断开连接,当用户要想接收到对方的信息时,就需要在间隔时间短的条件下不断轮询,问服务器有没有人给我发信息,这是非常浪费服务器资源的,也增大了服务器压力。。

1.搭建NodeJS服务端

1.首先搭建的是服务端,在项目目录下初始化:

npm install

项目目录会生成node_modules和package-lock.json文件。

2.服务端使用的是express框架:

npm install express --save

3.使用的socket版本是v2.3.0版本,更新的版本需要跨域

npm install [email protected] --save

想要看官方文档的可点击这里:socket.io官方文档

下面看代码:

var app = require('express')()
var server = require('http').createServer(app)
var io = require('socket.io')(server)
server.listen(80)

//客户端发起连接时触发
io.on('connection', (socket) => {
    
    
   //每当一个用户登录,就会生成一个socket对象,此时的socket是对应正连接的客户端对象
   
   //当用户连接成功后,向该客户端用户发送它自己的id,id特别重要,用于区分每个用户身份,正是用id才清楚发送方与接收方
   //为什么它只会发送给刚连接的用户呢?因为这个socket就是刚连接的用户生成的。
   //注意:第一个参数是自己定义的,只要前后端都对应即可
   socket.emit('setId',{
    
    id:socket.id})

   //allUser中保存了每个连接的用户的数据,即id和用户名,
   //由于新用户不知道之前有哪些旧用户,所以需要将这些已经在使用的用户发射给新用户,这样新用户才可以跟老用户聊天
   socket.emit('allUser',allUser);
	
    //广播api:它会向所有用户发送这个事件。由于它放在“连接”函数里面,所以只要有用户建立连接,就会发送这个事件
    //为什么要广播给所有用户呢?当有新用户加入,当然要告知之前的用户,让它们更新“用户列表”,这样新旧用户才能发起聊天
    //参数newUser是该新用户的信息
    //我这里使用的是一个对象,对象里面有两个属性,分别是用户id和用户名
    io.sockets.emit('addUser', newUser)

    //这是实现单聊的api,使用on监听客户端发来的sendMsgToUser事件
    //该事件携带发送的内容,data中有发送者和接收者的id和聊天内容
    //注意接收方的id是必须的,因为要通过接收方id,服务器才知道要把聊天内容发给谁
    //这里我之所以也传发送方的id,是为了让它知道是谁给它发信息
    socket.on('sendMsgToUser', (data) => {
    
    
      /**
       * data类型:
       * data:{
       *    from:"发送者id",
       *    to:'接收者id',
       *    content:'发送的内容'
       * }
       */
      //根据id,向接收方发射simpleChat事件,携带发送方发过来的data,即服务器只是起到转发作用
      socket.to(data.to).emit('simpleChat', data)
      })
  })
}

我相信看了上面的解释你们能理解服务器的socket的用法与作用。这些事件都是在用户发起连接时就绑定的监听事件。

2. 前端搭建

由于是一个小实验报告,为了减少代码体积,就没有使用框架,同时我们也不直接下载socket.io包,而是直接去github中复制socket.io的压缩代码:socket.io地址

图示:

在这里插入图片描述

在前端目录下新创一个socket.io.js文件,把复制的代码粘贴进去。

再创建一个index.html文件引入js文件:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>聊天室</title>
    <link rel="stylesheet" href="./index.css" />
    <script src="./socket.io.js" type="text/javascript" charset="utf-8"></script>
  </head>
  <body>
    
    <script>
      //引入socket.io.js文件成功的话,就可以在全局引用io对象
      //下面一句代码就是会连接上后端运行的服务器,并返回一个socket,只是我用conn表示而已
      var conn = io.connect('http://localhost')

      //监听,获取自身id
      conn.on('setId', (data) => {
     
     
        //在后端那里说过,当连接成功后,服务器会返回当前用户连接的id,在这里你可以保存好,在发送信息可以使用
      })

	  conn.on('allUser',(data)=>{
     
     
			//保存所用用户信息,将所有用户展示在用户列表上
	  })	  

      //监听是否有新用户加入
      conn.on('addUser', (data) => {
     
     
        //将这个新用户信息展示在用户列表中
      })

 
      //监听用户发来的信息
      conn.on('sendMsgToUser', (data) => {
     
     
        //假如xxx给我发送消息,那么当我点击用户列表的xxx时,聊天内容模板就给我展示聊天内容即可
        //要想做到有聊天记录,由于没有使用数据库,那你也可以在前端将与每个用户的聊天内容分别保存起来
        //当我点击哪个用户,就给我展示我与ta的聊天记录即可
      })

      //发送信息
      //将发送按钮的点击事件绑定给这个函数,当点击按钮时,就将信息发送
	 function sendMsg(){
     
     
	 	let msg={
     
     
			from:'由于是我给别人发送消息,那么就是我的id,我的id在上面已经保存了',
			to:'接收方的id',
			content:''获取输入框输入的内容
		};
		 conn.emit('sendMsgToUser', msg)
	}
    </script>
  </body>
</html>

这篇博客主要讲解socket实现单聊的关键api和思想,知道了如何实现单聊的思想和socket的api使用,剩下的就是如何设计聊天框,在这里就不再讲述。

猜你喜欢

转载自blog.csdn.net/weixin_43334673/article/details/109839669