1. package main
  2. import "github.com/gin-gonic/gin"
  3. //1.一定要将代码新建到gopath目录之下的src
  4. //2.要记得设置GO111MODULE=off 开始go modules要记得GO111MODULE=on
  5. //3.先查找gopath/src 这个目录之下的包是否有 ->goroot/src目录之下找
  6. //其实就是不做包管理
  7. //包管理 - 异常处理 泛型
  8. //能用go modules 就用modules 不用去考虑以前的开发模式了
  9. //即使你使用了以前的模式 也可以自动设置为现在的modules模式
  10. //go modules是一个统一的做法
  11. func main() {
  12. //fmt.Println("hello go")
  13. //calc.Add(1,2)
  14. r := gin.Default()
  15. r.GET("/ping", func(c *gin.Context) {
  16. c.JSON(200, gin.H{"message": "pong"})
  17. })
  18. r.Run()
  19. }
  20. //package OldPackageTest/calc is not in GOROOT(...)
  21. //Solution:cmd -> go env -> go env -w GO111MODULE=off
  22. //多行申明

calc

  1. package calc
  2. func Add(x, y int) int {
  3. return x + y
  4. }

grpc_test

proto

  1. syntax = "proto3";
  2. //option go_package = ".;proto";
  3. service Greeter {
  4. rpc SayHello (HelloRequest) returns (HelloReply);
  5. }
  6. message HelloRequest {
  7. string name = 1;
  8. }
  9. message HelloReply {
  10. string message = 1;
  11. }

helloworld

client

  1. package main
  2. import (
  3. "fmt"
  4. "net/rpc"
  5. )
  6. func main() {
  7. //1.建立连接
  8. client, err := rpc.Dial("tcp", "localhost:1234")
  9. if err != nil {
  10. panic("连接失败")
  11. }
  12. //var reply *string = new(string)
  13. var reply string
  14. err2 := client.Call("HelloService.Hello", "jeff", &reply)
  15. if err2 != nil {
  16. panic("调用失败")
  17. }
  18. fmt.Println(reply) //0xc00004a0f0
  19. }

server

  1. package main
  2. import (
  3. "net"
  4. "net/rpc"
  5. )
  6. type HelloService struct {
  7. }
  8. func (s *HelloService) Hello(request string, reply *string) error {
  9. //返回值是通过修改reply的值
  10. *reply = "hello, " + request
  11. return nil
  12. }
  13. func main() {
  14. //1. 实例化一个server
  15. listener, err := net.Listen("tcp",":1234")
  16. if err != nil {
  17. return
  18. }
  19. //2. 注册处理逻辑
  20. err2 := rpc.RegisterName("HelloService", &HelloService{})
  21. if err2 != nil {
  22. return
  23. }
  24. //3. 启动服务
  25. conn, err3 := listener.Accept() //当一个新的连接进来的时候,
  26. if err3 != nil{
  27. return
  28. }
  29. rpc.ServeConn(conn)
  30. //一连串的代码大部分都是net的包好像和rpc没关系
  31. //不想 rpc调用中有几个问题需要解决 1.call id 2.序列化和反序列化
  32. //python下的开发而言 这个就显得不好用
  33. //可以跨语言调用 1.go语言的rpc的序列化协议是什么(Gob编码 go特有) 2.能否替换成常见的序列化
  34. }

http_rpc_client

client

  1. package main
  2. func main() {
  3. }

server

  1. package main
  2. import (
  3. "io"
  4. "net/http"
  5. "net/rpc"
  6. "net/rpc/jsonrpc"
  7. )
  8. type HelloService struct {
  9. }
  10. func (s *HelloService) Hello(request string, reply *string) error {
  11. //返回值是通过修改reply的值
  12. *reply = "hello, " + request
  13. return nil
  14. }
  15. func main() {
  16. //1. 实例化一个server
  17. _ = rpc.RegisterName("HelloService", &HelloService{})
  18. http.HandleFunc("/jsonrpc", func(writer http.ResponseWriter, request *http.Request) {
  19. var conn io.ReadWriteCloser = struct {
  20. io.Writer
  21. io.ReadCloser
  22. }{
  23. ReadCloser: request.Body,
  24. Writer: writer,
  25. }
  26. err := rpc.ServeRequest(jsonrpc.NewServerCodec(conn))
  27. if err != nil {
  28. return
  29. }
  30. })
  31. err := http.ListenAndServe(":1234",nil)
  32. if err != nil {
  33. return
  34. }
  35. }

json_rpc_test

client

  1. package main
  2. import (
  3. "fmt"
  4. "net"
  5. "net/rpc"
  6. "net/rpc/jsonrpc"
  7. )
  8. func main() {
  9. //1.建立连接
  10. conn, err := net.Dial("tcp", "localhost:1234")
  11. if err != nil {
  12. panic("连接失败")
  13. }
  14. //var reply *string = new(string)
  15. var reply string
  16. client := rpc.NewClientWithCodec(jsonrpc.NewClientCodec(conn))
  17. err2 := client.Call("HelloService.Hello", "jeff", &reply) //底层是json字符串
  18. if err2 != nil {
  19. panic("调用失败")
  20. }
  21. fmt.Println(reply) //0xc00004a0f0
  22. }
  23. //{"method":"HelloService.Hello", "params":["hello"],"id":0}

server

  1. package main
  2. import (
  3. "net"
  4. "net/rpc"
  5. "net/rpc/jsonrpc"
  6. )
  7. type HelloService struct {
  8. }
  9. func (s *HelloService) Hello(request string, reply *string) error {
  10. //返回值是通过修改reply的值
  11. *reply = "hello, " + request
  12. return nil
  13. }
  14. func main() {
  15. //1. 实例化一个server
  16. listener, err := net.Listen("tcp", ":1234")
  17. if err != nil {
  18. return
  19. }
  20. //2. 注册处理逻辑
  21. err2 := rpc.RegisterName("HelloService", &HelloService{})
  22. if err2 != nil {
  23. return
  24. }
  25. //3. 启动服务
  26. for {
  27. conn, err3 := listener.Accept() //当一个新的连接进来的时候,
  28. if err3 != nil {
  29. return
  30. }
  31. go rpc.ServeCodec(jsonrpc.NewServerCodec(conn))
  32. }
  33. }

new_helloworld

client

  1. package main
  2. import (
  3. "OldPackageTest/new_helloworld/client_proxy"
  4. "fmt"
  5. )
  6. func main() {
  7. //1.建立连接
  8. client := client_proxy.NewHelloServiceClient("tcp", "localhost:1234")
  9. //1.只想写业务逻辑 不想关注每个函数的名称
  10. //客户端部分
  11. //var reply *string = new(string)
  12. var reply string
  13. err2 := client.Hello("jeff", &reply)
  14. if err2 != nil {
  15. panic("调用失败")
  16. }
  17. fmt.Println(reply)
  18. //1.这些概念在grpc中都有对应
  19. //2.发自灵魂的拷问:server_proxy 和 client_proxy 能否自动生成 为多种语言生成
  20. //3.这两个功能都能满足 protobuf + grpc
  21. }

client_proxy

  1. package client_proxy
  2. import (
  3. "OldPackageTest/new_helloworld/handler"
  4. "net/rpc"
  5. )
  6. type HelloServiceStub struct {
  7. *rpc.Client
  8. }
  9. //在go语言中没有类对象 就意味着没有初始化方法
  10. func NewHelloServiceClient(protocol, address string) HelloServiceStub {
  11. conn, err := rpc.Dial(protocol, address)
  12. if err != nil {
  13. panic("connect error!")
  14. }
  15. return HelloServiceStub{conn}
  16. }
  17. func (c *HelloServiceStub) Hello(request string, reply *string) error {
  18. err := c.Call(handler.HelloServiceName+".Hello", request, reply)
  19. if err != nil {
  20. return err
  21. }
  22. return nil
  23. }

handler

  1. package handler
  2. //为了解决命名冲突的问题
  3. const HelloServiceName = "handler/HelloService"
  4. //我们关心的是 NewHelloService 这个名字呢 还是这个结构体中的方法
  5. type NewHelloService struct {
  6. }
  7. func (s *NewHelloService) Hello(request string, reply *string) error {
  8. //返回值是通过修改reply的值
  9. *reply = "hello, " + request
  10. return nil
  11. }

server

  1. package main
  2. import (
  3. "OldPackageTest/new_helloworld/handler"
  4. "OldPackageTest/new_helloworld/server_proxy"
  5. "net"
  6. "net/rpc"
  7. )
  8. func main() {
  9. //1. 实例化一个server
  10. listener, err := net.Listen("tcp", ":1234")
  11. if err != nil {
  12. return
  13. }
  14. //2. 注册处理逻辑 handler
  15. err2 := server_proxy.RegisterHelloService(&handler.NewHelloService{})
  16. if err2 != nil {
  17. return
  18. }
  19. //3. 启动服务
  20. for {
  21. conn, err3 := listener.Accept() //当一个新的连接进来的时候,
  22. if err3 != nil {
  23. return
  24. }
  25. go rpc.ServeConn(conn)
  26. }
  27. }

server_proxy

  1. package server_proxy
  2. import (
  3. "OldPackageTest/new_helloworld/handler"
  4. "net/rpc"
  5. )
  6. type HelloServicer interface {
  7. Hello(request string , reply *string)error
  8. }
  9. //如何做到解耦 - 我们关心的是函数 鸭子类型
  10. func RegisterHelloService(srv HelloServicer) error {
  11. return rpc.RegisterName(handler.HelloServiceName,srv)
  12. }

go.mod

  1. module OldPackageTest
  2. go 1.18
  3. require github.com/gin-gonic/gin v1.6.3
  4. require (
  5. github.com/gin-contrib/sse v0.1.0 // indirect
  6. github.com/go-playground/locales v0.14.0 // indirect
  7. github.com/go-playground/universal-translator v0.18.0 // indirect
  8. github.com/go-playground/validator/v10 v10.10.0 // indirect
  9. github.com/golang/protobuf v1.5.0 // indirect
  10. github.com/json-iterator/go v1.1.12 // indirect
  11. github.com/leodido/go-urn v1.2.1 // indirect
  12. github.com/mattn/go-isatty v0.0.14 // indirect
  13. github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect
  14. github.com/modern-go/reflect2 v1.0.2 // indirect
  15. github.com/stretchr/testify v1.7.1 // indirect
  16. github.com/ugorji/go/codec v1.2.7 // indirect
  17. golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 // indirect
  18. golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069 // indirect
  19. golang.org/x/text v0.3.6 // indirect
  20. google.golang.org/protobuf v1.28.0 // indirect
  21. gopkg.in/yaml.v2 v2.4.0 // indirect
  22. )