package mainimport "github.com/gin-gonic/gin"//1.一定要将代码新建到gopath目录之下的src//2.要记得设置GO111MODULE=off 开始go modules要记得GO111MODULE=on//3.先查找gopath/src 这个目录之下的包是否有 ->goroot/src目录之下找//其实就是不做包管理//包管理 - 异常处理 泛型//能用go modules 就用modules 不用去考虑以前的开发模式了//即使你使用了以前的模式 也可以自动设置为现在的modules模式//go modules是一个统一的做法func main() { //fmt.Println("hello go") //calc.Add(1,2) r := gin.Default() r.GET("/ping", func(c *gin.Context) { c.JSON(200, gin.H{"message": "pong"}) }) r.Run()}//package OldPackageTest/calc is not in GOROOT(...)//Solution:cmd -> go env -> go env -w GO111MODULE=off//多行申明
calc
package calcfunc Add(x, y int) int { return x + y}
grpc_test
proto
syntax = "proto3";//option go_package = ".;proto";service Greeter { rpc SayHello (HelloRequest) returns (HelloReply);}message HelloRequest { string name = 1;}message HelloReply { string message = 1;}
helloworld
client
package mainimport ( "fmt" "net/rpc")func main() { //1.建立连接 client, err := rpc.Dial("tcp", "localhost:1234") if err != nil { panic("连接失败") } //var reply *string = new(string) var reply string err2 := client.Call("HelloService.Hello", "jeff", &reply) if err2 != nil { panic("调用失败") } fmt.Println(reply) //0xc00004a0f0}
server
package mainimport ( "net" "net/rpc")type HelloService struct {}func (s *HelloService) Hello(request string, reply *string) error { //返回值是通过修改reply的值 *reply = "hello, " + request return nil}func main() { //1. 实例化一个server listener, err := net.Listen("tcp",":1234") if err != nil { return } //2. 注册处理逻辑 err2 := rpc.RegisterName("HelloService", &HelloService{}) if err2 != nil { return } //3. 启动服务 conn, err3 := listener.Accept() //当一个新的连接进来的时候, if err3 != nil{ return } rpc.ServeConn(conn) //一连串的代码大部分都是net的包好像和rpc没关系 //不想 rpc调用中有几个问题需要解决 1.call id 2.序列化和反序列化 //python下的开发而言 这个就显得不好用 //可以跨语言调用 1.go语言的rpc的序列化协议是什么(Gob编码 go特有) 2.能否替换成常见的序列化}
http_rpc_client
client
package mainfunc main() {}
server
package mainimport ( "io" "net/http" "net/rpc" "net/rpc/jsonrpc")type HelloService struct {}func (s *HelloService) Hello(request string, reply *string) error { //返回值是通过修改reply的值 *reply = "hello, " + request return nil}func main() { //1. 实例化一个server _ = rpc.RegisterName("HelloService", &HelloService{}) http.HandleFunc("/jsonrpc", func(writer http.ResponseWriter, request *http.Request) { var conn io.ReadWriteCloser = struct { io.Writer io.ReadCloser }{ ReadCloser: request.Body, Writer: writer, } err := rpc.ServeRequest(jsonrpc.NewServerCodec(conn)) if err != nil { return } }) err := http.ListenAndServe(":1234",nil) if err != nil { return }}
json_rpc_test
client
package mainimport ( "fmt" "net" "net/rpc" "net/rpc/jsonrpc")func main() { //1.建立连接 conn, err := net.Dial("tcp", "localhost:1234") if err != nil { panic("连接失败") } //var reply *string = new(string) var reply string client := rpc.NewClientWithCodec(jsonrpc.NewClientCodec(conn)) err2 := client.Call("HelloService.Hello", "jeff", &reply) //底层是json字符串 if err2 != nil { panic("调用失败") } fmt.Println(reply) //0xc00004a0f0}//{"method":"HelloService.Hello", "params":["hello"],"id":0}
server
package mainimport ( "net" "net/rpc" "net/rpc/jsonrpc")type HelloService struct {}func (s *HelloService) Hello(request string, reply *string) error { //返回值是通过修改reply的值 *reply = "hello, " + request return nil}func main() { //1. 实例化一个server listener, err := net.Listen("tcp", ":1234") if err != nil { return } //2. 注册处理逻辑 err2 := rpc.RegisterName("HelloService", &HelloService{}) if err2 != nil { return } //3. 启动服务 for { conn, err3 := listener.Accept() //当一个新的连接进来的时候, if err3 != nil { return } go rpc.ServeCodec(jsonrpc.NewServerCodec(conn)) }}
new_helloworld
client
package mainimport ( "OldPackageTest/new_helloworld/client_proxy" "fmt")func main() { //1.建立连接 client := client_proxy.NewHelloServiceClient("tcp", "localhost:1234") //1.只想写业务逻辑 不想关注每个函数的名称 //客户端部分 //var reply *string = new(string) var reply string err2 := client.Hello("jeff", &reply) if err2 != nil { panic("调用失败") } fmt.Println(reply) //1.这些概念在grpc中都有对应 //2.发自灵魂的拷问:server_proxy 和 client_proxy 能否自动生成 为多种语言生成 //3.这两个功能都能满足 protobuf + grpc}
client_proxy
package client_proxyimport ( "OldPackageTest/new_helloworld/handler" "net/rpc")type HelloServiceStub struct { *rpc.Client}//在go语言中没有类对象 就意味着没有初始化方法func NewHelloServiceClient(protocol, address string) HelloServiceStub { conn, err := rpc.Dial(protocol, address) if err != nil { panic("connect error!") } return HelloServiceStub{conn}}func (c *HelloServiceStub) Hello(request string, reply *string) error { err := c.Call(handler.HelloServiceName+".Hello", request, reply) if err != nil { return err } return nil}
handler
package handler//为了解决命名冲突的问题const HelloServiceName = "handler/HelloService"//我们关心的是 NewHelloService 这个名字呢 还是这个结构体中的方法type NewHelloService struct {}func (s *NewHelloService) Hello(request string, reply *string) error { //返回值是通过修改reply的值 *reply = "hello, " + request return nil}
server
package mainimport ( "OldPackageTest/new_helloworld/handler" "OldPackageTest/new_helloworld/server_proxy" "net" "net/rpc")func main() { //1. 实例化一个server listener, err := net.Listen("tcp", ":1234") if err != nil { return } //2. 注册处理逻辑 handler err2 := server_proxy.RegisterHelloService(&handler.NewHelloService{}) if err2 != nil { return } //3. 启动服务 for { conn, err3 := listener.Accept() //当一个新的连接进来的时候, if err3 != nil { return } go rpc.ServeConn(conn) }}
server_proxy
package server_proxyimport ( "OldPackageTest/new_helloworld/handler" "net/rpc")type HelloServicer interface { Hello(request string , reply *string)error}//如何做到解耦 - 我们关心的是函数 鸭子类型func RegisterHelloService(srv HelloServicer) error { return rpc.RegisterName(handler.HelloServiceName,srv)}
go.mod
module OldPackageTestgo 1.18require github.com/gin-gonic/gin v1.6.3require ( github.com/gin-contrib/sse v0.1.0 // indirect github.com/go-playground/locales v0.14.0 // indirect github.com/go-playground/universal-translator v0.18.0 // indirect github.com/go-playground/validator/v10 v10.10.0 // indirect github.com/golang/protobuf v1.5.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/leodido/go-urn v1.2.1 // indirect github.com/mattn/go-isatty v0.0.14 // indirect github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/stretchr/testify v1.7.1 // indirect github.com/ugorji/go/codec v1.2.7 // indirect golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 // indirect golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069 // indirect golang.org/x/text v0.3.6 // indirect google.golang.org/protobuf v1.28.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect)