Nodejs实现WebSocket代码实例

yizhihongxing

下面是针对“Nodejs实现WebSocket代码实例”的完整攻略,包含代码示例和详细说明:

什么是WebSocket

WebSocket是HTML5提出的一种新型通信协议,它建立在传输层TCP协议之上,并通过HTTP协议进行握手。WebSocket协议的特点是支持全双工通信、实时性更高、更省带宽、更灵活、能够实现跨域通信等。

Nodejs实现WebSocket的原理

Node.js中实现WebSocket通信需要依赖两个核心模块wshttp模块,前者用于WebSocket通信,后者用于提供HTTP请求服务。

WebSocket通信的过程可以简化为以下步骤:

  1. 客户端发送一个WebSocket请求,请求报文中包含WebSocket key和协议版本信息。
  2. 服务端收到WebSocket请求,校验WebSocket key并返回HTTP响应报文,包含一个握手响应头Sec-WebSocket-Accept以及协议版本信息。
  3. 客户端收到握手响应后,判断Sec-WebSocket-Accept是否与自己生成的WebSocket key匹配,如果匹配则认为握手成功,开始进行WebSocket通信。

实现WebSocket通信的关键是进行握手,需要在服务端接收到WebSocket请求后进行握手处理。

握手的过程示例代码如下:

const http = require('http');
const crypto = require('crypto');
const websocket = require('ws');

const server = http.createServer((req, res) => {
  //处理WebSocket握手
  if (req.headers.connection === 'Upgrade' && req.headers.upgrade === 'websocket') {
    const secWebSocketKey = req.headers['sec-websocket-key'];
    const secWebSocketAccept = crypto
      .createHash('sha1')
      .update(secWebSocketKey + '258EAFA5-E914-47DA-95CA-C5AB0DC85B11', 'binary')
      .digest('base64');
    res.writeHead(101, {
      Connection: 'Upgrade',
      Upgrade: 'websocket',
      'Sec-WebSocket-Accept': secWebSocketAccept
    });
    const ws = new websocket.WebSocket({ server: server });
    ws.on('connection', function (socket) {
      console.log('webSocket server connected');
      socket.on('message', function (message) {
        console.log('received: %s', message);
      });
      socket.send('Hello from WebSocket server');
    });
  } else {
    //处理HTTP请求
    res.writeHead(200, { 'Content-Type': 'text/plain' });
    res.end('Hello World\n');
  }
});

server.listen(8080);
console.log('Server running on port 8080.');

在代码中,我们通过http.createServer创建了一个HTTP请求服务,当收到WebSocket请求时,会进入到握手处理逻辑中。

首先取出WebSocket key,生成WebSocket Accept,然后通过res.writeHead设置响应报文头,包括状态码101、Connection和Upgrade字段以及Sec-WebSocket-Accept字段。此外,还需要创建一个websocket对象,该对象监听connection事件,并在连接成功后,处理收到的消息并返回一个问候信息。

Nodejs实现WebSocket的使用示例

在第一个示例中,我们将通过WebSocket连接模拟客户端和服务端之间的聊天,服务端收到客户端发送的消息后,通过WebSocket通道将消息推送给所有已连接的客户端。

服务端代码:

const http = require('http');
const crypto = require('crypto');
const websocket = require('ws');

const server = http.createServer((req, res) => {
  //处理WebSocket握手
  if (req.headers.connection === 'Upgrade' && req.headers.upgrade === 'websocket') {
    const secWebSocketKey = req.headers['sec-websocket-key'];
    const secWebSocketAccept = crypto
      .createHash('sha1')
      .update(secWebSocketKey + '258EAFA5-E914-47DA-95CA-C5AB0DC85B11', 'binary')
      .digest('base64');
    res.writeHead(101, {
      Connection: 'Upgrade',
      Upgrade: 'websocket',
      'Sec-WebSocket-Accept': secWebSocketAccept
    });
    const ws = new websocket.WebSocket({ server: server });
    ws.on('connection', function (socket) {
      console.log('webSocket server connected');
      socket.on('message', function (message) {
        console.log('received: %s', message);
        ws.clients.forEach(client => {
          if (client.readyState === websocket.OPEN) {
            client.send(message);
          }
        });
      });
    });
  } else {
    //处理HTTP请求
    res.writeHead(200, { 'Content-Type': 'text/plain' });
    res.end('Hello World\n');
  }
});

server.listen(8080);
console.log('Server running on port 8080.');

客户端代码:

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>WebSocket Chat Example</title>
  <script>
    let socket;
    function connect() {
      socket = new WebSocket('ws://localhost:8080');
      socket.onopen = function () {
        console.log('WebSocket connection opened.');
      }
      socket.onmessage = function (e) {
        console.log('received: ' + e.data);
        const messages = document.getElementById('messages');
        const message = document.createElement('li');
        message.textContent = e.data;
        messages.appendChild(message);
      }
      socket.onclose = function () {
        console.log('WebSocket connection closed.');
        setTimeout(connect, 1000);
      }
      socket.onerror = function (error) {
        console.log('WebSocket error: ' + error.message);
      }
      const form = document.getElementById('sendForm');
      const input = document.getElementById('messageInput');
      form.addEventListener('submit', e => {
        e.preventDefault();
        socket.send(input.value);
        input.value = '';
      });
    }
    window.addEventListener('load', connect);
  </script>
</head>
<body>
  <ul id="messages"></ul>
  <form id="sendForm">
    <input id="messageInput" type="text"><button>Send</button>
  </form>
</body>
</html>

在客户端启动后,在页面输入框内输入任意内容,再点击发送按钮,消息将被发送到服务端,而服务端收到消息后,会通过WebSocket通道将消息推送给所有已连接的客户端。

第二个示例中,我们将通过WebSocket连接模拟客户端和服务端之间的传输文件,客户端选择文件后,服务端接收文件并保存到本地。

服务端代码:

const http = require('http');
const fs = require('fs');
const crypto = require('crypto');
const websocket = require('ws');
const stream = require('stream');

const server = http.createServer((req, res) => {
  //处理WebSocket握手
  if (req.headers.connection === 'Upgrade' && req.headers.upgrade === 'websocket') {
    const secWebSocketKey = req.headers['sec-websocket-key'];
    const secWebSocketAccept = crypto
      .createHash('sha1')
      .update(secWebSocketKey + '258EAFA5-E914-47DA-95CA-C5AB0DC85B11', 'binary')
      .digest('base64');
    res.writeHead(101, {
      Connection: 'Upgrade',
      Upgrade: 'websocket',
      'Sec-WebSocket-Accept': secWebSocketAccept
    });
    const ws = new websocket.WebSocket({ server: server });
    ws.on('connection', function (socket) {
      console.log('webSocket server connected');
      let writableStream;
      socket.on('message', function (message) {
        if (message instanceof Buffer) {
          if (writableStream) {
            writableStream.write(message);
          }
        } else {
          //收到文件名
          const fileName = message.toString();
          writableStream = fs.createWriteStream(`./files/${fileName}`);
        }
      });
      socket.on('close', function () {
        writableStream.end(() => {
          console.log('file saved successfully');
        });
      });
    });
  } else {
    //处理HTTP请求
    res.writeHead(200, { 'Content-Type': 'text/plain' });
    res.end('Hello World\n');
  }
});

server.listen(8080);
console.log('Server running on port 8080.');

客户端代码:

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>WebSocket File Transfer Example</title>
  <script>
    let socket;
    function connect() {
      socket = new WebSocket('ws://localhost:8080');
      socket.onopen = function () {
        console.log('WebSocket connection opened.');
      }
      socket.onmessage = function (e) {
        console.log('received: ' + e.data);
        if (typeof e.data === 'string') {
          //接收到服务端请求文件内容的消息,开始发送文件
          const file = document.getElementById('file').files[0];
          const reader = new FileReader();
          reader.onload = function (e) {
            const buffer = e.target.result;
            for (let i=0, length=buffer.byteLength; i<length; i+=1024) {
              const chunk = buffer.slice(i, i+1024);
              socket.send(chunk);
            }
          }
          reader.readAsArrayBuffer(file);
          //发送文件名
          socket.send(file.name);
        }
      }
      socket.onclose = function () {
        console.log('WebSocket connection closed.');
      }
      socket.onerror = function (error) {
        console.log('WebSocket error: ' + error.message);
      }
    }
    window.addEventListener('load', connect);
  </script>
</head>
<body>
  <form enctype="multipart/form-data">
    <input id="file" type="file">
  </form>
</body>
</html>

在客户端启动后,选择任意文件,上传文件时,服务端便会接收到文件,并将文件保存到指定目录中。

这便是应用WebSocket实现的两个示例,第一个示例利用WebSocket实现客户端与服务端之间的聊天,第二个示例利用WebSocket实现了文件上传及保存的功能。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Nodejs实现WebSocket代码实例 - Python技术站

(0)
上一篇 2023年6月8日
下一篇 2023年6月8日

相关文章

  • 阿里云ecs服务器中安装部署node.js的步骤

    下面我将详细讲解在阿里云ECS服务器上安装部署Node.js的步骤。本攻略分为以下几步: 升级服务器 安装Node.js 部署Node.js应用 升级服务器 在开始安装Node.js之前,我们需要先升级服务器的软件包和依赖项。在终端中输入以下命令,进行升级: sudo apt-get update sudo apt-get upgrade 注意:以上命令是D…

    node js 2023年6月8日
    00
  • Node.js的进程管理的深入理解

    Node.js 进程管理是 Node.js 一个重要的功能,可以帮助我们更好地管理和控制 Node.js 运行过程中的进程,提高 Node.js 的稳定性和可靠性。在本文中,我们将深入探讨 Node.js 进程管理的相关内容,包括进程的创建、运行、退出,以及一些常用的进程管理方式。 进程的创建 在 Node.js 中,我们可以通过调用 child_proce…

    node js 2023年6月8日
    00
  • npm 常用命令详解(小结)

    下面是对“npm 常用命令详解(小结)”的一个完整攻略。 npm 常用命令详解(小结) npm 是 Node.js 自带的包管理工具,它可以让我们更加方便地管理项目依赖。下面是 npm 常用的几个命令: 初始化项目 首先,我们需要初始化一个新项目,让 npm 来管理我们的依赖: npm init 这个命令会引导你创建一个新的 package.json 文件,…

    node js 2023年6月8日
    00
  • 详解JavaScript树结构

    详解JavaScript树结构 什么是树结构 树结构是一种非常常见的数据结构,它由多个节点(Node)和连接它们的边(Edge)所组成的集合体。其中树的顶部节点被称为根节点(Root),没有子节点的节点称为叶节点(Leaf),除了根节点外,每个节点都有一个父节点(Parent)。 树结构可以被用来表示许多信息,例如文件系统、公司组织架构、网页导航等。 用对象…

    node js 2023年6月8日
    00
  • Lua协同程序coroutine的简介及优缺点

    Lua中的协同程序coroutine是一种特殊的线程,它允许您在相同进程中的不同代码段之间切换执行。与操作系统线程相比,coroutine更加轻量级,且由于没有线程间的切换和锁竞争开销,所以使用coroutine可以有效提高性能。 如何创建一个coroutine 在Lua中,使用函数coroutine.create()可以创建一个coroutine对象,例如…

    node js 2023年6月8日
    00
  • NodeJs Express路由使用流程解析

    下面是关于Node.js Express路由使用流程的完整攻略。 什么是路由? 路由是Web应用中控制URI(或称为URL)请求的一部分。它是基于URL和HTTP方法(如GET、POST、PUT和DELETE)来选择一个处理程序(handler)。 在Node.js中,我们可以使用Express框架来构建Web应用程序,Express可以让我们很方便地处理H…

    node js 2023年6月8日
    00
  • node解析修改nginx配置文件操作实例分析

    针对“node解析修改nginx配置文件操作实例分析”的完整攻略,以下是具体的过程和示例: 1. 准备工作 在开始修改nginx配置文件之前,需要先安装node.js和nginx,并确保已经启动nginx服务。同时,还需安装一些常用的node.js模块: npm install –save fs http url 2. 解析配置文件 首先,我们需要读取ng…

    node js 2023年6月8日
    00
  • node.js中的fs.link方法使用说明

    当我们需要在Node.js中创建一个硬链接时,可以使用fs.link()方法。下面是fs.link()方法的使用说明: fs.link()方法 语法 fs.link(existingPath, newPath, callback) 参数 existingPath:原始文件的路径(包含文件名)。 newPath:硬链接的新路径(包含文件名)。 callback…

    node js 2023年6月8日
    00
合作推广
合作推广
分享本页
返回顶部