Skip to content

Instantly share code, notes, and snippets.

@Vaelatern
Created August 5, 2019 03:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Vaelatern/dd8aae465e3807af5d189143377f5008 to your computer and use it in GitHub Desktop.
Save Vaelatern/dd8aae465e3807af5d189143377f5008 to your computer and use it in GitHub Desktop.
Minimum broken example for websockets.
// Code generated by capnpc-go. DO NOT EDIT.
// Not relevant to this example. Just minimum necessary code.
package spec
import (
context "golang.org/x/net/context"
capnp "zombiezen.com/go/capnproto2"
text "zombiezen.com/go/capnproto2/encoding/text"
schemas "zombiezen.com/go/capnproto2/schemas"
server "zombiezen.com/go/capnproto2/server"
)
type R struct{ Client capnp.Client }
// R_TypeID is the unique identifier for the type R.
const R_TypeID = 0x92cb9960ce88a13d
func (c R) Note(ctx context.Context, params func(R_note_Params) error, opts ...capnp.CallOption) R_note_Results_Promise {
if c.Client == nil {
return R_note_Results_Promise{Pipeline: capnp.NewPipeline(capnp.ErrorAnswer(capnp.ErrNullClient))}
}
call := &capnp.Call{
Ctx: ctx,
Method: capnp.Method{
InterfaceID: 0x92cb9960ce88a13d,
MethodID: 0,
InterfaceName: "basic.capnp:R",
MethodName: "note",
},
Options: capnp.NewCallOptions(opts),
}
if params != nil {
call.ParamsSize = capnp.ObjectSize{DataSize: 8, PointerCount: 0}
call.ParamsFunc = func(s capnp.Struct) error { return params(R_note_Params{Struct: s}) }
}
return R_note_Results_Promise{Pipeline: capnp.NewPipeline(c.Client.Call(call))}
}
type R_Server interface {
Note(R_note) error
}
func R_ServerToClient(s R_Server) R {
c, _ := s.(server.Closer)
return R{Client: server.New(R_Methods(nil, s), c)}
}
func R_Methods(methods []server.Method, s R_Server) []server.Method {
if cap(methods) == 0 {
methods = make([]server.Method, 0, 1)
}
methods = append(methods, server.Method{
Method: capnp.Method{
InterfaceID: 0x92cb9960ce88a13d,
MethodID: 0,
InterfaceName: "basic.capnp:R",
MethodName: "note",
},
Impl: func(c context.Context, opts capnp.CallOptions, p, r capnp.Struct) error {
call := R_note{c, opts, R_note_Params{Struct: p}, R_note_Results{Struct: r}}
return s.Note(call)
},
ResultsSize: capnp.ObjectSize{DataSize: 0, PointerCount: 0},
})
return methods
}
// R_note holds the arguments for a server call to R.note.
type R_note struct {
Ctx context.Context
Options capnp.CallOptions
Params R_note_Params
Results R_note_Results
}
type R_note_Params struct{ capnp.Struct }
// R_note_Params_TypeID is the unique identifier for the type R_note_Params.
const R_note_Params_TypeID = 0xbfba254722426321
func NewR_note_Params(s *capnp.Segment) (R_note_Params, error) {
st, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 0})
return R_note_Params{st}, err
}
func NewRootR_note_Params(s *capnp.Segment) (R_note_Params, error) {
st, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 8, PointerCount: 0})
return R_note_Params{st}, err
}
func ReadRootR_note_Params(msg *capnp.Message) (R_note_Params, error) {
root, err := msg.RootPtr()
return R_note_Params{root.Struct()}, err
}
func (s R_note_Params) String() string {
str, _ := text.Marshal(0xbfba254722426321, s.Struct)
return str
}
func (s R_note_Params) R() bool {
return s.Struct.Bit(0)
}
func (s R_note_Params) SetR(v bool) {
s.Struct.SetBit(0, v)
}
// R_note_Params_List is a list of R_note_Params.
type R_note_Params_List struct{ capnp.List }
// NewR_note_Params creates a new list of R_note_Params.
func NewR_note_Params_List(s *capnp.Segment, sz int32) (R_note_Params_List, error) {
l, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 8, PointerCount: 0}, sz)
return R_note_Params_List{l}, err
}
func (s R_note_Params_List) At(i int) R_note_Params { return R_note_Params{s.List.Struct(i)} }
func (s R_note_Params_List) Set(i int, v R_note_Params) error { return s.List.SetStruct(i, v.Struct) }
func (s R_note_Params_List) String() string {
str, _ := text.MarshalList(0xbfba254722426321, s.List)
return str
}
// R_note_Params_Promise is a wrapper for a R_note_Params promised by a client call.
type R_note_Params_Promise struct{ *capnp.Pipeline }
func (p R_note_Params_Promise) Struct() (R_note_Params, error) {
s, err := p.Pipeline.Struct()
return R_note_Params{s}, err
}
type R_note_Results struct{ capnp.Struct }
// R_note_Results_TypeID is the unique identifier for the type R_note_Results.
const R_note_Results_TypeID = 0xeada765e4955823d
func NewR_note_Results(s *capnp.Segment) (R_note_Results, error) {
st, err := capnp.NewStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 0})
return R_note_Results{st}, err
}
func NewRootR_note_Results(s *capnp.Segment) (R_note_Results, error) {
st, err := capnp.NewRootStruct(s, capnp.ObjectSize{DataSize: 0, PointerCount: 0})
return R_note_Results{st}, err
}
func ReadRootR_note_Results(msg *capnp.Message) (R_note_Results, error) {
root, err := msg.RootPtr()
return R_note_Results{root.Struct()}, err
}
func (s R_note_Results) String() string {
str, _ := text.Marshal(0xeada765e4955823d, s.Struct)
return str
}
// R_note_Results_List is a list of R_note_Results.
type R_note_Results_List struct{ capnp.List }
// NewR_note_Results creates a new list of R_note_Results.
func NewR_note_Results_List(s *capnp.Segment, sz int32) (R_note_Results_List, error) {
l, err := capnp.NewCompositeList(s, capnp.ObjectSize{DataSize: 0, PointerCount: 0}, sz)
return R_note_Results_List{l}, err
}
func (s R_note_Results_List) At(i int) R_note_Results { return R_note_Results{s.List.Struct(i)} }
func (s R_note_Results_List) Set(i int, v R_note_Results) error { return s.List.SetStruct(i, v.Struct) }
func (s R_note_Results_List) String() string {
str, _ := text.MarshalList(0xeada765e4955823d, s.List)
return str
}
// R_note_Results_Promise is a wrapper for a R_note_Results promised by a client call.
type R_note_Results_Promise struct{ *capnp.Pipeline }
func (p R_note_Results_Promise) Struct() (R_note_Results, error) {
s, err := p.Pipeline.Struct()
return R_note_Results{s}, err
}
const schema_902d2bfc3bbf0d49 = "x\xda\x12\xa8p`2d\xcdgb`\x08\x94ae" +
"\xfbo\xbb\xb0\xe3\\\xc2\xcc\xd3\x93\x18\x04y\x98\xff{" +
"\xf2\xee\xb7\xfe\xa3\xad;\x81\x81\x81QX\x96\xb1HX" +
"\x91\x91\x9d\x81AX\x96\xd1]\xd8\x15\xc4\xfa\xaf\x98\xec" +
"\xa4\xe4\xae\xbak?C \x1f##\x03\x03\x0bHV" +
"\x97\xf1\x12\x03\xa3\xb0!\xa3=\x03\xe3\x7f\xdb\xa6P\xcf" +
"\xb8\xb2[\xaf\x18\x04\xf9`\xd2\x81\x8c\xb7\x18\x0c\xfe'" +
"%\x16g&\xeb%'2\xc8\x17\xe4\x15X\x05\x050" +
"2\x06\xb20\xb3\"\x99\xc8\x08\xd3*(\xa8\xc5\xc0$" +
"\xc8\xca\xce\x9f\x97_\x92\xea\xc0\x18\xc0\xc8\x08\xd7\xcc\x04" +
"\xd6\xab\x07\x92P\x09H,J\xcce,\x0edaf" +
"a``ad`\x10\xe4\x15b`\x08\xe4`f\x0c" +
"\x14abd,bdd`bdd\xc0\xae9(" +
"\xb5\xb84\x87\xb9\xa4\x18\x10\x00\x00\xff\xff\x02bA\xd5"
func init() {
schemas.Register(schema_902d2bfc3bbf0d49,
0x92cb9960ce88a13d,
0xbfba254722426321,
0xeada765e4955823d)
}
//go:generate capnp compile -ogo:api -I ./capnp basic.capnp
package main
import (
"context"
"log"
"net/http"
"nhooyr.io/websocket"
"zombiezen.com/go/capnproto2/rpc"
"github.com/dxpb/dxpb/api"
)
type r struct {
*r_actual
}
type r_actual struct{}
func (b *r_actual) Note(call spec.R_note) error {
return nil
}
func connectDrone(url string) spec.R_note_Results {
ctx := context.Background()
rawconn, _, err := websocket.Dial(ctx, url, websocket.DialOptions{
Subprotocols: []string{"proto"},
})
if err != nil {
log.Fatal("TODO: Don't fatally crash on failed dials: err: ", err)
}
conn := rpc.NewConn(rpc.StreamTransport(websocket.NetConn(rawconn)))
log.Println("About to trigger crash")
drone := spec.R{Client: conn.Bootstrap(ctx)}
log.Println("Passed the crash begin. If there were a sleep, it'd already have errored.")
rV, err := drone.Note(ctx, func(p spec.R_note_Params) error {
return nil
}).Struct()
log.Println("Now done with the RPC call, but I bet it errored...")
if err != nil {
log.Fatal("TODO: Don't fatally crash when the call fails due to err: ", err)
}
return rV
}
func ListenAndWork(listen string) {
var actee r
http.HandleFunc("/v1/ws", func(w http.ResponseWriter, r *http.Request) {
conn, err := websocket.Accept(w, r, websocket.AcceptOptions{
Subprotocols: []string{"proto"},
})
if err != nil {
log.Println(err)
return
}
defer conn.Close(websocket.StatusInternalError, "the sky is falling")
transport := rpc.StreamTransport(websocket.NetConn(conn))
iface := rpc.MainInterface(spec.R_ServerToClient(actee).Client)
rpcconn := rpc.NewConn(transport, iface)
rpcconn.Wait()
})
log.Println("Now listening on " + listen)
log.Fatal(http.ListenAndServe(listen, nil))
}
func main() {
go ListenAndWork("localhost:9191")
connectDrone("ws://localhost:9191/v1/ws")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment