WebSocket前后端建立以及使用

1、什么是WebSocket

WebSocket 是一种在 Web 应用程序中实现双向通信的协议。它提供了一种持久化的连接允许服务器主动向客户端推送数据,同时也允许客户端向服务器发送数据,实现了实时的双向通信。 这部分直接说你可能听不懂;我举个例子说他的功能(

  • 比如我们在网站上通过点击用户,然后出现用户的主页这是http请求,通过我们主动点击然后出现页面
  • 然后在网站上有人给我发送了私信消息的时候,我们没有点击任何东西,页面却会跳出提示(xxx发送了一条私信)这是websocket

下面先说一下为什么会出现WebSocket?

2、WebSocket的由来?

平时我们用java或者go等语言去写一些接口,然后前端调用这些接口就能实现数据获取展示等功能,也就是写出来了一个web页面比如:xx书城。但经过观察就发现这种普通的http接口都是要:当前端点击某个位置的时候,主动的发送http请求去后端接口,才能够拿到数据。也可以理解为http如果想知道服务器是否有内容更新就必须一直发请求到服务端去确认,如果服务器没有更新,那这些通信就都是徒劳的。

所以想要实现http协议能够及时探知服务器上是否有内容更新,以下这些http标准就会成为瓶颈

  • 一条连接上只可发送一个请求。
  • 请求只能从客户端开始。客户端不可以接收除响应以外的指令。
  • 请求 / 响应首部未经压缩就发送。首部信息越多延迟越大。
  • 发送冗长的首部。每次互相发送相同的首部造成的浪费较多。
  • 可任意选择数据压缩格式。非强制压缩发送。

后来提出了一种Commet的解决方法,即当客户端发送服务端是否有内容更新的查看请求的时候,服务端就先不回应,当服务器端内有内容更新时,再返回该响应。这是一种通过延迟应答,实现服务器端向客户端推送的功能。但是一次连接持续时间边长会消耗更多的资源,同时 http 的瓶颈也没解决。

后来又提出了SPDY的设计,能实现功能但有一些缺点过于明显

最后后来Websocket就出现了。因为不论用什么技术,只要通信使用的是HTTP协议,那就无法彻底解决瓶颈问题。WebSocket网络技术正实为解决这些问题而实现的一套新协议及API。

WebSocket协议

一旦建立了WebSocket协议的通信连接,之后所有的通信都依靠这个专用协议进行,通信过程可以发json、xml、图片等任意格式的数据。

由于是建立在HTTP基础之上的协议,因此连接的发起方仍是客户端,而一旦确立 WebSocket 通信连接,不论服务器还是客户端,任意一方都可直接向对方发送报文

websocket有推送功能且是长久连接,它的首部信息也小,连接开销以及通信量都减小了很多。

WebSocket连接

接下来就简单实现以下 前端用js,后端用go 语言怎么实现建立websocket连接的,前端和后端使用相同的 URL 来建立 WebSocket 连接是最常见的方式

后端部分

因为想建立连接要先开启服务端做好准备监听,然后等待客户端去发起请求

package main

import (
	"fmt"
	"log"
	"net/http"

	"github.com/gorilla/websocket"
)

// 创建一个 websocket.Upgrader 对象
var upgrader = websocket.Upgrader{
	CheckOrigin: func(r *http.Request) bool {
		// CheckOrigin 函数用于检查请求的来源是否合法,即允许跨域访问
		return true
	},
}

func websocketHandler(w http.ResponseWriter, r *http.Request) {
	// 将 HTTP 连接升级为 WebSocket 连接   //request 参数包含了客户端发起连接时提供的 URL 信息ws://localhost:8088/userid
	conn, err := upgrader.Upgrade(w, r, nil)
	if err != nil {
		log.Println("升级为 WebSocket 连接失败:", err)
		return
	}

	// 读取客户端发送的消息
	for {
		//阻塞式的操作。当调用这个方法时,如果没有接收到新的消息,它将一直阻塞等待,直到收到新的消息或发生错误。
		messageType, p, err := conn.ReadMessage()
		if err != nil {
			log.Println("读取消息失败:", err)
			break
		}

		// 在控制台打印接收到的消息
		log.Printf("接收到消息: %s", p)

		// 构建回复消息
		response := []byte(fmt.Sprintf("接收到消息: %s", p))

		// 通过websocket推送,去回复客户端消息,客户端会及时接收到这份信息
		err = conn.WriteMessage(messageType, response)
		if err != nil {
			log.Println("发送消息失败:", err)
			break
		}
	}

	// 关闭 WebSocket 连接
	err = conn.Close()
	if err != nil {
		log.Println("关闭连接失败:", err)
	}
}

func main() {
	http.HandleFunc("/ws", websocketHandler)
	log.Println("WebSocket 服务器运行在 http://localhost:8000/ws")
	err := http.ListenAndServe(":8088", nil)
	if err != nil {
		log.Fatal("启动服务器失败:", err)
	}
}

前端通过websocket发送给后端的信息就会打印到控制台了

前端部分

前端页面就这样,打开的时候就会自动运行js部分,然后发起连接请求了


<!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>
  <button onclick="onclicked()">发送</button >
    <script>
    	//与本地计算机通信,注意建立的是websocket连接,所以连接的url开头就是ws了
        const ws = new WebSocket('ws://localhost:8088/ws')
        //与其他计算机通信
        //const ws = new WebSocket('ws://服务器地址:端口号')
        function onclicked (){
          ws.send(999);
        }
        ws.onopen = function () {
	        console.log('我们连接成功啦...')
	        ws.send(11);
        }
        ws.onerror = function () {
        	console.log('连接失败了...')
        }
        ws.onmessage = function (e) {
	        console.log('服务端传来数据啦...' + e.data)
        }
        ws.onclose = function () {
        	console.log('连接关闭了...')
        }

    </script>
</body>
</html>

同样,服务端通过websocket推送到前端的控制台中展示

这就是一个简单的websocket应用,下次我会用websocket推送功能去实现一个简单的聊天系统,关注看后续。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/625650.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

nestJs中跨库查询

app.module.ts中配置 模块的module中 注意实体类在写的时候和数据库中的表名一样 service中使用一下

【Cesium解读】Cesium中primitive/entity贴地

官方案例 Cesium Sandcastle Cesium Sandcastle 好文推荐&#xff1a;Cesium贴地设置_primitive贴地-CSDN博客 scene.globe.depthTestAgainstTerrain true; True if primitives such as billboards, polylines, labels, etc. should be depth-tested against the terrain…

【C++】内联函数、auto、范围for

文章目录 1.内联函数2.auto关键字2.1auto简介2.2auto的注意事项2.3auto不能推导的场景 3.基于范围的for循环(C11)4.指针空值nullptr(C11) 1.内联函数 概念&#xff1a; 以inline修饰的函数叫做内联函数&#xff0c;编译时C编译器会在调用内联函数的地方展开&#xff0c;没有函…

CLIPDraw:通过语言-图像编码器探索文本到绘图合成

摘要 本工作介绍了 CLIPDraw&#xff0c;这是一种基于自然语言输入合成新颖绘画的算法。CLIPDraw 不需要任何训练&#xff1b;相反&#xff0c;它使用了一个预先训练好的 CLIP 语言-图像编码器作为衡量标准&#xff0c;以最大化给定描述与生成绘画之间的相似度。关键的是&…

使用XxlCrawler抓取全球航空公司ICAO三字码

目录 前言 一、数据源介绍 1、目标网站 2、页面渲染结构 二、XxlCrawler信息获取 1、创建XxlCrawler对象 2、定义PageVo对象 3、直接PageVO解析 4、自定义解析 总结 前言 长距离旅行或者出差&#xff0c;飞机一定是出行的必备方式。对于旅行达人或者出差人员而言&…

为什么使用AI 在游戏中不犯法

使用AI在游戏中本身并不违法&#xff0c;甚至在很多情况下&#xff0c;游戏公司自己也会在游戏中集成AI来提高游戏体验&#xff0c;例如通过AI驱动的非玩家角色&#xff08;NPC&#xff09;来增加游戏的互动性和挑战性。然而&#xff0c;使用AI是否违法取决于AI的使用方式和目的…

轻松掌握抖音自动点赞技巧,快速吸粉

在当今这个信息爆炸的时代&#xff0c;抖音作为短视频领域的领头羊&#xff0c;不仅汇聚了庞大的用户群体&#xff0c;也成为了品牌和个人展示自我、吸引粉丝的重要平台。如何在众多内容创作者中脱颖而出&#xff0c;实现高效引流获客&#xff0c;精准推广自己的内容&#xff0…

Context Pattern上下文模式

使用情景 全局使用的配置&#xff0c;数据库的连接。MVC中的跨层数据传输携带请求ID&#xff0c;用户信息等用户权限信息线程上下文 跨层数据共享 统一调用参数 携带多个事务需要处理的对象 携带用户信息 使用ThreadLocal

项目-坦克大战-让坦克动起来

为什么写这个项目 好玩涉及到java各个方面的技术 1&#xff0c;java面向对象 2&#xff0c;多线程 3&#xff0c;文件i/o操作 4&#xff0c;数据库巩固知识 java绘图坐标体系 坐标体系-介绍 坐标体系-像素 计算机在屏幕上显示的内容都是由屏幕上的每一个像素组成的像素是一…

drippingblues 靶机实战

信息收集&#xff1a; Nmap: 存活&#xff1a; 靶机ip&#xff1a;192.168.10.110 端口&#xff1a; 服务&#xff1a; 发现ftp服务可以匿名登录。且用户名是FTP。 发现一个压缩包&#xff0c;下载并爆破。 得到密码 072528035。发现关键字 drip。里面还有一个 secret.zip(…

GIT基础01 基础命令与分支

前言 我们知道git是开发中比较常见的版本控制工具 我们可以先提出一个场景: 老板让你去修改方案 第一次修改 打回 第二次修改 打回 第n次修改 老板让你使用第一次的版本 阁下如何应对??? 我对每个版本进行编号?? 是一种方案 但是这里也是有缺陷的 比如说在很多版本中找…

将 Vue、React、Angular、HTML 等一键打包成 macOS 和 Windows 平台客户端应用

应用简介 PPX 基于 pywebview 和 PyInstaller 框架&#xff0c;构建 macOS 和 Windows 平台的客户端。本应用的视图层支持 Vue、React、Angular、HTML 中的任意一种&#xff0c;业务层支持 Python 脚本。考虑到某些生物计算场景数据量大&#xff0c;数据私密&#xff0c;因此将…

odoo16 银行对账单导入改造

解决问题: odoo原生功能的话 是不能在系统上临时处理文件内容的&#xff0c;只会提示文件内容格式不对。 原始文件格式 在头部与尾部 格式问题&#xff0c;例如csv文件和 C53 文件&#xff0c;做一个前置弹框处理数据之后再导入 camt效果: csv效果:

Ajax额

原生Ajax xml 已被json取代 http 请求方法urlhttp版本号 network 谷歌浏览器查看请求报文和响应报文 F12 network header里面有 请求头 响应头 点击view source 可以查看请求响应行 请求体在请求行头下面 get请求有url参数&#xff0c;请求体变为query String…

九、e2studio VS STM32CubeIDE之const修饰BSP函数的形参

目录 一、概述/目的 二、通过串口发送函数对比 2.1 stm32 hal库 VS renesas FSP 2.2 const修改函数形参的作用 2.2.1 值传递-副本 2.2.2 指针传递&#xff08;就近原则&#xff09; 2.2.2.1 const修饰&#xff1a;*P 2.2.2.2 const修饰&#xff1a;指针变量P 2.2.2.3 …

工业物联网解决方案:机房动环监控系统

工业物联网解决方案&#xff1a;机房动环监控系统 工业物联网&#xff08;IIoT&#xff09;作为数字化转型的关键驱动力&#xff0c;正深刻改变着各行各业的运作模式&#xff0c;其中机房动环监控系统是实现智能化运维管理的重要组成部分。该系统通过集成传感器技术、大数据分…

基于51单片机的时钟万年历—可农历显示

基于51单片机的时钟万年历 &#xff08;仿真&#xff0b;程序&#xff0b;原理图&#xff0b;设计报告&#xff09; 功能介绍 具体功能&#xff1a; 1、可以显示年、月、日、时、分、秒、星期、农历&#xff1b; 2、按键可以设置闹钟及报警&#xff1b; 3、按键可以调整时…

Mimikatz安装 lsass进程 SAM NTML

目录 什么是Mimikatz Mimikatz在windows上安装及使用 mimkatz语法 lsass进程 SAM NTML 什么是Mimikatz Mimikatz是一款开源的Windows安全工具&#xff0c;由法国安全研究员Benjamin Delpy开发。它最初被设计为用于学习C语言和进行Windows安全性实验的工具。然而&#xf…

常用地图API平台对比:高德、百度、腾讯、必应、天地图

本文介绍高德、百度、腾讯、必应与天地图等5个地图开发API平台&#xff0c;并对其各自的优势与相对不足加以对比与主观分析。 最近&#xff0c;一些工作需要用到地图开发API方面的内容&#xff1b;在此之前&#xff0c;我还从来没有接触过地图开发相关API的知识与实践&#xff…