前端开发 - 即时通信 【socket.io(WebSocket)】 基本使用?

一、WebSocket 简介

  • 什么是 websocket
    • 是一种 网络通信协议 ,和 http 协议一样;
  • 为什么需要 websocket 协议?
    • http 协议通信 只能由 客户端发起不能双向通信
      • 简单来说,http是客户端发一个,服务端响应一个;
      • 如果你不发请求,服务端是不会有响应的;
    • websocket ,只要客户端向服务端发起邀请,建立连接,服务端应答之后,就可以发送消息了(不管是客户端还是服务端还是两个同时都能发),关闭连接之后,通信就结束了;
  • 项目中使用 socket.io-client 来实现 客户端功能 ,它是基于 websocketJS 库;

二、JS 内置的 WebSocket 基本使用

  • WebSocketJS内置的构造函数;
  • 使用原生 WebSocket 进行前后端通信的时候,该构造函数需要一个参数:
    • 服务端的通信地址;

2.1 建立连接

js 复制代码
const ws = new WebSocket('wss://javascript.info/article/websocket/demo/hello');

2.2 监听连接成功 - ws.onopen

  • 服务器应答之后就连接成功了
  • 应答之后会触发 onopen() 处理函数;
js 复制代码
ws.onopen = () => {
    console.log('连接成功');
}

2.3 如何发消息 - ws.send()

html 复制代码
<body>
<button id="btn">发消息</button>

<script>
    document.querySelector('#btn').onclick = () => {
        ws.send('你好服务器!');
    };
</script>
</body>
  • 如何检测发向服务端的消息发送成功了?
  • 只要能接收到服务器发送来的消息,就说明发送成功了

2.4 如何接消息 - ws.onmessage

  • onmessage() ➡ 该函数有一个实参 $e / event ,**$e.data**就是服务端向客户端发送的消息;
js 复制代码
ws.onmessage = ($e) => {
    console.log('服务端向客户端发送的消息', $e);
};

2.5 如何关闭连接

  • 关闭服务器连接有两种方式可以关闭,一种是客户端关闭(推荐),还有一种是服务端主动关闭(不推荐);
  • 在我们开发的过程中,一定是要我们 客户端去关闭的

2.5.1 客户端关闭 - ws.close()

html 复制代码
<body>
<button id="btn2">关闭连接</button>

<script>
    document.querySelector('#btn2').onclick = () => {
        ws.close();
    };
</script>
</body>

2.5.2 服务端主动关闭

  • 当服务器向客户端发送消息等几秒之后,此次的连接会自动关闭,但是 是 服务端主动关闭

2.6 监听通信关闭 - ws.close

js 复制代码
ws.onclose = () => {
    console.log('连接关闭');
};
  • 注意
    • 第一次:
      • 服务端关闭连接
      • 服务端给客户端发送消息等一会之后,自动关闭了连接;
    • 第二次:
      • 客户端关闭连接
      • 我手动点击的关闭连接;

三、体验 Socket.IO

3.1 Socket.IO是什么?

  • 基于 WebSocket即时通讯 的解决方案,提供后端即时通信服务,前端连接后端JS库;
  • socket.io 是一个基于 WebSocket 的 CS(客户端-服务端)的实时通信库;
  • 使用它可以在后端提供一个即时通讯服务;
  • 它也提供一个 js 库,在前端可以去链接后端的 socket.io 创建的服务;
  • 总结 :它是一套基于 websocket 前后端 即时通讯 解决方案

3.2 克隆 socket.io 官方提供的服务端

  1. 仓库地址:git clone https://github.com/socketio/chat-example.git注意
    • 可能克隆的项目跑不起来,提示 Error: ENOENT: no such file or directory, stat xxx(如果哪位大佬解决了这个问题,告诉小弟一声哈😁);
    • 大家可以克隆这个比较旧的项目体验:git clone https://gitee.com/draw-a-beautiful-yarn/socket-io.git
  2. 克隆到本地之后,使用命令下载对应的包:
    • pnpm install、pnpm add、npm install、yarn add
  3. 运行项目:pnpm start、npm run start、yarn start
  4. 测试:
    • 项目跑起之后,有很多地址,我们可以随便选一个进行测试;
    • 在浏览器中打开两个Tab页,输入选择的地址,进行发送消息,可以看到,A窗口发送的消息在B窗口中也能看到,反之同理;

注意

  • 可能在运行项目的时候会报错:
  • 报错信息:
    • 报错原因为是因为没有 express 这个包;
  • 解决方案
    • 安装express包:
      • pnpm install express@4;
      • 大家可以自行选择命令(pnpm快很多😂😂);

四、socket.io-client 在项目中的使用

4.1 安装 socket.io-client

js 复制代码
// 选择一个命令下载即可
pnpm add socket.io-client
npm install socket.io-client
yarn add socket.io-client

4.2 初始化socket 及 常用事件

ts 复制代码
import io from 'socket.io';

// 初始化 socket.io
const socket = io('服务器地址');

// 连接成功触发的事件
socket.on('content', () => {
    console.log('连接成功');
});

// 客户端 发消息
socket.emit('前后端约定的事件名称', '要发送的消息');

// 客户端接收服务端发送的消息
socket.on('前后端约定的事件名称', (msg) => {
    // msg 就是后端发送的消息
    console.log(msg);
});

// 关闭连接
socket.close();

// 关闭连接触发的函数(触发这个函数的时候,说明服务已经断开了)
socket.on('disconnect', () => {
    console.log('关闭连接');
});

4.3 ❗❗ 在项目中的使用

4.3.1 初始化 socket

  • 初始化的时机:
    • 组件初始化完毕之后 开始初始化socket;
      • Vue2created() / mounted()
      • Vue3onMounted()
js 复制代码
// Vue2
created() {
    // 参数1:不传默认是当前服务域名,开发中传入服务器地址
    // 参数2:配置参数,根据需求(一般 token 是必须传递的)
    const socket = io(参数1, 参数2);
    
    // 将以上需要的地址、配置参数完成之后,就可以建立连接
}

// Vue3
import { onMounted } from 'vue';

onMounted(() => {
    // 参数1:不传默认是当前服务域名,开发中传入服务器地址
    // 参数2:配置参数,根据需求(一般 token 是必须传递的)
    const socket = io(参数1, 参数2);
    
    // 将以上需要的地址、配置参数完成之后,就可以建立连接
});

4.3.2 添加基本事件

  • 我这里就以 Vue3 + TypeScript 为例开始写(如果是Vue2的项目,不用写类型注解,更换钩子函数即可);
ts 复制代码
// Vue2: import io from 'socket.io';

// Vue3
import { io, type Socket } from 'socket.io';
import { onMounted, onUnmounted } from 'vue';

// 将 socket 定义在这里是因为,在组件加载完毕 和 卸载(或这说离开当前页面)的时候,都需要使用到socket;
let socket: Socket;

// 在组件初始化的时候建立连接
// Vue2: mounted()
onMounted(() => {
    // 初始化 socket
    socket = io('服务器地址', options);
    
    // 建立连接
    socket.on('connect', () => {
        console.log('建立连接');
    });
    
    // 客户端发送消息失败触发的函数
    // 消息发送失败的时候,可以在这个事件处理函数中进行相应逻辑的处理
    socket.on('error', () => {
        console.log('客户端发送消息失败');
    });
    
    // 关闭连接
    socket.on('disconnect', () => {
        console.log('关闭连接');
    });
});

// 组件卸载钩子函数
// Vue2: destroyed()
onUnmounted(() => {
    // 组件卸载 / 离开当前页面 的时候 关闭连接
    socket.close();
});

4.3.3 通信规则(聊天事件)

  • 我们和服务器聊天的时候,需要定义对应的事件来触发不同的聊天机制;
  • 关于定义的事件,需要和后端商议,等后端那边完成之后,有时候会直接给我们一个事件名称,有时候给的是一个接口地址(eg:https://xxx.xxx/getMessage),如果给的是地址,我们只需关注最后面的单词,这个就是事件名,保险起见,最好还是咨询一下后端😂😂;
  • 注意
    • 通信规则很重要;
相关推荐
秦jh_9 分钟前
【Linux】多线程(概念,控制)
linux·运维·前端
蜗牛快跑21322 分钟前
面向对象编程 vs 函数式编程
前端·函数式编程·面向对象编程
Dread_lxy23 分钟前
vue 依赖注入(Provide、Inject )和混入(mixins)
前端·javascript·vue.js
涔溪1 小时前
Ecmascript(ES)标准
前端·elasticsearch·ecmascript
榴莲千丞1 小时前
第8章利用CSS制作导航菜单
前端·css
奔跑草-1 小时前
【前端】深入浅出 - TypeScript 的详细讲解
前端·javascript·react.js·typescript
羡与2 小时前
echarts-gl 3D柱状图配置
前端·javascript·echarts
guokanglun2 小时前
CSS样式实现3D效果
前端·css·3d
咔咔库奇2 小时前
ES6进阶知识一
前端·ecmascript·es6
渗透测试老鸟-九青2 小时前
通过投毒Bingbot索引挖掘必应中的存储型XSS
服务器·前端·javascript·安全·web安全·缓存·xss