Node.js学习笔记(五)——WebSocket

文章浏览阅读323次。前端和后端的交互的方式有哪些?前台里面能够发送网络请求的标签,基本上都可以和后端实现网络交互。ajaxjsonpiframewebsocket…我们思考一个问题在之前,我们知道前后端数据交互的过程中,都是前端发送请求,

前端和后端的交互的方式有哪些?

前台里面能够发送网络请求的标签,基本上都可以和后端实现网络交互。

  • ajax
  • jsonp
  • iframe
  • websocket

我们思考一个问题
在之前,我们知道前后端数据交互的过程中,都是前端发送请求,后端给予响应。但是有没有一种情况就是在前端没有发送请求的情况下,后端自动向前端一个响应?

其实是有这种情况的,就是服务器主动向客户端推信息,我们称之为coment技术(推技术)。

coment技术如何实现?

  • ajax+定时器(轮询long-polling,伪实现)
  • 长链接
  • websocket

WebSocket

WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。

WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在 WebSocket API 中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。

在 WebSocket API 中,浏览器和服务器只需要做一个握手的动作,然后,浏览器和服务器之间就形成了一条快速通道。两者之间就直接可以数据互相传送。

现在,很多网站为了实现推送技术,所用的技术都是 Ajax 轮询。轮询是在特定的的时间间隔(如每1秒),由浏览器对服务器发出HTTP请求,然后由服务器返回最新的数据给客户端的浏览器。这种传统的模式带来很明显的缺点,即浏览器需要不断的向服务器发出请求,然而HTTP请求可能包含较长的头部,其中真正有效的数据可能只是很小的一部分,显然这样会浪费很多的带宽等资源。

HTML5 定义的 WebSocket 协议,能更好的节省服务器资源和带宽,并且能够更实时地进行通讯。

在这里插入图片描述
为了方便使用,我们可以使用第三方库socket.io

socket.io

socket.io是一个跨浏览器支持WebSocket的实时通讯的JS。

Socket.io支持及时、双向、基于事件的交流,可在不同平台、浏览器、设备上工作,可靠性和速度稳定。最典型的应用场景如:

  • 实时分析:将数据推送到客户端,客户端表现为实时计数器、图表、日志客户。
  • 实时通讯:聊天应用
  • 二进制流传输:socket.io支持任何形式的二进制文件传输,例如图片、视频、音频等。
  • 文档合并:允许多个用户同时编辑一个文档,并能够看到每个用户做出的修改。

Socket.io实际上是WebSocket的父集,Socket.io封装了WebSocket和轮询等方法,会根据情况选择方法来进行通讯。

Node.js提供了高效的服务端运行环境,但由于Browser对HTML5的支持不一,为了兼容所有浏览器,提供实时的用户体验,并为开发者提供客户端与服务端一致的编程体验,于是Socket.io诞生了。

Socket.io将WebSocket和Polling机制以及其它的实时通信方式封装成通用的接口,并在服务端实现了这些实时机制相应代码。

socket.io基本使用方式

  1. 安装
npm install socket.io
  1. 使用
const express = require('express');
const app = express();
const http = require('http').createServer(app);
const io = require('socket.io')(http);

// 静态资源
app.use(express.static('./public'));

app.get('/', (req, res) => {
   
  res.send("hello")
});

io.on('connection', (socket) => {
   
    // emit 参数:
    // 参数1:代表是触发事件需要实现在websocket的客户端进行监听
    // 参数2:传递给客户端的数据
    setInterval(() => {
   
        socket.emit('msg', '服务器端' + Math.random());
    },1000)
});

http.listen(3000, () => {
   
  console.log('listening on *:3000');
});
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <h1>客户端</h1>
    <button id="btn">点击连接websocket服务器</button>
    <div class="content"></div>
</body>
<!-- 书写websocket客户端代码 -->
<!--1. 使用一个第三方的websocket客户端库实现websocket服务-->
<script src="https://cdn.bootcdn.net/ajax/libs/socket.io/2.2.0/socket.io.js"></script>
<script src="https://cdn.bootcss.com/jquery/2.0.1/jquery.js"></script>

<script> // 2. 编写客户端代码 var socketServerUrl = 'http://localhost:3000'; $("#btn").click(() => {
     // 3. 发送链接请求 var socketClient = io(socketServerUrl); // 4. 得到一个websocket客户端 // 5. connect是客户端一旦链接websocket服务器成功,回调函数立即执行 socketClient.on('connect', () => {
     console.log("链接服务器成功" ) }) socketClient.on('msg', (data) => {
     $(".content").append(data + "<hr>"); }) }) </script>
</html>

启动服务,在浏览器地址栏输入:http://localhost:3000/
在这里插入图片描述
点击按钮,客户端和服务器成功链接一次,这次链接后,将保持链接,之后每一秒钟服务器端都会主动向客户端发送响应。

在这里插入图片描述

使用webscoket实现一个简单的即时聊天工具

const express = require('express')
const app = express();
const moment = require('moment')
const http = require('http').createServer(app);
const io = require('socket.io')(http);

// 静态资源
app.use(express.static('./public'));

// 客户端月服务端连接 短连接服务
app.get('/', (req, res) => {
   
    res.send('hi web!');
});

// websocket 客户端---> websocket 服务器 长链接服务
// on 代表事件监听 connection 链接事件,服务器现在监听websocket客户端的链接,一般 链接成功 回调函数执行,socket 参数代表是当前链接的对象,我们可以通过该对象和客户端进行交互。
io.on('connection', (socket) => {
   
    // console.log(socket);
    console.log('a user connected');
    // emit 单词翻译过来触发。
    // 参数1:代表是触发事件需要实现在websocket的客户端进行监听
    // 参数2: 传递给客户端的数据

    // 监听客户端发送的 joinUs 事件
    socket.on('joinUs', (data)=> {
   
        console.log(data);
        // 广播给所有的客户端,有新人加入聊天(暴照)
        io.emit('guangbo', data);
    })

    // 监听 用户发送聊天信息
    socket.on('sendMsg', (data) => {
   
        // 广播给所有人
        data.time = moment().format('YYYY-MM-DD HH:mm:ss');
        io.emit('chat', data);
    })
});

http.listen(3000, () => {
   
    console.log('listening on *:3000');
});
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>输入用户名</title>
  <link rel="stylesheet" href="./style/style.css">
</head>
<body>
  <div class="i-body">
    <h1>请输入你的昵称:</h1>
    <form id="usernameForm">
      <input type="text" id="nickname">
    </form>
  </div>
</body>
</html>
<script src="https://cdn.bootcss.com/jquery/2.0.1/jquery.js"></script>
<script> $("#usernameForm").submit( (event) => {
     event.preventDefault(); // 阻止表单默认的提交 var nickname = $("#nickname").val().trim(); // 自己跳转到 room.html // 现在要和 room.html 页面共享 nickname这个用户名 localStorage.setItem('nickname', nickname); location.href = '/room.html'; } ) </script>
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>迷你聊天室</title>
  <link rel="stylesheet" href="./style/style.css">
</head>
<body>
  <header class="c-header">
    <h1>迷你聊天室</h1>
    <div class="c-user"><img src="./imgs/1.jpg" title=""></div>
  </header>
  <div class="c-body">
    <div class="c-main">
      <ul class="c-list">
      </ul>

      <div class="c-xxx"></div>
      <div class="c-chat">
        <img class="c-avatar2" src="./imgs/1.jpg" alt="">
        <input class="c-input" type="text" id="content">
        <button class="c-btn" id="msgBtn">发送</button>
      </div>
    </div>
  </div>
</body>
</html>

<script src="https://cdn.bootcss.com/jquery/2.0.1/jquery.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/socket.io/2.2.0/socket.io.js"></script>

<script> ;(()=>{
     var nickname = localStorage.getItem('nickname'); if(!nickname){
     location.href = '/index.html'; return; } // 设置连接地址 var socketServerUrl = 'http://localhost:3000'; // 连接请求 var socketClient = io(socketServerUrl); // connect是客户端一旦链接websocket服务器成功,回调函数立即执行 socketClient.on('connect', () => {
     console.log('链接服务器成功!'); }) // 将数据发送给websocket服务器,发布广播 socketClient.emit('joinUs', {
    nickname}); // 点击发送按钮 $("#msgBtn").click(()=> {
     var content = $("#content").val().trim(); if(!content){
     alert('聊天信息不能为空!'); return; } // 将数据发送给websocket服务器,发布广播 socketClient.emit('sendMsg', {
    nickname, content}); $("#content").val(''); }) // 监听事件 socketClient.on('guangbo', (data)=>{
     console.log('guangbo', data); var html = `<li class="c-item"> <div class="c-join-info">【${
      data.nickname}】加入聊天室</div> </li> `; $(".c-list").append(html) }) // 监听事件 socketClient.on('chat', (data) => {
     console.log('data', data); // 聊天的信息放置页面 data.nickname 信息发送者 var html = ``; if(nickname == data.nickname){
     // 代表自己发送 my-item 类名 底纹 html = ` <li class="c-item my-item"> <img class="c-avatar" src="./imgs/3.jpg" title=""> <div class="c-box"> <div class="c-info"> <div class="c-name">${
      data.nickname} ${
      data.time}</div> </div> <div class="c-content">${
      data.content}</div> </div> </li>`; }else{
     html = ` <li class="c-item"> <img class="c-avatar" src="./imgs/3.jpg" title=""> <div class="c-box"> <div class="c-info"> <div class="c-name">${
      data.nickname} ${
      data.time}</div> </div> <div class="c-content">${
      data.content}</div> </div> </li>`; } $('.c-list').append(html); }) })(); </script>

启动服务,在浏览器地址栏输入:http://localhost:3000/index.html
在这里插入图片描述
输入昵称,回车,加入聊天室:
在这里插入图片描述

在这里插入图片描述
可以发送消息:
在这里插入图片描述
当另一个用户也进入了聊天室,可以看到提示:
在这里插入图片描述
当另一个人发送消息:
在这里插入图片描述
至此,简单的聊天室实现了。

当然,在实际开发中,我们大可不必自己写聊天室,有现成的一些网站就提供了很好的即时聊天功能,比如:
http://kedou.workerman.net/
https://www.easemob.com/
https://layim.layui.com/

参考文档:
https://socket.io/get-started/chat/
https://www.jianshu.com/p/4e80b931cdea

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/88367.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注