socket.io聊天室

介绍

通常我们web使用的是http协议,但是 HTTP 协议有一个缺陷:通信只能由客户端发起。

所以我们需要一个可以由服务端主动发出的协议,即WebSocket。

WebSocket是HTML5新增的一种通信协议,其特点是服务端可以主动向客户端推送信息,客户端也可以主动向服务端发送信息,是真正的双向平等对话,属于服务器推送技术的一种。

Socket.IO 是一个基于 Node.js 的实时应用程序框架,在即时通讯、通知与消息推送,实时分析等场景中有较为广泛的应用。

socket.io 包含两个部分:

  • 服务器端(server):运行在 Node.js 服务器上
  • 客户端(client):运行在浏览器中

搭建步骤

  1. 首先,让我们创建一个package.json描述我们项目的清单文件。
    执行:npm init -y
    生成package.json文件
{
  "name": "aaa",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies":{}
}
  1. 下面,为dependencies用我们需要的东西填充属性,我们将使用npm install:
    npm install express --save
  2. 安装完成后,我们可以创建一个index.js文件来设置我们的应用程序。
    const express = require('express')
    const app = express()
    
    app.use(express.static(__dirname + '/www'));
    
    app.listen(3000, () => console.log('Example app listening on port 3000!'))

这意味着:

  • Express初始化app为可以提供给HTTP服务器的函数处理程序
  • 我们定义了一个路由处理程序/,当我们访问我们的网站主页时会被调用。
  • 我们使http服务器在端口3000上侦听。
  1. 创建静态资源 www/index.html :
<!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
        <style>
            * {
                margin: 0;
                padding: 0;
            }
            html,
            body {
                height: 100%;
                overflow: hidden;
            }
            .chat {
                float: left;
                padding: 1em 1em 0 2em;
                height: 100%;
                width: 500px;
                border-right: 1px solid #DA4;
                overflow-y: scroll;
            }
            .inputpart {
                float: left;
                margin-left: 10px;
            }
            #userName {
                font-size: 20px;
                color: rgb(3, 57, 109);
            }
        </style>
    </head>
    <body>
        <div class="chat">
            <ul id="messages">
                //聊天信息

            </ul>
        </div>
        <div class="inputpart">
            <div id="userName">
    			//用来展示用户id
            </div>
            
            <div action="" id='logForm'>
              <input type="text" id='inpU'>
              <button id='login'>登陆</button>
            </div>

            <div id='chatForm' style='display: none;'>
                <input autocomplete="off" id="inpB" /><button id="say">Send</button>
            </div>
        </div>
    </body>
    </html>

此时开启服务: node index, 访问 localhost:3000。就能看到页面了。
5. 安装:socket.io

npm install socket.io --save

这将安装模块并将依赖项添加到中package.json
6. 然后在index.js中注册socket.io,并改为http监听:

const express=require('express')

const app = express();

let http = require('http').Server(app)
// socket.io作为一个函数,当前http作为参数传入生成一个io对象?
// io-server
const io = require('socket.io')(http) 
app.use(express.static(__dirname + '/www'));

io.on('connection', (socket) => {
  console.log('a user connected');
});
http.listen(3000, () => console.log('Example app listening on port 3000!'))

此时服务已改为WebSocket服务。

这段代码中,connection事件在客户端成功连接到服务端时触发,有了这个事件,我们可以随时掌握用户连接到服务端的信息。

  1. 数据传输
    服务端运行后会在根目录动态生成socket.io的客户端js文件,客户端可以通过固定路径/socket.io/socket.io.js添加引用。
    在HTML中引用js文件,并调用:
<script src="/socket.io/socket.io.js"></script>
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script>
$(function () {
   // 连接成功会触发服务器端的connection事件
    var socket = io(); 
})
</script>
  1. 开启服务: node index, 访问 localhost:3000。尝试打开多个标签,您将看到几条消息。

在这里插入图片描述
9. 当客户端成功建立连接时,在connection事件的回调函数中,我们还是可以为socket注册一些常用的事件,如:disconnect事件socket.on(‘disconnect’,function(){…});,它在客户端连接断开时触发,这时候我就知道用户已经离开了。


io.on('connection', (socket) => {
  console.log('a user connected');
  socket.on('disconnect', () => {
    console.log('user disconnected');
  });
});

  1. 然后,如果多次刷新选项卡,则可以看到它的作用。
    在这里插入图片描述
  • 向连接的客户端发消息,Socket.IO向我们提供了该io.emit()方法。
  socket.emit('hello', 'can you hear me?', 1, 2, 'abc');
  • 给除了本次连接的其他所有连接者广播消息
socket.broadcast.emit('broadcast', 'hello friends!');

前端代码如下:

$(function () {
   // 连接成功会触发服务器端的connection事件
       // io-client
    // 连接成功会触发服务器端的connection事件
    var socket = io(); 


    //输入昵称 、登陆
    $('#login').on('click',function(e){
      if($('#inpU').val().trim()!==''){
        socket.emit('login', { 
            name: $('#inpU').val()
          });
      }else{
        alert('用户名不能为空')
      }
          
    })

    // 登录成功,隐藏登录模块,显示聊天模块
      socket.on('loginSuc', function(){ 
      $('#logForm').hide(); 

      $('#chatForm').show();

    })

    // 登陆失败
    socket.on('loginError', ()=> {
      alert('用户名已存在,请重新输入!');
      $('#name').val('');
    }); 

       //按下回车键发送聊天信息
      $('#inpB').keyup((e)=> {
      if(e.keyCode == 13) {
        sendMessage();
      }
    });
      //点击发送也可以发送消息
      $('#say').on('click',function(){
        sendMessage();
      })
    function sendMessage(){
      if($('#inpB').val().trim()==''){
        alert('请输入内容!');
        return false;
      }else{
        socket.emit('sendMsg', {
        msg: $('#inpB').val()
      });
      $('#inpB').val(''); 
      return false; 
      }
    }

        // 接收消息
        socket.on('receiveMsg', function(obj){  
              console.log(obj);
              $('#messages').append(`<li>姓名:${obj.name}   ${obj.msg}</li>`)
        })


})
  1. 后端代码如下:
var express = require('express');  // 引入express模块
var app=express();
var http = require('http').Server(app);

var io = require('socket.io')(http);

var users = []; // 储存登录用户
// 路由为/默认www静态文件夹
app.use('/', express.static(__dirname + '/www'));


io.on('connection', function(socket){ // 用户连接时触发
        console.log('a user connected');
    
        // 登录,检测用户名
    socket.on('login', function(user){
      if(users.indexOf(user.name) > -1) { 
          socket.emit('loginError');
      } else {
          users.push(user.name);
          socket.nickname = user.name;
          socket.emit('loginSuc');
      }
    })      

     // 发送消息事件
     socket.on('sendMsg', function(data){
      
    
      socket.broadcast.emit('receiveMsg', {
          name: socket.nickname,
          msg: data.msg
      });
      socket.emit('receiveMsg', {
          name: socket.nickname,
          msg: data.msg   
      });
  });  

   


        socket.on('disconnect', function(){
          console.log('user disconnected');
        });
      });


http.listen(4000, function(){  // 监听3000端口
  console.log('listening on *:4000'); 
});
原创文章 56 获赞 55 访问量 9640

猜你喜欢

转载自blog.csdn.net/weixin_43638968/article/details/105716211