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

前言

前段时间修一个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通信。在有的业务功能中,服务端推送也是必不可少的一种技术,但最终要如何选择还得根据项目情况来做具体分析。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,657评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,662评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,143评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,732评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,837评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,036评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,126评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,868评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,315评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,641评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,773评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,470评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,126评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,859评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,095评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,584评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,676评论 2 351