Socket.io的使用以及前后端通信方式的簡(jiǎn)單介紹

前言

前段時(shí)間修一個(gè)Bug的時(shí)候,涉及到了系統(tǒng)簡(jiǎn)歷上傳的功能,看了下代碼發(fā)現(xiàn)用到了Socket來(lái)和后端通信。
簡(jiǎn)要概況一下業(yè)務(wù)場(chǎng)景:先通過(guò)http請(qǐng)求來(lái)提交一份簡(jiǎn)歷文件,后端返回部分?jǐn)?shù)據(jù)。當(dāng)后端解析處理完簡(jiǎn)歷文件后,通過(guò)socket返回詳細(xì)的簡(jiǎn)歷信息。
這里涉及到了兩個(gè)值得記錄的地方,一個(gè)是socket通信的實(shí)現(xiàn),一個(gè)是服務(wù)端主動(dòng)向客戶(hù)端通信的方式,這篇文章主要介紹這兩點(diǎn)。

Socket通信

Socket的實(shí)現(xiàn)有基于TCP協(xié)議的,也有基于UDP協(xié)議的,具體底層原理和模型這里就不贅述了,相關(guān)的文章也有不少。這里簡(jiǎn)要概況一下Socket和我們常用的Http的區(qū)別。

Http請(qǐng)求-響應(yīng)式的通信方式,客戶(hù)端請(qǐng)求,服務(wù)端響應(yīng),然后通信結(jié)束。第二次通信就又需要重新建立連接。

Socket是一種全雙工通信,當(dāng)客戶(hù)端和服務(wù)端建立起連接后,如果不主動(dòng)斷開(kāi),雙方可以一直互相發(fā)送消息,適合于雙方頻繁通信的場(chǎng)景,也是支持服務(wù)端主動(dòng)推送的一種通信方式。

WebSocketHtml5推出的前端可以直接使用的API,不過(guò)目前項(xiàng)目中用的還是Socket.io比較多。Socket.io在瀏覽器環(huán)境下封裝了WebSocket, 可以給開(kāi)發(fā)者帶來(lái)更好的體驗(yàn),在功能上也更完善。接下來(lái)我會(huì)使用Socket.io實(shí)現(xiàn)一個(gè)簡(jiǎn)單的Demo。

Socket.io實(shí)現(xiàn)通信功能

首先是服務(wù)端代碼,先使用express來(lái)起一個(gè)服務(wù)。請(qǐng)求http://localhost:3000/upload接口返回對(duì)應(yīng)數(shù)據(jù)。

const express = require('express')
const app = express()
const port = 3000

app.get('/upload', (req, res) => {
  res.send({
    name: 'Harlan的簡(jiǎn)歷'
  })
})

app.listen(3000)

接下來(lái)我們引入socket.io,實(shí)現(xiàn)一開(kāi)始提到的業(yè)務(wù)場(chǎng)景:客戶(hù)端上傳簡(jiǎn)歷文件之后服務(wù)端先返回基本信息,服務(wù)端解析完簡(jiǎn)歷文件后返回詳細(xì)信息。

const express = require('express')
const app = express()
const port = 3000
const server = require('http').createServer(app);
const io = require('socket.io')(server);

// 解決跨域問(wèn)題
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的簡(jiǎn)歷'
  })
  // 耗時(shí)操作,3秒后通過(guò)socket返回?cái)?shù)據(jù),不使用http防止阻塞前端操作
  setTimeout(() => {
    io.emit('upload-resume', 'Harlan的簡(jiǎn)歷詳情')
  }, 3000)
  
})

server.listen(port, () => console.log(`Example app listening on port ${port}!`) );

然后是客戶(hù)端代碼,這里也不用啥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('上傳簡(jiǎn)歷成功,返回?cái)?shù)據(jù):', res));
      });
      socket.on("upload-resume", (res) => {
        console.log('收到后端耗時(shí)處理的數(shù)據(jù):', res)
      });
    </script>
  </body>
</html>

邏輯比較簡(jiǎn)單,先創(chuàng)建socket連接,然后點(diǎn)擊按鈕上傳簡(jiǎn)歷文件,接收到http返回的數(shù)據(jù),一段時(shí)間后通過(guò)socket接受到其他的信息然后進(jìn)行業(yè)務(wù)處理。

服務(wù)端推送技術(shù)

在這個(gè)業(yè)務(wù)場(chǎng)景中,socket通信其實(shí)是實(shí)現(xiàn)了一種服務(wù)端主動(dòng)推送的功能,下面介紹一下我了解的服務(wù)端推送的技術(shù) ,僅做簡(jiǎn)單介紹,有時(shí)間可能會(huì)再寫(xiě)幾篇文章詳細(xì)介紹一下。

  1. 客戶(hù)端輪詢(xún)
    這是一開(kāi)始最早用到的一種方式,客戶(hù)端定期去請(qǐng)求服務(wù)端看看有沒(méi)有數(shù)據(jù)需要推送過(guò)來(lái),缺點(diǎn)顯而意見(jiàn),會(huì)進(jìn)行大量無(wú)意義的http請(qǐng)求,消耗性能,但是現(xiàn)在有些項(xiàng)目可能還會(huì)用這種技術(shù)。
  2. Socket通信
    socket是這篇文章主要介紹的東西,也是服務(wù)端主動(dòng)推送的一種方式
  3. 消息隊(duì)列
    消息隊(duì)列也是以前用過(guò)的一種技術(shù),比較常用的庫(kù)是Rabbitmq的js實(shí)現(xiàn)amqplib。曾經(jīng)做過(guò)PC端的Electron項(xiàng)目和IOS端應(yīng)用的通信,當(dāng)時(shí)使用了amqplib這個(gè)庫(kù)。
  4. RPC
    RPC也是實(shí)現(xiàn)服務(wù)端推送的一種方式,以前調(diào)研過(guò)GRPC這個(gè)庫(kù),有興趣的可以關(guān)注一下,和其他的幾種技術(shù)還是不一樣的。
  5. Http2
    現(xiàn)在Http2也已經(jīng)實(shí)現(xiàn)了服務(wù)端推送的功能,如果你的項(xiàng)目里已經(jīng)開(kāi)始使用Http2.0的話(huà),也可以考慮這種方式。

小結(jié)

socket最常用的場(chǎng)景還是進(jìn)行頻繁的客戶(hù)端/服務(wù)端交互,比如說(shuō)最經(jīng)典的聊天室功能,核心的技術(shù)就是socket通信。在有的業(yè)務(wù)功能中,服務(wù)端推送也是必不可少的一種技術(shù),但最終要如何選擇還得根據(jù)項(xiàng)目情況來(lái)做具體分析。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容