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)