package main
import "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 calc
func 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 main
import (
"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 main
import (
"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 main
func main() {
}
server
package main
import (
"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 main
import (
"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 main
import (
"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 main
import (
"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_proxy
import (
"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 main
import (
"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_proxy
import (
"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 OldPackageTest
go 1.18
require github.com/gin-gonic/gin v1.6.3
require (
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
)