前端(二十一)——WebSocket:实现实时双向数据传输的Web通信协议_前端websocket-程序员宅基地

技术标签: 1024程序员节  网络  前端  网络协议  javascript  开发语言  

在这里插入图片描述

博主:小猫娃来啦
文章核心:WebSocket:实现实时双向数据传输的Web通信协议

前言

在当今互联网时代,实时通信已成为很多应用的需求。为了满足这种需求,WebSocket协议被设计出来。WebSocket是一种基于TCP议的全双工通信协议,通过WebSocket,Web应用程序可以与服务器建立持久的连接,实现实时双向数据输,提供极低的延迟和高效的数据传输。


WebSocket原理

  • HTTP请求-响应协议

在理解WebSocket原理之前,我们需要了解HTTP请求-响应协议。HTTP是一种无状态的请求-响应协议,客户端通过发送HTTP请求到服务器,服务器接收并处理请求,并返回HTTP响应给客户端。但是,在传统的HTTP协议中,客户端只能发送请求,而服务器只能通过响应来处理客户端的请求。

  • WebSocket协议

WebSocket协议是在HTTP协议的基础上进行扩展的。在建立WebSocket连接时,客户端首先发送一个HTTP请求到服务器,并将Upgrade头部字段设置为"websocket",表示希望升级到WebSocket协议。服务器接收到这个请求后,如果支持WebSocket协议,会返回一个状态码101 Switching Protocols的HTTP响应,并通过Upgrade头部字段将连接升级为WebSocket连接。

升级完成后,客户端和服务器之间的通信不再遵循HTTP请求-响应模式,而是通过WebSocket协议进行双向的实时通信。客户端和服务器可以直接发送消息给对方,不需要等待对方的请求。


如何使用WebSocket

建立WebSocket连接:

要建立WebSocket连接,需要在客户端和服务器之间进行系列的握手操作。下面是详细的代码教程,示了如何在Web应用程序中建立WebSocket连接。

在户端(JavaScript):

// 创建WebSocket对象并指定服务器地址
var socket = new WebSocket("ws://example.com/socket");

// 监听连接建立事件
socket.onopen = function() {
    
  console.log("WebSocket连接已建立");
  // 在连接建立后,可以发送消息到服务器
  socket.send("Hello Server!");
};

// 监听接收到服务器发送的消息
socket.onmessage = function(event) {
    
  var message = event.data;
  console.log("接收到服务器发送的消息:" + message);
};

// 监听连接关闭事件
socket.onclose = function(event) {
    
  console.log("WebSocket连接已关闭");
};

// 监听连接错误事件
socket.onerror = function(event) {
    
  console.error("WebSocket连接错误:" + event};

在服务器端(示例使用Node.js):

const WebSocket = require("ws");

// 创建WebSocket服务器
const wss = new WebSocket.Server({
     port: 8080 });

// 监听连接建立事件
wss.on("connection", function(socket) {
    
  console.log("WebSocket连接已建立");

  // 监听接收到客户端发送的消息
  socket.on("message", function(message) {
    
    console.log("接收到户端发送的消息:" + message);

    // 向客户端发送消息
    socket.send("Hello Client!");
  });

  // 监听连接关闭事件
  socket.on("close", function() {
    
    console.log("WebSocket连接已关闭");
  });
});

在以上代码中,客户端通过创建WebSocket对象,并指定服务器地址"ws://example.com/socket"来建立WebSocket连接。同时,客户端通过监听onopen事件,可以在连接建立后发送消息到服务器。服务器端使用WebSocket.Server类创建WebSocket服务器,并监听"connection事件来处理连接建立后的操作。服务器端通过socket.on(“message”)来监听接收到客户端发送的消息,并通过socket.send()向客户端发送消息。

数据传输:

建立WebSocket连接后,客户端和服务器可以通过WebSocket对象进行双向的实时数据传输。下面是一个示例代码,演示了如何在客户端和服务器之间进行数据传输。

在客户端(JavaScript):

// 发送消息到服务器
socket.send("Hello Server!");

// 监听接收到服务器发送的消息
socket.onmessage = function(event) {
    
  var message = event.data;
  console.log("接收到服务器发送的消息:" + message);
};

在服务器端(示例使用Node.js):

// 向客户端发送消息
socket.send("Hello Client!");

// 监听接收到客户端发送的消息
socket.on("message", function(message) {
    
  console.log("接收到客户端发送的消息:" + message);
});

在以上代码中,客户端通过调用socket.send()方法将消息发送到服务器,服务器通过socket.send()方法将消息发送到客户端。客户端通过监听socket.onmessage事件来接收服务器发送的消息,服务器通过监听socket.on("message")事件来接收客户端发送的消息。

通过以上代码示例,你可以详细了解如何使用WebSocket建立连接并进行数据传输。请注意,示例代码中使用的服务器地址和端口号需要根据实际情况进行修改。同时,你还可以在具体应用中根据需要使用WebSocket的其他方法和事件来实现更复杂的功能。


WebSocket的真实使用场景

即时通讯:

WebSocket非常适合用于即时通讯应用,因为它能够实现实时双向通信。以下是一个简单的即时聊天应用的代码教程。

在客户端(JavaScript):

// 创建WebSocket对象并指定服务器地址
var socket = new WebSocket("ws://example.com/socket");

// 监听连接建立事件
socket.onopen = function() {
    
  console.log("WebSocket连接已建立");
  
  // 监听文本框输入,按下Enter键时发送消息
  var input = document.getElementById("input");
  input.addEventListener("keyup", function(event) {
    
    if (event.keyCode === 13) {
    
      var message = input.value;
      socket.send(message);
      input.value = "";
    }
  });
};

// 监听接收到服务器发送的消息
socket.onmessage = function(event) {
    
  var message = event.data;
  console.log("接收到服务器发送的消息:" + message);

  // 将接收到的消息显示在聊天窗口中
  var chatWindow = document.getElementById("chatWindow");
  chatWindow.innerHTML += "<p>" + message + "</p>";
};

// 监听连接关闭事件
socket.onclose = function(event) {
    
  console.log("WebSocket连接已关闭");
};

// 监听连接错误事件
socket.onerror = function(event) {
    
  console.error("WebSocket连接错误:" + event};

在服务器端(示例使用Node.js):

const WebSocket = require("ws");

// 创建WebSocket服务器
const wss = new WebSocket.Server({
     port: 8080 });

// 监听连接建立事件
wss.on("connection", function(socket) {
    
  console.log("WebSocket连接已建立");

  // 监听接收到客户端发送的消息
  socket.on("message", function(message) {
    
    console.log("接收到客户端发送的消息:" + message);

    // 向所有连接的客户端发送消息
    wss.clients.forEach(function(client) {
    
      client.send(message);
    });
  });

  // 监听连接关闭事件
  socket.on("close", function() {
    
    console.log("WebSocket连接已关闭");
  });
});

在上述代码中,客户端通过创建WebSocket对象连接到服务器。输入框中的文本框用于录入要发送的消息,按下Enter键时会将消息发送给服务器。服务器接收到消息后,通过遍历所有连接的客户端,向每个客户端发送消息。

这样,多个客户端就可以实时地进行聊天,并且所有的消息都会实时地在各个客户端之间同步显示。

多人协作:

WebSocket还可用于多人协作应用,让多个用户可以实时地协同编辑文档或画布。以下是一个简单的代码教程。

在客户端(JavaScript):

// 创建WebSocket对象并指定服务器地址
var socket = new WebSocket("ws://example.com/socket");

// 监听连接建立事件
socket.onopen = function() {
    
  console.log("WebSocket连接已建立");

  // 监听文本框输入,按下Enter键时发送绘画指令
  var canvas = document.getElementById("canvas");
  canvas.addEventListener("mousedown", function(event) {
    
    // 绘画指令的数据格式可以自定义,这里使用了简单的示例
    var instruction = {
    
      type: "draw",
      position: {
    
        x: event.clientX,
        y: event.clientY
      }
    };
    socket.send(JSON.stringify(instruction));
  });
};

// 监听接收到服务器发送的消息
socket.onmessage = function(event) {
    
  var message = JSON.parse(event.data);
  console.log("接收到服务器发送的消息:" + message);

  // 根据消息执行相应的操作,示例中处理了绘画指令
  if (message.type === "draw") {
    
    var canvas = document.getElementById("canvas");
    var ctx = canvas.getContext("2d");
    ctx.beginPath();
    ctx.arc(message.position.x, message.position.y, 5, 0, 2 * Math.PI);
    ctx.fill();
  }
};

// 监听连接关闭事件
socket.onclose = function(event) {
    
  console.log("WebSocket连接已关闭");
};

// 监听连接错误事件
socket.onerror = function(event) {
    
  console.error("WebSocket连接错误:" + event};

在服务器端(示例使用Node.js):

const WebSocket = require("ws");

// 创建WebSocket服务器
const wss = new WebSocket.Server({
     port: 8080 });

// 监听连接建立事件
wss.on("connection", function(socket) {
    
  console.log("WebSocket连接已建立");

  // 监听接收到客户端发送的消息
  socket.on("message", function(message) {
    
    console.log("接收到客户端发送的消息:" + message);

    // 向所有连接的客户端发送消息
    wss.clients.forEach(function(client) {
    
      client.send(message);
    });
  });

  // 监听连接关闭事件
  socket.on("close", function() {
    
    console.log("WebSocket连接已关闭");
  });
});

在上述代码中,客户端通过创建WebSocket对象连接到服务器。当鼠标在画布上按下时,将绘画指令发送给服务器。服务器接收到绘画指令后,将指令广播给所有连接的客户端,并在各个客户端上进行绘画操作。

这样,多个用户就可以实时地协同编辑同一个画布或文档,所有的绘画指令都会即时同步在各个客户端之间。

实时数据更新:

WebSocket还可以用于实时数据更新应用,例如股票交易应用中的实时股票价格更新。以下是一个简单的代码教程。

在客户端(JavaScript):

// 创建WebSocket对象并指定服务器地址
var socket = new WebSocket("链接");

// 监听连接建立事件
socket.onopen = function() {
    
  console.log("WebSocket连接已建立");
};

// 监听接收到服务器发送的消息
socket.onmessage = function(event) {
    
  var message = JSON.parse(event.data);
  console.log("接收到服务器发送的消息:" + message);

  // 对接收到的实时数据进行处理
  var stockPriceElement = document.getElementById("stockPrice");
  stockPriceElement.innerText = message.price;
};

// 监听连接关闭事件
socket.onclose = function(event) {
    
  console.log("WebSocket连接已关闭");
};

// 监听连接错误事件
socket.onerror = function(event) {
    
  console.error("WebSocket连接错误:" + event};

在服务器端(示例使用Node.js):

const WebSocket = require("ws");

// 创建WebSocket服务器
const wss = new WebSocket.Server({
     port: 8080 });

// 模拟实时股票价格更新
setInterval(function() {
    
  var stockPrice = Math.random() * 100;
  
  // 向所有连接的客户端发送实时数据
  wss.clients.forEach(function(client) {
    
    var data = {
    
      price: stockPrice
    };
    client.send(JSON.stringify(data));
  });
}, 2000);

// 监听连接建立事件
wss.on("connection", function(socket) {
    
  console.log("WebSocket连接已建立");
 
  // 初始化发送实时数据
  var stockPrice = Math.random() * 100;
  var data = {
    
    price: stockPrice
  };
  socket.send(JSON.stringify(data));

  // 监听连接关闭事件
  socket.on("close", function() {
    
    console.log("WebSocket连接已关闭");
  });
});

在上述代码中,客户端通过创建WebSocket对象连接服务器。服务器使用setInterval函数模拟实时股票价格的更新,并将更新的数据发送给所有连接的客户端。客户端监听接收到服务器发送的消息,并处理接收到的实时数据。

这样,在股票交易应用中,多个用户可以实时地接收和显示股票价格的更新信息。包括打游戏的时候,队友之间互相沟通,打字交流,或者走位,放技能等等,都是即时的。


WebSocket的优势与局限性

  • WebSocket的优势:
  • 双向实时通信:WebSocket提供了双向的实时信能力,客户端和服务器可以通过该协议进行双向数据传输,实时反馈更新信息,实现即时通讯、实时数据推送等功能。

  • 较低的延迟:与传统的HTTP请求相比,WebSocket降低了通信的开销,减少了传输和处理数据的延迟,因此可以更快进行实时数据传输。

  • 更高的性能:由于WebSocket使用较少的头部信息和更有效的消息传输格式,因此在相同带宽下可以传输更多的数据,提高了性能和效率。

  • 广泛的浏览器支持:WebSocket是HTML5的一部分,并且得到了大多数现代浏览器的支持,因此它可以在各种平台和设备上使用。

  • 连接保持:与传统的HTTP请求不同,WebSocket连接保持在建立之后,双方可以随时进行数据传输,避免了不必要的连接和断开操作。

  • WebSocket的局限性:
  • 兼容性问题:虽然现代浏览器广泛支持WebSocket,但在某些旧版本或特定设备上可能存在兼容性问题。为了兼容性,可以使用轮训技术(如长轮询)作为备选方案。

  • 部署和维护复杂性:WebSocket服务器的设置和配置可能比传统的Web服务器复杂一些,需要专门的服务器环境和配置。

  • 安全性问题:由于WebSocket是在HTTP协议的基础上建立的,它们共享相同的安全风险,例如跨站点脚本(XSS)和跨站请求伪造(CSRF)。因此,在使用WebSocket时需要考虑到安全性,并采取适当的安全措施。

  • 扩展问题:WebSocket协议还不支持像HTTP/2那样的一些高级特性,例如头部压缩和流量控制。在某些特殊情况下,可能需要通过其他方式实现这些功能。

尽管WebSocket具有上述局限性,但它仍然是实时通讯、实时数据传输和实时协作等场景下的首选协议,因为它具备了双向实时通信和较低延迟等一系列的优势。在开发时,需要根据具体需求和限制,综合考虑使用WebSocket的适用性。


结论

WebSocket是一种能够提供双向实时通信的协议,适用于需要实时数据传输和双向通信的场景。它具有较低的延迟、更高的性和广泛的浏览器持等优势,能够实现即时通讯、多人协和实时数据更新等功能。

然而,WebSocket也存在兼容性、部署和维护复杂性、安全性问题以及缺乏一些高级特性等局限性。在开发时,需要仔细考虑具体需求和限制,并必要时采取适当的解决方案。

总的来说,WebSocket在实时通信和实时数据传输方面具有明显的优势,是构建现代Web应用的重要工具之一。

在这里插入图片描述


版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/dyk11111/article/details/133915426

智能推荐

计算机组成原理(第3版)唐朔飞著 知识点总结 第十章控制单元的设计_计算机组成原理(第3版)唐朔飞-程序员宅基地

文章浏览阅读631次。计算机组成原理(第3版)唐朔飞著 知识点总结 第十章 控制单元的设计第十章 控制单元的设计其他章内容在这里汇总链接第十章 控制单元的设计组合逻辑设计:硬件、快微程序设计:软件微指令的基本格式:(1)操作控制字段(2)顺序控制字段:可指出下地址微指令的编码方式:(1)直接编码方式(2)字段直接编码方式(3)字段间接编码方式(4)混合编码(5)其他…2种微指令格式(1)水平型微指令:简单(2)垂直型微指令:复杂 毫微程序看作是解释微程序的动态微程序设计和静态微程序设_计算机组成原理(第3版)唐朔飞

计网一些关键知识点_计网报文传输多少次会被丢弃-程序员宅基地

文章浏览阅读988次,点赞2次,收藏6次。计网_计网报文传输多少次会被丢弃

【路径规划】基于matlab学校算法栅格地图机器人路径规划【含Matlab源码 2833期】_matlab路径规划-程序员宅基地

文章浏览阅读608次。学校算法栅格地图机器人路径规划完整的代码,方可运行;可提供运行操作视频!适合小白!_matlab路径规划

mysql 报错 key column_MySQL ERROR "** syntax to use near 'USING BTREE,KEY `Email` (`Email`) USING BTRE...-程序员宅基地

文章浏览阅读512次。报错:[Err] 1064 – You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ‘USING BTREE,KEY `Email` (`Email`) USING BTREE分析问题..._mysql 1064 use near using btree

TCP/UDP客户端服务器实现通信_可以用udp客户端与tcp服务器连接吗-程序员宅基地

文章浏览阅读2.3k次,点赞5次,收藏11次。TCP/UDP实现编程TCP服务器与客户端的连接过程:客户端与服务器三次握手是在accept和connect之后建立的。三次握手的过程:A-->B 发送SYNB->A 确认发一个ACK,再发一个SYNA->B 确认发一个ACK四次挥手过程:A---->B 发FINB----->A 发ACK(注意:此时,A--->B_可以用udp客户端与tcp服务器连接吗

手把手教你完成Android期末大作业(多功能应用型APP)_安卓大作业-程序员宅基地

文章浏览阅读7.6w次,点赞137次,收藏1.4k次。前言Android期末作业,估摸着也花了整整5天。里面可能会缺少某些细节,如果跟着做有不会的评论就行,每天都会看,尽力解答。功能待办专注计时音乐天气实现步骤一、底部菜单栏切换页1.添加依赖dependencies { implementation 'com.google.android.material:material:1.2.1'}2.在res资源文件夹下新建一个menu文件夹,创建底部导航的菜单布局文件创建对应数量的item,为每个菜单栏选项给每个item定_安卓大作业

随便推点

linux设置双屏拼接_单屏 VS 双屏:谁才是完美的显示器解决方案?-程序员宅基地

文章浏览阅读1.1k次。双屏显示器是目前很多朋友组建显示器的方案,相比单个显示器来说,双屏显示器可以呈现更多的内容,进而带来工作效率或者视觉体验的大幅提升,相信凡是用过双屏显示器的朋友都会有所感触。尽管双屏显示器有着诸多好处,但是如果双屏显示器选择、搭配不当反而会适得其反,带来不必要的麻烦,比如下面这几个问题:1、色彩差异突出双屏显示器无法保证色彩统一多屏显示器拼接时首当其冲的就是色差问题,即使是同型号的显示器,也会因为..._linux x-display 多屏

CentOS下Redis6.x安装教程_centos安装redis6-程序员宅基地

文章浏览阅读714次。Redis6.x安装详细说明_centos安装redis6

Audio CODEC 基本知识及应用_audio 中的codec-程序员宅基地

文章浏览阅读5.8k次。一、Codec字面上的意思就是编解码器,是bai编码器encoder与解码器decoder的混合体,软件层面来说,音频编解码器就是根据特定的音频文件格式或流媒体格式、对数字音频数据实现压缩/解压缩的计算机程序.在硬件层面,音频编解码器指一个能编码模拟音频到数字音频和解码数字音频到模拟音频的独立设备。换种说法,它包含运行在同样时钟的模数转换器(ADC)和数模转换器(DAC)。这在声卡中被使用以支持音频输入和输出。Codec里面包含了I2S接口、D/A、A/D、Mixer、PA(功放),通常包含多种输入_audio 中的codec

${pageContext.request.contextPath}-程序员宅基地

文章浏览阅读72次。这表示的是一个全路径,在我们的Dynamic Web Project中,我们的java文件和jsp文件不在同一个目录下,在jsp向servlet跳转时,会报404错误。当在/servlet前加上${pageContext.request.contextPath}这个全路径时,就会很好的解决这个问题。希望对大家有帮助。转载于:https://www.cnblogs.com/zgybk/..._${pagecontext.request.contextpath}/servlet

WebView 加载失败(net::ERR_CLEARTEXT_NOT_PERMITTED)/ 网络图片无法加载_wpf webview加载失败状态-程序员宅基地

文章浏览阅读616次。问题:WebView 加载失败(net::ERR_CLEARTEXT_NOT_PERMITTED)原因:从Android 9.0(API级别28)开始,默认情况下限制了明文流量的网络请求,对未加密流量不再信任,直接放弃请求,因此http的url均无法在webview中加载,https 不受影响。解决方案:// AndroidManifest.xml 声明网络权限<uses-per..._wpf webview加载失败状态

cf的游戏服务器在哪些位置,cf游戏服务器架构-程序员宅基地

文章浏览阅读1.4k次。cf游戏服务器架构 内容精选换一换查询云服务器组详情。GET /v2.1/{project_id}/os-server-groups/{server_group_id}参数说明请参见表1。参数说明参数是否必选描述project_id是项目ID。获取方法请参见获取项目ID。server_group_id是弹性云服务器组UUID。无响应参数如表2所示。请参考通用请求返回值。服务器安装上架、服务器基础参..._cf服务器