美文网首页
Socket.io的使用以及前后端通信方式的简单介绍

Socket.io的使用以及前后端通信方式的简单介绍

作者: Harlan_Zhang | 来源:发表于2020-09-20 16:09 被阅读0次

    前言

    前段时间修一个Bug的时候,涉及到了系统简历上传的功能,看了下代码发现用到了Socket来和后端通信。
    简要概况一下业务场景:先通过http请求来提交一份简历文件,后端返回部分数据。当后端解析处理完简历文件后,通过socket返回详细的简历信息。
    这里涉及到了两个值得记录的地方,一个是socket通信的实现,一个是服务端主动向客户端通信的方式,这篇文章主要介绍这两点。

    Socket通信

    Socket的实现有基于TCP协议的,也有基于UDP协议的,具体底层原理和模型这里就不赘述了,相关的文章也有不少。这里简要概况一下Socket和我们常用的Http的区别。

    Http请求-响应式的通信方式,客户端请求,服务端响应,然后通信结束。第二次通信就又需要重新建立连接。

    Socket是一种全双工通信,当客户端和服务端建立起连接后,如果不主动断开,双方可以一直互相发送消息,适合于双方频繁通信的场景,也是支持服务端主动推送的一种通信方式。

    WebSocketHtml5推出的前端可以直接使用的API,不过目前项目中用的还是Socket.io比较多。Socket.io在浏览器环境下封装了WebSocket, 可以给开发者带来更好的体验,在功能上也更完善。接下来我会使用Socket.io实现一个简单的Demo。

    Socket.io实现通信功能

    首先是服务端代码,先使用express来起一个服务。请求http://localhost:3000/upload接口返回对应数据。

    const express = require('express')
    const app = express()
    const port = 3000
    
    app.get('/upload', (req, res) => {
      res.send({
        name: 'Harlan的简历'
      })
    })
    
    app.listen(3000)
    

    接下来我们引入socket.io,实现一开始提到的业务场景:客户端上传简历文件之后服务端先返回基本信息,服务端解析完简历文件后返回详细信息。

    const express = require('express')
    const app = express()
    const port = 3000
    const server = require('http').createServer(app);
    const io = require('socket.io')(server);
    
    // 解决跨域问题
    app.all('*', function(req, res, next) {
      res.header("Access-Control-Allow-Origin", "*");
      res.header("Access-Control-Allow-Methods", "GET,HEAD,OPTIONS,POST,PUT");
      res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization");
      next();
    });
    
    app.get('/upload', (req, res) => {
      res.send({
        name: 'Harlan的简历'
      })
      // 耗时操作,3秒后通过socket返回数据,不使用http防止阻塞前端操作
      setTimeout(() => {
        io.emit('upload-resume', 'Harlan的简历详情')
      }, 3000)
      
    })
    
    server.listen(port, () => console.log(`Example app listening on port ${port}!`) );
    

    然后是客户端代码,这里也不用啥vue、react前端框架了,直接使用CDN引入socket.io,跑在浏览器中。

    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Document</title>
        <script src="https://cdn.jsdelivr.net/npm/socket.io-client@2/dist/socket.io.js"></script>
      </head>
      <body>
        <button id="upload">上传</button>
        <script>
          const socket = io("http://localhost:3000");
          const uploadBtn = document.querySelector("#upload");
          uploadBtn.addEventListener("click", () => {
            fetch("http://localhost:3000/upload")
              .then((res) => res.json())
              .then((res) => console.log('上传简历成功,返回数据:', res));
          });
          socket.on("upload-resume", (res) => {
            console.log('收到后端耗时处理的数据:', res)
          });
        </script>
      </body>
    </html>
    
    

    逻辑比较简单,先创建socket连接,然后点击按钮上传简历文件,接收到http返回的数据,一段时间后通过socket接受到其他的信息然后进行业务处理。

    服务端推送技术

    在这个业务场景中,socket通信其实是实现了一种服务端主动推送的功能,下面介绍一下我了解的服务端推送的技术 ,仅做简单介绍,有时间可能会再写几篇文章详细介绍一下。

    1. 客户端轮询
      这是一开始最早用到的一种方式,客户端定期去请求服务端看看有没有数据需要推送过来,缺点显而意见,会进行大量无意义的http请求,消耗性能,但是现在有些项目可能还会用这种技术。
    2. Socket通信
      socket是这篇文章主要介绍的东西,也是服务端主动推送的一种方式
    3. 消息队列
      消息队列也是以前用过的一种技术,比较常用的库是Rabbitmq的js实现amqplib。曾经做过PC端的Electron项目和IOS端应用的通信,当时使用了amqplib这个库。
    4. RPC
      RPC也是实现服务端推送的一种方式,以前调研过GRPC这个库,有兴趣的可以关注一下,和其他的几种技术还是不一样的。
    5. Http2
      现在Http2也已经实现了服务端推送的功能,如果你的项目里已经开始使用Http2.0的话,也可以考虑这种方式。

    小结

    socket最常用的场景还是进行频繁的客户端/服务端交互,比如说最经典的聊天室功能,核心的技术就是socket通信。在有的业务功能中,服务端推送也是必不可少的一种技术,但最终要如何选择还得根据项目情况来做具体分析。

    相关文章

      网友评论

          本文标题:Socket.io的使用以及前后端通信方式的简单介绍

          本文链接:https://www.haomeiwen.com/subject/rvcpyktx.html