分享一個(gè)簡(jiǎn)單的 rpc 服務(wù)框架
一、服務(wù)端實(shí)現(xiàn)文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-846509.html
package main
import (
"log"
"net"
"net/rpc"
)
const HelloServiceName = "main.HelloService"
type HelloServiceInterface interface {
Hello(request string, replay *string) error
}
func RegisterHelloService(svc HelloServiceInterface) error {
//todo 其中 rpc.Register 函數(shù)調(diào)用會(huì)將對(duì)象類(lèi)型中所有滿(mǎn)足 RPC 規(guī)則的對(duì)象方法注冊(cè)為 RPC 函數(shù),所有注冊(cè)的方法會(huì)放在 “HelloService” 服務(wù)空間之下。
return rpc.RegisterName(HelloServiceName, svc)
}
type HelloService struct{}
//todo RPC方法需要滿(mǎn)足的規(guī)則:只能有兩個(gè)可序列化的參數(shù),第二個(gè)參數(shù)表reply是指針類(lèi)型,函數(shù)返回error類(lèi)型,函數(shù)需要大寫(xiě)進(jìn)行公開(kāi)
func (p *HelloService) Hello(request string, reply *string) error {
*reply = "hello:" + request
return nil
}
func main() {
//rpc.RegisterName("HelloService", new(HelloService))
RegisterHelloService(new(HelloService))
//todo 然后我們建立一個(gè)唯一的 TCP 連接,并且通過(guò) rpc.ServeConn 函數(shù)在該 TCP 連接上為對(duì)方提供 RPC 服務(wù)。
listener, err := net.Listen("tcp", ":1234")
if err != nil {
log.Fatal("ListenTCP error:", err)
}
for {
conn, err := listener.Accept()
if err != nil {
log.Fatal("Accept error:", err)
}
//todo 啟動(dòng)協(xié)程去處理每個(gè)tcp請(qǐng)求
go rpc.ServeConn(conn)
}
}
二、客戶(hù)端實(shí)現(xiàn)文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-846509.html
package main
import (
"fmt"
"log"
"net/rpc"
)
const HelloServiceName = "main.HelloService"
type HelloServiceInterface interface {
Hello(request string, replay *string) error
}
type HelloServiceClient struct {
*rpc.Client
}
// todo 在編譯階段檢查 HelloServiceClient 類(lèi)型是否實(shí)現(xiàn)了 HelloServiceInterface 接口。
// TODO 這里將 nil 轉(zhuǎn)換為 *HelloServiceClient 類(lèi)型并賦值給 _(匿名變量),編譯器會(huì)自動(dòng)檢查 HelloServiceClient 是否實(shí)現(xiàn)了接口 HelloServiceInterface 中聲明的所有方法。
// TODO 如果 HelloServiceClient 沒(méi)有實(shí)現(xiàn)接口中的所有方法,這段代碼會(huì)導(dǎo)致編譯失敗,從而在編碼階段就能發(fā)現(xiàn)潛在的問(wèn)題。
var _ HelloServiceInterface = (*HelloServiceClient)(nil)
func DialHelloService(network, address string) (*HelloServiceClient, error) {
c, err := rpc.Dial(network, address)
if err != nil {
return nil, err
}
return &HelloServiceClient{Client: c}, nil
}
func (p *HelloServiceClient) Hello(request string, reply *string) error {
return p.Client.Call(HelloServiceName+".Hello", request, reply)
}
func main() {
client, err := DialHelloService("tcp", "localhost:1234")
if err != nil {
log.Fatal("dialing:", err)
}
var reply string
err = client.Hello("world", &reply)
if err != nil {
log.Fatal(err)
}
fmt.Println(reply)
}
到了這里,關(guān)于Golang 實(shí)現(xiàn)一個(gè)簡(jiǎn)單的 RPC 服務(wù)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!