Golang實現自己的RPC框架

2021-10-21 05:55:34 字數 4966 閱讀 5148

rpc/session.go

package rpc

import (

"encoding/binary"

"io"

"net"

)// 編寫資料會話中讀寫

// 會話連線的結構體

type session struct

// 建立新連線

func newsession(conn net.conn) *session

}// 向連線中寫資料

func (s session) write(data byte) error

return nil

}// 從連線中讀資料

func (s session) read() (byte, error)

// 讀取資料長度

datalen := binary.bigendian.uint32(header)

// 按照資料長度去讀取資料

data := make(byte, datalen)

_, err = io.readfull(s.conn, data)

if err != nil

return data, nil

}

rpc/session_test.go

package rpc

import (

"fmt"

"net"

"sync"

"testing"

)func testsession_readwrite(t *testing.t)

// 協程,乙個讀,乙個寫

wg.add(2)

// 寫資料協程

go func()

conn,_ := lis.accept()

s := session

// 寫資料

err = s.write(byte(my_data))

if err != nil

}()// 讀資料協程

go func()

s := session

// 讀資料

data, err := s.read()

if err != nil

if string(data) != my_data

fmt.println(string(data))

}()wg.wait()

}

rpc/codec.go

package rpc

import (

"bytes"

"encoding/gob"

)// 定義資料格式和編譯碼

type rpcdata struct

}// 編碼

func encode(data rpcdata) (byte, error)

return buf.bytes(), nil

}// 解碼

func decode(b byte) (rpcdata, error)

return data, nil

}

rpc/server.go

package rpc

import (

"fmt"

"net"

"reflect"

)// 宣告服務端

type server struct

// 建立服務端物件

func newserver(addr string) *server

}// 服務端繫結註冊方法

// 將函式名與函式真正實現對應起來

// 第乙個引數為函式名, 第二個傳入真正的函式

func (s *server) register(rpcname string, f inte***ce{})

// map中沒有值,則將對映新增進map,便於呼叫

fval := reflect.valueof(f)

s.funcs[rpcname] = fval

}// 服務端等待呼叫

func (s *server) run()

for

// 建立會話

srvsession := newsession(conn)

// rpc 讀取資料

b, err := srvsession.read()

if err != nil

// 對資料解碼

rpcdata, err := decode(b)

if err != nil

// 根據讀取到的資料的name,得到呼叫的函式名

f, ok := s.funcs[rpcdata.name]

if !ok

// 解析遍歷客戶端出來的引數, 放到乙個陣列中

inargs := make(reflect.value, 0, len(rpcdata.args))

for _, arg := range rpcdata.args

// 反射呼叫方法,傳入引數

out := f.call(inargs)

// 解析遍歷執行結果,放到乙個陣列中

outargs := make(inte***ce{}, 0, len(out))

for _, o := range out

// 包裝資料返回給客戶端

resprpcdata := rpcdata

// 編碼

respbytes, err := encode(resprpcdata)

if err != nil

// 使用rpc寫出資料

err = srvsession.write(respbytes)

if err != nil

}}

rpc/client.go

package rpc

import (

"net"

"reflect"

)// 宣告客戶端

type client struct

// 建立客戶端物件

func newclient(conn net.conn) *client

}// 實現通用的rpc客戶端

// 繫結rpc使用的方法

// 傳入訪問的函式名

// 函式具體實現在server端, client只有函式原型

// 使用makefunc() 完成原型到函式的呼叫

// fptr指向函式原型

func (c *client) callrpc(rpcname string, fptr inte***ce{}) , 0, len(args))

for _, arg := range args

// 建立連線

clisession := newsession(c.conn)

// 編碼資料

reqrpc := rpcdata

b, err := encode(reqrpc)

if err != nil

// 寫出資料

err = clisession.write(b)

if err != nil

// 讀響應資料

respbytes, err := clisession.read()

if err != nil

// 解碼資料

resprpc, err := decode(respbytes)

if err != nil

// 處理服務端返回的資料

outargs := make(reflect.value, 0, len(resprpc.args))

for i, arg := range resprpc.args

} return outargs

} v := reflect.makefunc(fn.type(), f)

// 為函式fptr賦值

fn.set(v)

}

rpc/******_tpc_test.go

package rpc

import (

"encoding/gob"

"fmt"

"net"

"testing"

)// 使用者查詢

// 用於測試的結構體

type user struct

// 用於測試查詢使用者的方法

func queryuser(uid int) (user, error)

user[1] = user

user[2] = user

// 模擬查詢使用者

if u, ok := user[uid]; ok

return user{}, fmt.errorf("id %d not in user db", uid)

}func testrpc(t *testing.t) )

addr := "127.0.0.1:8080"

// 建立服務端

srv := newserver(addr)

// 將方法註冊到服務端

srv.register("queryuser", queryuser)

// 服務端等待呼叫

go srv.run()

// 客戶端獲取連線

conn , err := net.dial("tcp", addr)

if err != nil

// 建立客戶端

cli := newclient(conn)

// 宣告函式原型

var query func(int) (user error)

cli.callrpc("queryuser", &query)

// 得到查詢結果

u, err := query(1)

if err != nil

fmt.println(u)

}

golang 實現rpc遠端呼叫,開箱即用

rpc 遠端方法呼叫 優點 提公升系統可擴充套件性,提公升可維護性,和吃持續交付能力 實現系統的高可用等 缺點 rpc受限於網路 實現乙個rcp遠端呼叫關鍵在於帶裡層的實現 還是貼 吧 將client 位址賦值 func new addr string client jrp實現 func c cli...

乙個自己實現的rpc框架

整合spring配置 檔案頭部加入rpc的namespace 服務端 服務端標籤 其中,protocol標籤屬性分析 port指定服務端繫結的埠 service標籤屬性分析 inte ce指定介面的完整類名,ref指定實現類的id,且該實現類必須放入spring容器中service標籤也可 以用註解...

golang官方rpc包的使用

rpc remote rrocedure call,遠端過程呼叫 是乙個計算機通訊協議。rpc協議假定某些傳輸協議的存在,如tcp和udp,為通訊程式之間攜帶資訊資料。在osi網路通訊模型中,rpc跨越了傳輸層和應用層。rpc採用c s模式,請求程式就是乙個客戶機,而服務提供程式就是乙個伺服器。首先...