php+golang grpc客户端和服务端详细案例

2023-11-18

测试环境:win10、centos7.9、php7.4、golang1.17

一、安装 protobuf

  • 1、protoc的源码和各个系统的预编译包 - https://github.com/protocolbuffers/protobuf/releases

  • 2、选择对应的安装文件下载,解压(tips:文件解压的路径最好是英文,无任何特殊字符,包括空格;之前安装es插件时就因为Program
    Files中有个空格,导致安装失败)

在这里插入图片描述

  • 3、添加到环境变量中(win10)
    步骤:电脑 -> 右键 -> 属性 -> 高级系统设置 -> 环境变量 -> 系统变量 -> 选中 [ Path ] -> 编辑 -> 新建 [ copy:D:\ProgramFiles\protoc-3.13.0-win64\bin ] -> 依次确定关闭弹框

在这里插入图片描述

  • 4、查看是否成功安装,查看对应的版本即可
protoc --version    #查看protoc的版本

版本信息打印如下:

libprotoc 3.13.0

二、安装PHP相关扩展(grpc、protobuf)

#安装PECL
wget http://pear.php.net/go-pear.phar
php go-pear.phar

#php版本 < 7
yum install php-pear

#安装grpc、protobuf扩展
pecl install protobuf
pecl install grpc
  • 如果grpc安装不上报错可能是cmake版本原因

方法1,升级camke版本
参考:https://blog.csdn.net/CrystalShaw/article/details/120043042

方法2,降低grpc版本

#可以到pecl选一个版本,http://pecl.php.net/package/gRPC
#如:
pecl install grpc-1.31.1

安装成功后,需要将生成的grpc.so和protobuf.so文件移动到php扩展目录下,并加载到php.ini中,如:

#扩展路径请改为你实际的路径
extension = /www/server/php/74/lib/php/extensions/no-debug-non-zts-20190902/protobuf.so

extension = /www/server/php/74/lib/php/extensions/no-debug-non-zts-20190902/grpc.so
  • 生成grpc_php_plugin
git clone  https://github.com/grpc/grpc
cd grpc
git submodule update --init
mkdir -p cmake/build
cd cmake/build
cmake ../..
make protoc grpc_php_plugin
mv ./grpc_php_plugin /opt/homebrew/bin/

如果是国内服务器,一直安装不成功,其原因众所周知无非就是有些东西需要科学上网
找到项目的.gitmodules文件,这个文件就是子工程的clone path 以及clone的位置:
在这里插入图片描述
我们只需要找到url对应的可访问地址,这里给出两个结局的方案,也是我常用的方案:

1、使用github镜像地址:http://git.what996.com
2、在gitee上找别人fork好的对应项目的地址
这里我们使用第一种,将url的https://github.com换成http://git.what996.com

然后在执行git submodule update --init就ok了

三、生成proto文件和grpc代码

  • 创建文件:hello.proto,内容如下:
syntax = "proto3";
package services;
option go_package = "./;proto";
service Greeter {
  rpc SayHello (HelloRequest) returns (HelloReply);
}
message HelloRequest {
  string name = 1;
}
message HelloReply {
  string message = 1;
  int64 len = 2;
}
  • 生成go语言文件:
#在hello.proto文件目录下执行
protoc -I. --go_out=plugins=grpc:./ ./*.proto

执行成功后会生成一个hello.pb.go文件
在这里插入图片描述

hello.pb.go的包名为proto,后续写服务端和客户端代码需要引入此文件
在这里插入图片描述

  • 编写go服务端代码,server.go:
package main

import (
	"context"
	"fmt"
	"proto" #引入生成的go文件,路径改成你实际的引入路径
	"google.golang.org/grpc"
	"net"
)

// 服务端
var Server = new(server)

type server struct{}

// 业务逻辑
func (s *server) SayHello(ctx context.Context, request *proto.HelloRequest) (*proto.HelloReply, error) {
	res := &proto.HelloReply{
		Message: "hello " + request.Name,
		Len:     101,
	}

	fmt.Print("SayHello成功调用..\r\n")
	return res, nil
}

// 启动rpc的server服务
func (s *server) Start() {
	// 1.实例化server
	g := grpc.NewServer()
	// 2.注册逻辑到server中
	proto.RegisterGreeterServer(g, &server{})
	// 3.启动server
	lis, err := net.Listen("tcp", ":8399")
	if err != nil {
		panic("监听错误:" + err.Error())
	}

	fmt.Print("grpc启动服务成功..\r\n")

	err = g.Serve(lis)
	fmt.Print("err:", err)
	if err != nil {
		panic("grpc服务端运行错误:" + err.Error())
	}

}

func main() {
	Server.Start()
}
  • 编写go客户端代码,client.go:
package main

import (
	"context"
	"fmt"
	"proto" #引入生成的go文件,路径改成你实际的引入路径
	"google.golang.org/grpc"
)

// rpc调用
func clientRpc(body map[string]string) (res *proto.HelloReply, err error) {
	name := body["name"]
	conn, err := grpc.Dial("localhost:8399", grpc.WithInsecure())
	if err != nil {
		return nil, err
	}
	defer conn.Close()
	rpc := proto.NewGreeterClient(conn)
	response, err := rpc.SayHello(context.Background(), &proto.HelloRequest{Name: name})
	if err != nil {
		return nil, err
	}
	return response, nil
}

// 业务代码
func start() {
	body := make(map[string]string)
	body["name"] = "niubi!"
	response, err := clientRpc(body)
	if err != nil {
		fmt.Println("rpc调用失败:", err)
		return
	}
	fmt.Println(response.Message)
}
func main() {
	start()
}
  • 生成php语言文件:
#在hello.proto文件目录下执行
protoc --proto_path=./ --php_out=.. --grpc_out=.. --plugin=protoc-gen-grpc=(这里改成你实际生成grpc_php_plugin的路径) ./*.proto

执行成功后会生成以下几个文件:
在这里插入图片描述

  • 编写php客户端代码,client.php:
<?php

require dirname(__FILE__) . '/vendor/autoload.php';

$hostname = 'localhost:8399';

$client       = new \Services\GreeterClient(
    $hostname, [
    'credentials' => Grpc\ChannelCredentials::createInsecure(),
]
);
$indexRequest = new \Services\HelloRequest();
$indexRequest->setName($name = '测试');
/**
 * @var \Services\HelloReply $response
 */
[$response, $status] = $client->SayHello($indexRequest)->wait();

if ($status->code !== Grpc\STATUS_OK) {
    echo "ERROR: " . $status->code . ", " . $status->details . PHP_EOL;
}

var_export($response->serializeToJsonString());
  • 如果你是第一次使用,还需要配置composer:
#安装grpc扩展包
composer require google/protobuf
composer require grpc/grpc

#将生成的php类文件加载到composer ,注意路径改成你实际的路径
    "autoload":{
        "psr-4":{
            "GPBMetadata\\":"common/grpc/GPBMetadata/",
            "Services\\":"common/grpc/Services/"
        }
    }

# 更新composer配置    
composer update    
  • 启动GRPC服务
#go服务端:
go run server.go 

#go客户端:
go run client.go 

#php客户端:
php  client.php
  • go服务端测试:
    在这里插入图片描述

  • go客户端测试:
    在这里插入图片描述

  • php客户端测试:
    ![在这里插入图片描述](https://img-blog.csdnimg.cn/349c2e2cf1424d4980dbed5d449ba942.png

至此,php+golang grpc客户端和服务端详细案例结束!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

php+golang grpc客户端和服务端详细案例 的相关文章

  • 会话变量从 while 循环发送特定变量

    我有这个简单的while 循环它从 mysql 查询中检索数据并在我的主页上显示几个链接 我想避免使用 php get 函数并将查询字符串添加到我的网址中 我正在考虑使用会话变量 但我需要帮助 而且我很确定这是无法完成的 当访问者单击 wh
  • 如何使用 php __toString

    有什么用途 toString in PHP 例如 我有一个函数 例如 在一个名为 person 的类中 public function construct id name this gt id id this gt name name an
  • wordpressfunctions.php - 为每个帖子类别使用不同的页面模板

    我想连接到 save post 函数 找出帖子所属的类别 然后为每个类别中的帖子分配不同的页面模板 我已经尝试了大约 30 个不同的版本 但都没有成功 有人可以帮我指出正确的方向吗 add action save post assign c
  • 使用 Sendemail 的 HTML 表单

    我不知道问题出在哪里 mail 工作正常 我已经用一个简单的 php 文件对其进行了测试 但我的表单不发送任何电子邮件 HTML section div class wow fadeIn div div class parallax div
  • 正则表达式匹配IP地址[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我是正则表达式的新手 我想使用preg match函数用于查找字符串是否为 IP 地址 例如 string 10 0 0 1 preg m
  • 如何在 Go 中表示可选字符串?

    我希望建模一个可以有两种可能形式的值 不存在或字符串 执行此操作的自然方法是Maybe String or Optional
  • 更改laravel视图页面中的日期格式[重复]

    这个问题在这里已经有答案了 我想更改从数据库获取的日期格式 现在我得到了 2016 10 01 user gt from date 我想更改 laravel 5 3 中的格式 d m y user gt from date gt forma
  • WordPress Loop:如何将每 3 个帖子包装到一个 div 中?

    我正在尝试这个 div div 但这不起作用 谢谢你 感谢各位的支持 我尝试了两种解决方案 但都不起作用 我最终做到了这
  • 如何在 Goji (Golang) 中使用不同的中间件创建单独的路由组?

    我正在使用Goji https github com zenazn goji https github com zenazn goji 并希望定义具有自己的中间件的路由组 例如 下面的所有路径 company应使用 LDAP 身份验证并定义
  • Laravel 4,如何在 Route::controller() 上应用过滤器

    我知道我能做到 Route get foo bar array before gt filter uses gt Controller bar 应用路由一些过滤器 我也知道 Route group 方法 无论如何 如果我想以这种方式定义一个
  • “stream_socket_enable_crypto():对等证书 CN=`gains.nanosupercloud.com' 与共享托管中预期的 CN=`smtp.sendgrid.net' 不匹配”

    我在 laravel 从事邮件工作 我有以下配置 MAIL DRIVER smtp MAIL HOST smtp sendgrid net MAIL PORT 587 MAIL USERNAME MAIL PASSWORD MAIL ENC
  • 取消用户特定的 goroutine [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我有一个应用程序 网络应用程序 允许用户使用 twitter oauth 登录并提供自动推文删除功能 用户登录到 Web 应用程序后
  • 在php mysql排行榜表中显示用户排名?

    我创建了一个测验页面 将登录用户的测验结果存储到排行榜 我有一个名为 Members 的表 其中包含 user 和 quiz score 列 我根据登录用户进行的测验结果打印出排行榜 我在个人资料页面的排行榜中显示特定用户的位置时遇到问题
  • 获取客户在 WooCommerce 中最后订单的产品

    我想获取客户最近一次购买的产品数据或最近一次购买的产品数据 目前我有这个 但数组的结果给了我随机购买的结果 它甚至没有给我已完成购买的数据 它为我提供了暂停购买的详细信息 我在这里需要一些帮助 这是代码 Get the current us
  • 让 PHPUnit 忽略一些事情?

    我有一个 PHPUnit 测试类 我希望在测试运行中忽略它 我知道我可以通过重命名它来做到这一点 以便它的文件名中不包含 测试 一词 但我不想这样做 因为它比我想要的更混乱了源代码控制水域 有人有建议吗 有几个选项phpunit命令可以帮助
  • PHP imagettftext 返回的边界框与渲染的边界框不同

    我正在使用 imagettftext 渲染 PNG 文件 对 imagettftext 的调用返回渲染文本的边界框 但仔细检查后发现 文本的渲染稍微超出了它自己的边界框 边界框是正确的 我检查了图像的像素坐标 但文本位置不正确 它输出这个
  • 如何跨页面播放背景音乐

    我已经读过这个问题 我知道它只能用框架来完成 我真的不想要全站点 AJAX 如何在多个 HTML 页面上播放背景音频 https stackoverflow com questions 4210370 how to play a backg
  • Monolog:如何捕获所有错误和异常

    我错过了一些非常明显的东西 如何让 monolog 记录所有 php 错误 php 用户错误和异常 在使用 monolog 之前 我编写了自己的函数并将其传递给set error handler register shutdown func
  • 使用 Zend 实现 WURFL 时出现错误

    我环顾四周 似乎找不到与我有同样问题的人 希望我没有错过这里的叮当声 我想要获取每个用户的设备浏览器信息 我目前计划在引导程序中执行此操作 遵循我在 PHP 会议上看到的内容 为此我遇到了 http framework zend com m
  • 解决 php 常见冲突的最佳方法:忽略、修复还是其他?

    我正在尝试在 CentOS 6 上的 PHP 5 3 3 上安装 Soap 模块 来自 webtatic PHP 5 6 当我运行 yum 命令时yum install php56w soap要安装它 我收到以下消息 错误 php56w c

随机推荐

  • 正大讲解什么叫国际期货?需要多少本金?

    国际期货是指交易所建立在中国大陆以外的期货交易 以美国 英国 新加坡等交易所内的产品为常见交易期货合约 有些期货合约品种会对国内期货价格变动产生影响 所以国内投资者可以参考国际期货行情进行期货交易 开户没有资金限制 但交易期货要交纳手续费和
  • 32 位的有符号整数的取值范围以及数值溢出

    short int long 是C语言中常用的三种整数类型 分别称为短整型 整型 长整型 在现代操作系统中 short int long 的长度分别是 2 4 4 或者 8 它们只能存储有限的数值 当数值过大或者过小时 超出的部分会被直接截
  • 关于在VM虚拟机下,安装OpenWrt软路由,所遇错误及解决方法。

    首先是去阿里的openwrt源下载的镜像为img格式 vm虚拟无法识别 需要转换为iso格式或者vmdk格式 用软碟通转换iso格式失败 于是准备转换成vmdk格式 网上大部分采用starwindconverter软件 但是最新的版本老是报
  • 数字水印

    数字水印 Digital Watermarking 1 技术是将一些标识信息 即数字水印 直接嵌入数字载体当中 包括多媒体 文档 软件等 或是间接表示 修改特定区域的结构 且不影响原载体的使用价值 也不容易被探知和再次修改 但可以被生产方识
  • Golang笔记:使用http包实现基础WebServer功能

    文章目录 目的 监听请求并响应 请求解析 进行响应 静态文件服务 总结 目的 WebServer是一种非常常用的功能 Golang的高并发特性在处理此类工作中也有较大的优势 同时借助标准库中的 net http 包可以非常快速的编写WebS
  • mysql Specified key was too long; max key length is 767 bytes

    MySQL默认的索引最大长度是767字节 在5 5版本开始后可以通过设置innodb large prefix on来增大索引长度 可达到3072字节 但是只有row format DYNAMIC COMPRESSED的情况下索引的长度才能
  • 系统学Python(一)整数、浮点数、布尔值及类型转换

    整数 int类型数据是整数 正整数或负整数 没有小数 不限制长度 举例1 x 2 print x print type x 用tpye 函数可以查看变量类型 举例2 y 3 print y print type y 自动化QQ交流群 704
  • 常用的几款性能测试软件

    JMeter Apache JMeter是一款免费 开源的性能测试工具 广泛应用于Web应用程序和服务的性能测试 它支持模拟多种不同类型的负载 可以测试应用程序在不同压力下的性能表现 并提供丰富的图表和报告来分析测试结果 优点 免费且开源
  • youtube-dl 中文版帮助文档目录

    选项 常规选项 h help打印此帮助文本并退出 version打印程序版本并退出 U update将此程序更新为最新版本 使 确保您具有足够的权限 如果需要 使用sudo运行 i ignore errors继续出现下载错误 例如 跳过播放
  • JQueryUI如何读取本地文件

    1 设计html界面 这用了两个按钮主要是因为file类型的按钮太丑了 后面跟一个输入框 这里把它隐藏 用下面的按钮激活文件选择对话框
  • Adroid游戏开发实例讲解(四)-电子白板附源码

    Adroid游戏开发实例讲解 四 电子白板附源码 程序之美 电子白板 在很多Android设备中经常会用到 比如说Android电视 触摸屏用上手写笔 轻松在上面写字 比如视频教学Android设备 有很多培训教学机构 都放有Android
  • phpstudy php调试,phpStudy vscode 搭建debug调试的教程详解

    下载地址 Xdebug zend extension D phpstudy pro Extensions php php7 3 4nts ext php xdebug dll xdebug collect params 1 xdebug c
  • 论文:ViT(Transformer 图像分类)

    论文 https arxiv org abs 2010 11929 pytorch代码 https github com lucidrains vit pytorch 不了解Transformer的 建议先看这篇 https blog cs
  • Fiddler实现android手机抓包

    目录 一 fiddler的简介 二 安装fiddler 三 fiddler设置 1 设置HTTPS 2 设置允许远程连接 3 重启fillder 使得配置生效 4 查看端口监听 四 android端设置 1 首先查看电脑的 IP 地址 确保
  • AntDB数据库亮相2023操作系统产业大会,携手合作伙伴共建网信生态

    7月5日 以 麒麟遨天 聚创未来 为题的2023操作系统产业大会在中关村国家自主创新示范区展示交易中心顺利召开 亚信科技作为麒麟软件亲密的合作伙伴受邀参会 AntDB数据库生态负责人在会上进行了 与您携手 共建网信生态 的精彩演讲 与政 产
  • c 十进制数转十六进制

    有3种方式实现 其中两种是使用系统函数 另一种是直接自己编写 使用系统函数实现要加入 include
  • 使用QT纯代码创建(查找)对话框详细步骤与代码

    一 创建项目文件 打开Qt Creator gt 文件 gt 新建文件或项目 gt 选择Qt Widgets Application 为项目起名字 输入类的名字 二 了解每个文件的作用 项目创建完毕之后就会出现以下几个文件 先来分别介绍以下
  • 计算机网络的基本概念

    一 计算机网络的定义 1 计算机网络的定义 计算机网络是互连的 自治的计算机的集合 自治 是指互连的计算机系统彼此独立 不存在主从或者控制与被控制的关系 计算机 计算机设备 互连 是指利用通信链路链接相互独立的计算机系统 2 目前最大的 应
  • form表单数据回填

    前言 我相信很多人在做项目的时候都会碰到数据回填 每当有一个修改页面那么 就逃不掉 可以说修改跟回填是已经牢牢挂钩了 那么这时候有很多小伙伴 就会很头疼了 当我们的页面的form表单需要回填的数据特别特别多的时候 这时候如果还一个一个文本框
  • php+golang grpc客户端和服务端详细案例

    测试环境 win10 centos7 9 php7 4 golang1 17 一 安装 protobuf 1 protoc的源码和各个系统的预编译包 https github com protocolbuffers protobuf rel