https://github.com/apachecn-archive/qrpc
Science Score: 13.0%
This score indicates how likely this project is to be science-related based on various indicators:
-
○CITATION.cff file
-
✓codemeta.json file
Found codemeta.json file -
○.zenodo.json file
-
○DOI references
-
○Academic publication links
-
○Academic email domains
-
○Institutional organization owner
-
○JOSS paper metadata
-
○Scientific vocabulary similarity
Low similarity (5.9%) to scientific vocabulary
Repository
Basic Info
- Host: GitHub
- Owner: apachecn-archive
- Language: Go
- Default Branch: master
- Size: 9 MB
Statistics
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
- Releases: 0
Metadata Files
README.en_US.md
qrpc, tiny but powerful rpc framework
qrpc makes it tremendously easy to to perform rpc by offering 4 core features:
blockingornonblockingstreamingornonstreamingserver pushoverlay network(refer tows/README.mdfor detail)
By default each frame is blocking and nonstreaming, this allows traditional block-in-header sequencial behaviour like http/1.1, but you can make it behave tremendously different by attach flags to your frames!
Enough talk, let's demo!
blocking mode
server.go:
```golang package main import "github.com/zhiqiangxu/qrpc"
const ( HelloCmd qrpc.Cmd = iota HelloRespCmd ) func main() { handler := qrpc.NewServeMux() handler.HandleFunc(HelloCmd, func(writer qrpc.FrameWriter, request *qrpc.RequestFrame) { writer.StartWrite(request.RequestID, HelloRespCmd, 0)
writer.WriteBytes(append([]byte("hello world "), request.Payload...))
writer.EndWrite()
})
bindings := []qrpc.ServerBinding{
qrpc.ServerBinding{Addr: "0.0.0.0:8080", Handler: handler}}
server := qrpc.NewServer(bindings)
server.ListenAndServe()
}
```
client.go:
```golang package main import ( "fmt" "github.com/zhiqiangxu/qrpc" )
const ( HelloCmd qrpc.Cmd = iota ) func main() { conf := qrpc.ConnectionConfig{}
conn, _ := qrpc.NewConnection("0.0.0.0:8080", conf, nil)
_, resp, _ := conn.Request(HelloCmd, 0/*no flags*/, []byte("xu"))
frame, _ := resp.GetFrame()
fmt.Println("resp is", string(frame.Payload))
} ```
In the above example, server will process each client frames in sequence order.
Nonblocking mode
To use this mode we only need to change 1 line in client.go:
diff
- _, resp, _ := conn.Request(HelloCmd, 0/*no flags*/, []byte("xu"))
+ _, resp, _ := conn.Request(HelloCmd, qrpc.NBFlag, []byte("xu"))
In this mode request frames will be processed concurrently!
stream mode
stream is like chunked transfer in http, besides, it's bidirectional, we can make either request or response in stream, or we can make both!
Make request in stream mode:
streamclient.go:
```golang package main import ( "fmt" "github.com/zhiqiangxu/qrpc" )
const ( HelloCmd qrpc.Cmd = iota ) func main() { conf := qrpc.ConnectionConfig{}
conn, _ := qrpc.NewConnection("0.0.0.0:8080", conf, nil)
writer, resp, _ := conn.StreamRequest(HelloCmd, 0, []byte("first frame"))
writer.StartWrite(HelloCmd)
writer.WriteBytes([]byte("last frame"))
writer.EndWrite(true) // will attach StreamEndFlag
frame, _ := resp.GetFrame()
fmt.Println("resp is", string(frame.Payload))
}
```
streamserver.go:
```golang package main import ( "github.com/zhiqiangxu/qrpc" "fmt" )
const ( HelloCmd qrpc.Cmd = iota HelloRespCmd ) func main() { handler := qrpc.NewServeMux() handler.HandleFunc(HelloCmd, func(writer qrpc.FrameWriter, request *qrpc.RequestFrame) { writer.StartWrite(request.RequestID, HelloRespCmd, 0)
writer.WriteBytes(append([]byte("first frame "), request.Payload...))
for {
continueFrames := <-request.FrameCh()
if continueFrames == nil {
break
}
writer.WriteBytes(append([]byte(" continue frame "), continueFrames.Payload...))
}
writer.EndWrite()
})
bindings := []qrpc.ServerBinding{
qrpc.ServerBinding{Addr: "0.0.0.0:8080", Handler: handler}}
server := qrpc.NewServer(bindings)
err := server.ListenAndServe()
if err != nil {
panic(err)
}
} ```
In a similar fasion we can also make response in stream mode:
```golang package main import ( "github.com/zhiqiangxu/qrpc" "fmt" )
const ( HelloCmd qrpc.Cmd = iota HelloRespCmd ) func main() { handler := qrpc.NewServeMux() handler.HandleFunc(HelloCmd, func(writer qrpc.FrameWriter, request *qrpc.RequestFrame) { writer.StartWrite(request.RequestID, HelloRespCmd, qrpc.StreamFlag) writer.WriteBytes(append([]byte("first frame "), request.Payload...)) writer.EndWrite()
for {
continueFrames := <-request.FrameCh()
if continueFrames == nil {
break
}
fmt.Printf("%s\n", continueFrames.Payload)
if continueFrames.Flags.IsDone() {
// it's the last frame,so flag it with qrpc.StreamEndFlag
writer.StartWrite(request.RequestID, HelloRespCmd, qrpc.StreamEndFlag)
} else {
// no the last frame,just flag it with qrpc.StreamFlag
writer.StartWrite(request.RequestID, HelloRespCmd, qrpc.StreamFlag)
}
writer.WriteBytes(append([]byte(" continue frame "), continueFrames.Payload...))
writer.EndWrite()
}
})
bindings := []qrpc.ServerBinding{
qrpc.ServerBinding{Addr: "0.0.0.0:8080", Handler: handler}}
server := qrpc.NewServer(bindings)
err := server.ListenAndServe()
if err != nil {
panic(err)
}
} ```
The key is StreamFlag!
push mode
```golang package main import ( "github.com/zhiqiangxu/qrpc" "github.com/zhiqiangxu/util" "sync" )
const ( HelloCmd qrpc.Cmd = iota HelloRespCmd ) func main() { handler := qrpc.NewServeMux() handler.HandleFunc(HelloCmd, func(writer qrpc.FrameWriter, request *qrpc.RequestFrame) { var ( wg sync.WaitGroup ) qserver := request.ConnectionInfo().Server() pushID := qserver.GetPushID() qserver.WalkConn(0, func(writer qrpc.FrameWriter, ci *qrpc.ConnectionInfo) bool { util.GoFunc(&wg, func() { writer.StartWrite(pushID, HelloCmd, qrpc.PushFlag) writer.WriteBytes([]byte("pushed msg")) writer.EndWrite() }) return true }) wg.Wait()
writer.StartWrite(request.RequestID, HelloRespCmd, 0)
writer.WriteBytes(append([]byte("push done"), request.Payload...))
writer.EndWrite()
})
bindings := []qrpc.ServerBinding{
qrpc.ServerBinding{Addr: "0.0.0.0:8080", Handler: handler}}
server := qrpc.NewServer(bindings)
err := server.ListenAndServe()
if err != nil {
panic(err)
}
} ```
In the above example, server will push a message to all connections !
To handle pushed message, the relevant change at client side is:
diff
- conn, _ := qrpc.NewConnection("0.0.0.0:8080", conf, nil)
+ conn, _ := qrpc.NewConnection("0.0.0.0:8080", conf, func(conn *qrpc.Connection, pushedFrame *qrpc.Frame) {
+ fmt.Println(pushedFrame)
+ })
There are even more features like StreamRstFlag!
Performance

About 4 times faster than http!
Stargazers
Owner
- Name: ApacheCN 归档
- Login: apachecn-archive
- Kind: organization
- Email: wizard.z@qq.com
- Repositories: 180
- Profile: https://github.com/apachecn-archive
防止重要项目丢失而设立的归档
GitHub Events
Total
Last Year
Dependencies
- github.com/go-kit/kit v0.9.0
- github.com/gogo/protobuf v1.3.1
- github.com/gorilla/websocket v1.4.1
- github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd
- github.com/modern-go/reflect2 v1.0.1
- github.com/oklog/run v1.0.0
- github.com/urfave/cli/v2 v2.2.0
- github.com/zhiqiangxu/go-reuseport v0.2.1
- github.com/zhiqiangxu/util v0.0.0-20200612094741-8e7a0d4b9665
- go.uber.org/ratelimit v0.1.0
- go.uber.org/zap v1.13.0
- google.golang.org/grpc v1.26.0
- gotest.tools/v3 v3.0.2
- 167 dependencies