grpc代理服务的实现(一)

news2025/2/25 7:21:16

最近公司需要无感知基于服务代号来实现通信, 并监控和管理通信连接,目前公司使用的是如下的逻辑(当然逻辑简化了,但是思想不变)

目录

    • 简单的原理图
    • 代理服务的实现
      • 创建 tls tcp 服务, 用于grpc client 和 grpc service 通信
      • 保存 与 代理服务建立的 grpc service 的连接
      • 保存 grpc client dial 的连接
        • client 连接上了的时候告诉 tcp server, 要连接哪个 grpc service
        • 从 保存的conn 中查询是否有 相关的连接
        • 如果有,则 通过 io.Copy 来让grpc client 与 grpc service 通信
      • 代码地址

简单的原理图

schematic diagram

代理服务的实现

创建 tls tcp 服务, 用于grpc client 和 grpc service 通信

func Run() error {
	// 创建 CA证书 用于 tls 连接
	ca, err := private_keys.NewCA("127.0.0.1")
	if err != nil {
		log.Fatal(err)
	}
	serverCA, err := tls.X509KeyPair(ca.CertPem(), ca.KeyPem())
	if err != nil {
		log.Fatal(err)
	}

	tlsServerConfig := &tls.Config{
		Certificates: []tls.Certificate{serverCA},
	}
    // 创建 带 tls 的tcp服务
	listener, err := tls.Listen("tcp", fmt.Sprintf(":%d", Port), tlsServerConfig)
	if err != nil {
		log.Printf("Error tcp listening on port %d: %v\n", Port, err)
		return err
	}
	fmt.Println("TCP Listening on port ", Port, "; successfully")
	for {
		conn, err := listener.Accept()
		if err != nil {
			log.Printf("Error accepting connection: %v\n", err)
			return err
		}
		fmt.Println("tcp new connection")
		// 处理请求
		go forwardCommunication(conn)
	}
	return nil
}

func forwardCommunication(conn net.Conn) error {
	// 首次连接上的时候,通信告诉 tcp server 是客户端连接还是服务端连接
    bufBytes, err := ReadData(conn)
    if err != nil {
    return err
    }
    device := &Device{}
    err = json.Unmarshal(bufBytes, device)
    if err != nil {
    log.Printf("Error unmarshalling json: %v\n", err)
    return err
    }
}

保存 与 代理服务建立的 grpc service 的连接

func server(deviceID string, conn net.Conn) error {
	sendData, err := json.Marshal(OK{Code: 1})
	if err != nil {
		log.Printf("Error marshalling json: %v\n", err)
		return err
	}
	sendData = append(sendData, '@')
	_, err = conn.Write(sendData)
	if err != nil {
		log.Printf("Error writing to connection: %v\n", err)
		return err
	}
	// 保存 grpc 服务的 dial connect
	setConnMap(deviceID, conn)
	return nil
}

保存 grpc client dial 的连接

client 连接上了的时候告诉 tcp server, 要连接哪个 grpc service
从 保存的conn 中查询是否有 相关的连接
如果有,则 通过 io.Copy 来让grpc client 与 grpc service 通信
func client(deviceID string, conn net.Conn) error {
	toConn := GetConn(deviceID)
	successCode := 0
	if toConn == nil {
		successCode = -1
	}
	sendData, _ := json.Marshal(OK{Code: successCode})
	_, err := conn.Write(append(sendData, MessageEnd))
	if err != nil {
		log.Printf("Error writing to connection: %v\n", err)
	}
	if successCode < 0 {
		conn.Close()
		return err
	}

	go func() {
		_, err := io.Copy(toConn, conn)
		if err != nil {
			log.Printf("client toConn error reading from connection: %v\n", err)
		}
		log.Printf("toConn conn closed.\n")
		return
	}()

	go func() {
		_, err := io.Copy(conn, toConn)
		if err != nil {
			log.Printf("client conn error reading from connection: %v\n", err)
		}
		log.Printf("conn toConn closed.\n")
	}()
	fmt.Println("Client connected to device", deviceID)
	return nil
}

代码地址

https://github.com/wanmei002/websocket-reverse-proxy

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【docker实战】使用代理的坑

在docker公共仓库被封禁的日子里&#xff0c;大多数人更喜欢使用镜像仓库代理源。 网上教程一大把&#xff0c;似乎不使用代理&#xff0c;就不会使用docker一样。 上图就是我设置的代理源镜像仓库。通常是设置/etc/docker/daemon.json这个文件实现的。 这样设置之后&#xff0…

李永乐线代笔记

线性方程组 解方程组的变换就是矩阵初等行变换 三秩相等 方程组系数矩阵的行秩列秩&#xff0c;线性相关的问题应求列秩&#xff0c;但求行秩方便 齐次线性方程组 对应向量组的线性相关&#xff0c;所以回顾下线性相关的知识&#xff1a; 其中k是x&#xff0c;所以用向…

django.db.utils.NotSupportedError: MySQL 8 or later is required (found 5.7.33).

django.db.utils.NotSupportedError: MySQL 8 or later is required (found 5.7.33). 一、原因分析 在新版的Django默认需要MySQL 8或更高版本&#xff0c;才能运行。 二、解决办法 1、升级mysql数据库版本 只需要将mysql版本升级到8.0&#xff0c;即可解决&#xff0c;当然这…

达梦导入导出

针对导出数据库表结构通常有 3 种方法&#xff1a; 使用 DTS 导出 打开 DTS 迁移工具&#xff0c;选择【DM-->SQL】并链接到数据库中&#xff0c;如下图所示&#xff1a; 添加定义脚本&#xff0c;并选择【迁移范围】&#xff08;仅迁移对象定义&#xff09;&#xff0c;如…

202478读书笔记|《人间小满》——小满,才是最好的人生状态,养身先养心,知世故而不世故,历圆滑而弥天真

202478读书笔记|《人间小满》——小满&#xff0c;才是最好的人生状态&#xff0c;养身先养心&#xff0c;知世故而不世故&#xff0c;历圆滑而弥天真 一、画出世俗的欢喜&#xff0c;过一种平淡自由的人生二、与时舒卷&#xff0c;抵岁月荒唐三、一半是海水&#xff0c;一半是…

帕金森的锻炼方式

帕金森病&#xff0c;这个看似陌生的名词&#xff0c;其实离我们并不遥远。它是一种常见的神经系统疾病&#xff0c;影响着许多中老年人的生活质量。虽然帕金森病目前尚无根治之法&#xff0c;但通过科学合理的日常锻炼&#xff0c;可以有效缓解病情&#xff0c;提高生活质量。…

【中台】数字中台整体建设技术方案(doc原件获取)

1. 中台概念 2. 推动企业组织模式演进 3. 建设方法 4 .中台内容 5. 数据安全体系 中台内容围绕数据中台建设评估、整体框架、数据采集&#xff0c;结构化、半结构化、非结构化的数据采集&#xff0c;数据计算能力、存储计算引擎、数据架构、数据挖掘、各种不同数据层建设、模型…

一款不写代码的开源爬虫工具!!【送源码】

爬虫&#xff0c;也被称为网络爬虫或网络蜘蛛&#xff0c;是一种自动化的网络机器人&#xff0c;其主要功能是按照一定的规则&#xff0c;自动浏览互联网并从网页中提取信息。 作为一个开发人员&#xff0c;相信大家都尝试过写一些爬虫&#xff0c;合理的利用一些爬虫工具&…

异或运算在面试题中的应用

异或运算 是 涉及到数据位运算时常见的处理方式。如何进行异或运算&#xff1f;在对应位上&#xff0c;相同为0&#xff0c;不同1&#xff0c;但其实两个数据异或运算就是进行无进位加法。 例如&#xff1a; int a 7, b 6, a ^b ? 算法1: 相同为0&#xff0c;不同为1 a …

和鲸科技携手浙江大学地球科学学院,助推地球科学研究范式变革

近日&#xff0c;浙江省资源与环境信息系统重点实验室&#xff08;下简称“实验室&#xff09;与上海和今信息科技有限公司&#xff08;下简称“和鲸科技”&#xff09;签订合作框架协议&#xff0c;双方将以助推“数据算力模型科研场景”的地球科学研究范式变革&#xff0c;孕…

BFD(简单配置实验)

实验拓扑 配置接口IP地址 正常互通 配置静态BFD 查看状态&#xff1a;为UP 与静态路由联动 查看静态路由状态为active 将交换机的接口down掉 BFD的状态为down 再次查看静态路由的状态为Inactive

阿里云运维第一步(监控):开箱即用的监控

作者&#xff1a;仲阳 这是云的时代&#xff0c;现在云计算已经在各行各业广泛的应用。但是上云对于大多数客户来说&#xff0c;依然有很大的学习成本&#xff0c;如下图仅是阿里云都有几百款产品&#xff0c;怎么选择&#xff1f;怎么用&#xff1f;对于客户来说都是问题。“…

后端常见问题解答-位运算实际场景讲解

位运算 在计算机存储的世界中&#xff0c;一切都是二进制的&#xff0c;位运算就是对二进制位进行操作的一种运算。位运算是计算机中的一种常见运算&#xff0c;可以用来提高性能和提升代码的可读性。 位运算有很多种&#xff0c;比如与、或、非、异或等&#xff0c;这些运算…

【踩坑】解决运行一段时间GPU计算后忽然变得很慢

转载请注明出处&#xff1a;小锋学长生活大爆炸[xfxuezhagn.cn] 如果本文帮助到了你&#xff0c;欢迎[点赞、收藏、关注]哦~ 目录 发现问题 问题分析 修复思路 思路一 思路二 思路二对应代码 这个问题真的找了我好久&#xff0c;但说起来其实也简单&#xff0c;就是GPU温…

XILINX 7系列XDMA使用_IP核介绍以及工程搭建

文章目录 一、XDMA IP核1.1、接口说明1.2、配置页说明 二、XDMA工程搭建2.1、BD搭建2.2 Linux下XDMA驱动安装2.3 Linux下使用XDMA进行数据传输 一、XDMA IP核 1.1、接口说明 sys_clk&#xff1a;主机给PCIE提供的时钟信号&#xff0c;通过原理图查看 sys_rst_n&#xff1a;主机…

Flowable工作流中会签节点处理回退并清除审批意见

文章目录 1&#xff0c;操作方法及步骤2&#xff0c;实现细节3&#xff0c;总结 1&#xff0c;操作方法及步骤 在Flowable工作流会签流程中&#xff0c;如果最后一个人选择回退流程&#xff0c;想要清除前面用户A和B填写的审批意见&#xff0c;需要通过Flowable提供的API来操作…

LVS_Director + KeepAlived + 邮件报警

目录 一. 环境准备 二. 对master和backup操作 三. 配置master主机 四. 配置backup主机 六. 验证虚拟IP 七. 配置后端两个web服务器 对web1和web2主机都进行如下操作&#xff1a; 单独修改web1主机 单独修改web2主机 验证 八. 设置邮件报警 一. 环境准备 KeepAlive…

【CT】LeetCode手撕—102. 二叉树的层序遍历

目录 题目1-思路2- 实现⭐102. 二叉树的层序遍历——题解思路 3- ACM实现3-1 二叉树构造3-2 整体实现 题目 原题连接&#xff1a;102. 二叉树的层序遍历 1-思路 1.借助队列 Queue &#xff0c;每次利用 ①while 循环遍历当前层结点&#xff0c;②将当前层结点的下层结点放入 …

[大模型]Qwen2-7B-Instruct 接入 LangChain 搭建知识库助手

环境准备 在 autodl 平台中租赁一个 3090 等 24G 显存的显卡机器&#xff0c;如下图所示镜像选择 PyTorch–>2.1.0–>3.10(ubuntu20.04)–>12.1 接下来打开刚刚租用服务器的 JupyterLab&#xff0c;并且打开其中的终端开始环境配置、模型下载和运行 demo。 pip 换源…