wsh routing + proxy (#224)

lots of changes, including:
* source/route to rpcmessage
* rpcproxy
* wshrouter
* bug fixing
* wps uses routeids not clients
This commit is contained in:
Mike Sawka
2024-08-13 16:52:35 -07:00
committed by GitHub
parent 01d788b780
commit 844451ea0d
25 changed files with 716 additions and 323 deletions
+25 -25
View File
@@ -12,147 +12,147 @@ import (
)
// command "authenticate", wshserver.AuthenticateCommand
func AuthenticateCommand(w *wshutil.WshRpc, data string, opts *wshrpc.WshRpcCommandOpts) error {
func AuthenticateCommand(w *wshutil.WshRpc, data string, opts *wshrpc.RpcOpts) error {
_, err := sendRpcRequestCallHelper[any](w, "authenticate", data, opts)
return err
}
// command "controllerinput", wshserver.ControllerInputCommand
func ControllerInputCommand(w *wshutil.WshRpc, data wshrpc.CommandBlockInputData, opts *wshrpc.WshRpcCommandOpts) error {
func ControllerInputCommand(w *wshutil.WshRpc, data wshrpc.CommandBlockInputData, opts *wshrpc.RpcOpts) error {
_, err := sendRpcRequestCallHelper[any](w, "controllerinput", data, opts)
return err
}
// command "controllerrestart", wshserver.ControllerRestartCommand
func ControllerRestartCommand(w *wshutil.WshRpc, data wshrpc.CommandBlockRestartData, opts *wshrpc.WshRpcCommandOpts) error {
func ControllerRestartCommand(w *wshutil.WshRpc, data wshrpc.CommandBlockRestartData, opts *wshrpc.RpcOpts) error {
_, err := sendRpcRequestCallHelper[any](w, "controllerrestart", data, opts)
return err
}
// command "createblock", wshserver.CreateBlockCommand
func CreateBlockCommand(w *wshutil.WshRpc, data wshrpc.CommandCreateBlockData, opts *wshrpc.WshRpcCommandOpts) (waveobj.ORef, error) {
func CreateBlockCommand(w *wshutil.WshRpc, data wshrpc.CommandCreateBlockData, opts *wshrpc.RpcOpts) (waveobj.ORef, error) {
resp, err := sendRpcRequestCallHelper[waveobj.ORef](w, "createblock", data, opts)
return resp, err
}
// command "deleteblock", wshserver.DeleteBlockCommand
func DeleteBlockCommand(w *wshutil.WshRpc, data wshrpc.CommandDeleteBlockData, opts *wshrpc.WshRpcCommandOpts) error {
func DeleteBlockCommand(w *wshutil.WshRpc, data wshrpc.CommandDeleteBlockData, opts *wshrpc.RpcOpts) error {
_, err := sendRpcRequestCallHelper[any](w, "deleteblock", data, opts)
return err
}
// command "eventpublish", wshserver.EventPublishCommand
func EventPublishCommand(w *wshutil.WshRpc, data wshrpc.WaveEvent, opts *wshrpc.WshRpcCommandOpts) error {
func EventPublishCommand(w *wshutil.WshRpc, data wshrpc.WaveEvent, opts *wshrpc.RpcOpts) error {
_, err := sendRpcRequestCallHelper[any](w, "eventpublish", data, opts)
return err
}
// command "eventrecv", wshserver.EventRecvCommand
func EventRecvCommand(w *wshutil.WshRpc, data wshrpc.WaveEvent, opts *wshrpc.WshRpcCommandOpts) error {
func EventRecvCommand(w *wshutil.WshRpc, data wshrpc.WaveEvent, opts *wshrpc.RpcOpts) error {
_, err := sendRpcRequestCallHelper[any](w, "eventrecv", data, opts)
return err
}
// command "eventsub", wshserver.EventSubCommand
func EventSubCommand(w *wshutil.WshRpc, data wshrpc.SubscriptionRequest, opts *wshrpc.WshRpcCommandOpts) error {
func EventSubCommand(w *wshutil.WshRpc, data wshrpc.SubscriptionRequest, opts *wshrpc.RpcOpts) error {
_, err := sendRpcRequestCallHelper[any](w, "eventsub", data, opts)
return err
}
// command "eventunsub", wshserver.EventUnsubCommand
func EventUnsubCommand(w *wshutil.WshRpc, data wshrpc.SubscriptionRequest, opts *wshrpc.WshRpcCommandOpts) error {
func EventUnsubCommand(w *wshutil.WshRpc, data wshrpc.SubscriptionRequest, opts *wshrpc.RpcOpts) error {
_, err := sendRpcRequestCallHelper[any](w, "eventunsub", data, opts)
return err
}
// command "eventunsuball", wshserver.EventUnsubAllCommand
func EventUnsubAllCommand(w *wshutil.WshRpc, opts *wshrpc.WshRpcCommandOpts) error {
func EventUnsubAllCommand(w *wshutil.WshRpc, opts *wshrpc.RpcOpts) error {
_, err := sendRpcRequestCallHelper[any](w, "eventunsuball", nil, opts)
return err
}
// command "fileappend", wshserver.FileAppendCommand
func FileAppendCommand(w *wshutil.WshRpc, data wshrpc.CommandFileData, opts *wshrpc.WshRpcCommandOpts) error {
func FileAppendCommand(w *wshutil.WshRpc, data wshrpc.CommandFileData, opts *wshrpc.RpcOpts) error {
_, err := sendRpcRequestCallHelper[any](w, "fileappend", data, opts)
return err
}
// command "fileappendijson", wshserver.FileAppendIJsonCommand
func FileAppendIJsonCommand(w *wshutil.WshRpc, data wshrpc.CommandAppendIJsonData, opts *wshrpc.WshRpcCommandOpts) error {
func FileAppendIJsonCommand(w *wshutil.WshRpc, data wshrpc.CommandAppendIJsonData, opts *wshrpc.RpcOpts) error {
_, err := sendRpcRequestCallHelper[any](w, "fileappendijson", data, opts)
return err
}
// command "fileread", wshserver.FileReadCommand
func FileReadCommand(w *wshutil.WshRpc, data wshrpc.CommandFileData, opts *wshrpc.WshRpcCommandOpts) (string, error) {
func FileReadCommand(w *wshutil.WshRpc, data wshrpc.CommandFileData, opts *wshrpc.RpcOpts) (string, error) {
resp, err := sendRpcRequestCallHelper[string](w, "fileread", data, opts)
return resp, err
}
// command "filewrite", wshserver.FileWriteCommand
func FileWriteCommand(w *wshutil.WshRpc, data wshrpc.CommandFileData, opts *wshrpc.WshRpcCommandOpts) error {
func FileWriteCommand(w *wshutil.WshRpc, data wshrpc.CommandFileData, opts *wshrpc.RpcOpts) error {
_, err := sendRpcRequestCallHelper[any](w, "filewrite", data, opts)
return err
}
// command "getmeta", wshserver.GetMetaCommand
func GetMetaCommand(w *wshutil.WshRpc, data wshrpc.CommandGetMetaData, opts *wshrpc.WshRpcCommandOpts) (waveobj.MetaMapType, error) {
func GetMetaCommand(w *wshutil.WshRpc, data wshrpc.CommandGetMetaData, opts *wshrpc.RpcOpts) (waveobj.MetaMapType, error) {
resp, err := sendRpcRequestCallHelper[waveobj.MetaMapType](w, "getmeta", data, opts)
return resp, err
}
// command "message", wshserver.MessageCommand
func MessageCommand(w *wshutil.WshRpc, data wshrpc.CommandMessageData, opts *wshrpc.WshRpcCommandOpts) error {
func MessageCommand(w *wshutil.WshRpc, data wshrpc.CommandMessageData, opts *wshrpc.RpcOpts) error {
_, err := sendRpcRequestCallHelper[any](w, "message", data, opts)
return err
}
// command "remotefileinfo", wshserver.RemoteFileInfoCommand
func RemoteFileInfoCommand(w *wshutil.WshRpc, data string, opts *wshrpc.WshRpcCommandOpts) (*wshrpc.FileInfo, error) {
func RemoteFileInfoCommand(w *wshutil.WshRpc, data string, opts *wshrpc.RpcOpts) (*wshrpc.FileInfo, error) {
resp, err := sendRpcRequestCallHelper[*wshrpc.FileInfo](w, "remotefileinfo", data, opts)
return resp, err
}
// command "remotestreamfile", wshserver.RemoteStreamFileCommand
func RemoteStreamFileCommand(w *wshutil.WshRpc, data wshrpc.CommandRemoteStreamFileData, opts *wshrpc.WshRpcCommandOpts) chan wshrpc.RespOrErrorUnion[wshrpc.CommandRemoteStreamFileRtnData] {
func RemoteStreamFileCommand(w *wshutil.WshRpc, data wshrpc.CommandRemoteStreamFileData, opts *wshrpc.RpcOpts) chan wshrpc.RespOrErrorUnion[wshrpc.CommandRemoteStreamFileRtnData] {
return sendRpcRequestResponseStreamHelper[wshrpc.CommandRemoteStreamFileRtnData](w, "remotestreamfile", data, opts)
}
// command "resolveids", wshserver.ResolveIdsCommand
func ResolveIdsCommand(w *wshutil.WshRpc, data wshrpc.CommandResolveIdsData, opts *wshrpc.WshRpcCommandOpts) (wshrpc.CommandResolveIdsRtnData, error) {
func ResolveIdsCommand(w *wshutil.WshRpc, data wshrpc.CommandResolveIdsData, opts *wshrpc.RpcOpts) (wshrpc.CommandResolveIdsRtnData, error) {
resp, err := sendRpcRequestCallHelper[wshrpc.CommandResolveIdsRtnData](w, "resolveids", data, opts)
return resp, err
}
// command "setmeta", wshserver.SetMetaCommand
func SetMetaCommand(w *wshutil.WshRpc, data wshrpc.CommandSetMetaData, opts *wshrpc.WshRpcCommandOpts) error {
func SetMetaCommand(w *wshutil.WshRpc, data wshrpc.CommandSetMetaData, opts *wshrpc.RpcOpts) error {
_, err := sendRpcRequestCallHelper[any](w, "setmeta", data, opts)
return err
}
// command "setview", wshserver.SetViewCommand
func SetViewCommand(w *wshutil.WshRpc, data wshrpc.CommandBlockSetViewData, opts *wshrpc.WshRpcCommandOpts) error {
func SetViewCommand(w *wshutil.WshRpc, data wshrpc.CommandBlockSetViewData, opts *wshrpc.RpcOpts) error {
_, err := sendRpcRequestCallHelper[any](w, "setview", data, opts)
return err
}
// command "streamcpudata", wshserver.StreamCpuDataCommand
func StreamCpuDataCommand(w *wshutil.WshRpc, data wshrpc.CpuDataRequest, opts *wshrpc.WshRpcCommandOpts) chan wshrpc.RespOrErrorUnion[wshrpc.CpuDataType] {
func StreamCpuDataCommand(w *wshutil.WshRpc, data wshrpc.CpuDataRequest, opts *wshrpc.RpcOpts) chan wshrpc.RespOrErrorUnion[wshrpc.CpuDataType] {
return sendRpcRequestResponseStreamHelper[wshrpc.CpuDataType](w, "streamcpudata", data, opts)
}
// command "streamtest", wshserver.StreamTestCommand
func StreamTestCommand(w *wshutil.WshRpc, opts *wshrpc.WshRpcCommandOpts) chan wshrpc.RespOrErrorUnion[int] {
func StreamTestCommand(w *wshutil.WshRpc, opts *wshrpc.RpcOpts) chan wshrpc.RespOrErrorUnion[int] {
return sendRpcRequestResponseStreamHelper[int](w, "streamtest", nil, opts)
}
// command "streamwaveai", wshserver.StreamWaveAiCommand
func StreamWaveAiCommand(w *wshutil.WshRpc, data wshrpc.OpenAiStreamRequest, opts *wshrpc.WshRpcCommandOpts) chan wshrpc.RespOrErrorUnion[wshrpc.OpenAIPacketType] {
func StreamWaveAiCommand(w *wshutil.WshRpc, data wshrpc.OpenAiStreamRequest, opts *wshrpc.RpcOpts) chan wshrpc.RespOrErrorUnion[wshrpc.OpenAIPacketType] {
return sendRpcRequestResponseStreamHelper[wshrpc.OpenAIPacketType](w, "streamwaveai", data, opts)
}
// command "test", wshserver.TestCommand
func TestCommand(w *wshutil.WshRpc, data string, opts *wshrpc.WshRpcCommandOpts) error {
func TestCommand(w *wshutil.WshRpc, data string, opts *wshrpc.RpcOpts) error {
_, err := sendRpcRequestCallHelper[any](w, "test", data, opts)
return err
}
+7 -7
View File
@@ -9,19 +9,19 @@ import (
"github.com/wavetermdev/thenextwave/pkg/wshutil"
)
func sendRpcRequestCallHelper[T any](w *wshutil.WshRpc, command string, data interface{}, opts *wshrpc.WshRpcCommandOpts) (T, error) {
func sendRpcRequestCallHelper[T any](w *wshutil.WshRpc, command string, data interface{}, opts *wshrpc.RpcOpts) (T, error) {
if opts == nil {
opts = &wshrpc.WshRpcCommandOpts{}
opts = &wshrpc.RpcOpts{}
}
var respData T
if opts.NoResponse {
err := w.SendCommand(command, data)
err := w.SendCommand(command, data, opts)
if err != nil {
return respData, err
}
return respData, nil
}
resp, err := w.SendRpcRequest(command, data, opts.Timeout)
resp, err := w.SendRpcRequest(command, data, opts)
if err != nil {
return respData, err
}
@@ -32,12 +32,12 @@ func sendRpcRequestCallHelper[T any](w *wshutil.WshRpc, command string, data int
return respData, nil
}
func sendRpcRequestResponseStreamHelper[T any](w *wshutil.WshRpc, command string, data interface{}, opts *wshrpc.WshRpcCommandOpts) chan wshrpc.RespOrErrorUnion[T] {
func sendRpcRequestResponseStreamHelper[T any](w *wshutil.WshRpc, command string, data interface{}, opts *wshrpc.RpcOpts) chan wshrpc.RespOrErrorUnion[T] {
if opts == nil {
opts = &wshrpc.WshRpcCommandOpts{}
opts = &wshrpc.RpcOpts{}
}
respChan := make(chan wshrpc.RespOrErrorUnion[T])
reqHandler, err := w.SendComplexRequest(command, data, true, opts.Timeout)
reqHandler, err := w.SendComplexRequest(command, data, opts)
if err != nil {
go func() {
respChan <- wshrpc.RespOrErrorUnion[T]{Error: err}
+12 -9
View File
@@ -6,6 +6,7 @@ package wshrpc
import (
"context"
"log"
"os"
"reflect"
@@ -57,6 +58,7 @@ type RespOrErrorUnion[T any] struct {
type WshRpcInterface interface {
AuthenticateCommand(ctx context.Context, data string) error
MessageCommand(ctx context.Context, data CommandMessageData) error
GetMetaCommand(ctx context.Context, data CommandGetMetaData) (wstore.MetaMapType, error)
SetMetaCommand(ctx context.Context, data CommandSetMetaData) error
@@ -90,15 +92,15 @@ type WshServerCommandMeta struct {
CommandType string `json:"commandtype"`
}
type WshRpcCommandOpts struct {
Timeout int `json:"timeout"`
NoResponse bool `json:"noresponse"`
type RpcOpts struct {
Timeout int `json:"timeout,omitempty"`
NoResponse bool `json:"noresponse,omitempty"`
Route string `json:"route,omitempty"`
}
type RpcContext struct {
BlockId string `json:"blockid,omitempty"`
TabId string `json:"tabid,omitempty"`
WindowId string `json:"windowid,omitempty"`
BlockId string `json:"blockid,omitempty"`
TabId string `json:"tabid,omitempty"`
}
func HackRpcContextIntoData(dataPtr any, rpcContext RpcContext) {
@@ -122,12 +124,12 @@ func HackRpcContextIntoData(dataPtr any, rpcContext RpcContext) {
field.SetString(rpcContext.BlockId)
case "TabId":
field.SetString(rpcContext.TabId)
case "WindowId":
field.SetString(rpcContext.WindowId)
case "BlockORef":
if rpcContext.BlockId != "" {
field.Set(reflect.ValueOf(waveobj.MakeORef(wstore.OType_Block, rpcContext.BlockId)))
}
default:
log.Printf("invalid wshcontext tag: %q in type(%T)", tag, dataPtr)
}
}
}
@@ -147,7 +149,8 @@ type CommandSetMetaData struct {
}
type CommandResolveIdsData struct {
Ids []string `json:"ids"`
BlockId string `json:"blockid" wshcontext:"BlockId"`
Ids []string `json:"ids"`
}
type CommandResolveIdsRtnData struct {
+34 -48
View File
@@ -30,26 +30,33 @@ import (
const SimpleId_This = "this"
type WshServer struct{}
func (*WshServer) WshServerImpl() {}
var WshServerImpl = WshServer{}
func (ws *WshServer) TestCommand(ctx context.Context, data string) error {
defer func() {
if r := recover(); r != nil {
log.Printf("panic in TestCommand: %v", r)
}
}()
rpc := wshutil.GetWshRpcFromContext(ctx)
if rpc == nil {
rpcSource := wshutil.GetRpcSourceFromContext(ctx)
log.Printf("TEST src:%s | %s\n", rpcSource, data)
if rpcSource == "" {
return nil
}
go func() {
wshclient.MessageCommand(rpc, wshrpc.CommandMessageData{Message: "test message"}, &wshrpc.WshRpcCommandOpts{NoResponse: true})
resp, err := wshclient.RemoteFileInfoCommand(rpc, "~/work/wails/thenextwave/README.md", nil)
mainClient := GetMainRpcClient()
wshclient.MessageCommand(mainClient, wshrpc.CommandMessageData{Message: "test message"}, &wshrpc.RpcOpts{NoResponse: true, Route: rpcSource})
resp, err := wshclient.RemoteFileInfoCommand(mainClient, "~/work/wails/thenextwave/README.md", &wshrpc.RpcOpts{Route: rpcSource})
if err != nil {
log.Printf("error getting remote file info: %v", err)
return
}
log.Printf("remote file info: %#v\n", resp)
rch := wshclient.RemoteStreamFileCommand(rpc, wshrpc.CommandRemoteStreamFileData{Path: "~/work/wails/thenextwave/README.md"}, nil)
rch := wshclient.RemoteStreamFileCommand(mainClient, wshrpc.CommandRemoteStreamFileData{Path: "~/work/wails/thenextwave/README.md"}, &wshrpc.RpcOpts{Route: rpcSource})
for msg := range rch {
if msg.Error != nil {
log.Printf("error in stream: %v", msg.Error)
@@ -66,22 +73,6 @@ func (ws *WshServer) TestCommand(ctx context.Context, data string) error {
return nil
}
func (ws *WshServer) AuthenticateCommand(ctx context.Context, data string) error {
w := wshutil.GetWshRpcFromContext(ctx)
if w == nil {
return fmt.Errorf("no wshrpc in context")
}
newCtx, err := wshutil.ValidateAndExtractRpcContextFromToken(data)
if err != nil {
return fmt.Errorf("error validating token: %w", err)
}
if newCtx == nil {
return fmt.Errorf("no context found in jwt token")
}
w.SetRpcContext(*newCtx)
return nil
}
// for testing
func (ws *WshServer) MessageCommand(ctx context.Context, data wshrpc.CommandMessageData) error {
log.Printf("MESSAGE: %s | %q\n", data.ORef, data.Message)
@@ -228,17 +219,12 @@ func sendWaveObjUpdate(oref waveobj.ORef) {
})
}
func resolveSimpleId(ctx context.Context, simpleId string) (*waveobj.ORef, error) {
func resolveSimpleId(ctx context.Context, data wshrpc.CommandResolveIdsData, simpleId string) (*waveobj.ORef, error) {
if simpleId == SimpleId_This {
wshRpc := wshutil.GetWshRpcFromContext(ctx)
if wshRpc == nil {
return nil, fmt.Errorf("no wshrpc in context")
if data.BlockId == "" {
return nil, fmt.Errorf("no blockid in request")
}
rpcCtx := wshRpc.GetRpcContext()
if rpcCtx.BlockId == "" {
return nil, fmt.Errorf("no blockid in rpc context")
}
return &waveobj.ORef{OType: wstore.OType_Block, OID: rpcCtx.BlockId}, nil
return &waveobj.ORef{OType: wstore.OType_Block, OID: data.BlockId}, nil
}
if strings.Contains(simpleId, ":") {
rtn, err := waveobj.ParseORef(simpleId)
@@ -254,7 +240,7 @@ func (ws *WshServer) ResolveIdsCommand(ctx context.Context, data wshrpc.CommandR
rtn := wshrpc.CommandResolveIdsRtnData{}
rtn.ResolvedIds = make(map[string]waveobj.ORef)
for _, simpleId := range data.Ids {
oref, err := resolveSimpleId(ctx, simpleId)
oref, err := resolveSimpleId(ctx, data, simpleId)
if err != nil || oref == nil {
continue
}
@@ -471,40 +457,40 @@ func (ws *WshServer) EventRecvCommand(ctx context.Context, data wshrpc.WaveEvent
}
func (ws *WshServer) EventPublishCommand(ctx context.Context, data wshrpc.WaveEvent) error {
wrpc := wshutil.GetWshRpcFromContext(ctx)
if wrpc == nil {
return fmt.Errorf("no wshrpc in context")
rpcSource := wshutil.GetRpcSourceFromContext(ctx)
if rpcSource == "" {
return fmt.Errorf("no rpc source set")
}
if data.Sender == "" {
data.Sender = wrpc.ClientId()
data.Sender = rpcSource
}
wps.Broker.Publish(data)
return nil
}
func (ws *WshServer) EventSubCommand(ctx context.Context, data wshrpc.SubscriptionRequest) error {
wrpc := wshutil.GetWshRpcFromContext(ctx)
if wrpc == nil {
return fmt.Errorf("no wshrpc in context")
rpcSource := wshutil.GetRpcSourceFromContext(ctx)
if rpcSource == "" {
return fmt.Errorf("no rpc source set")
}
wps.Broker.Subscribe(wrpc, data)
wps.Broker.Subscribe(rpcSource, data)
return nil
}
func (ws *WshServer) EventUnsubCommand(ctx context.Context, data wshrpc.SubscriptionRequest) error {
wrpc := wshutil.GetWshRpcFromContext(ctx)
if wrpc == nil {
return fmt.Errorf("no wshrpc in context")
rpcSource := wshutil.GetRpcSourceFromContext(ctx)
if rpcSource == "" {
return fmt.Errorf("no rpc source set")
}
wps.Broker.Unsubscribe(wrpc, data)
wps.Broker.Unsubscribe(rpcSource, data)
return nil
}
func (ws *WshServer) EventUnsubAllCommand(ctx context.Context) error {
wrpc := wshutil.GetWshRpcFromContext(ctx)
if wrpc == nil {
return fmt.Errorf("no wshrpc in context")
rpcSource := wshutil.GetRpcSourceFromContext(ctx)
if rpcSource == "" {
return fmt.Errorf("no rpc source set")
}
wps.Broker.UnsubscribeAll(wrpc)
wps.Broker.UnsubscribeAll(rpcSource)
return nil
}
+34 -73
View File
@@ -4,89 +4,42 @@
package wshserver
import (
"context"
"fmt"
"log"
"net"
"reflect"
"sync"
"github.com/wavetermdev/thenextwave/pkg/wshrpc"
"github.com/wavetermdev/thenextwave/pkg/wshutil"
)
// this file contains the generic types and functions that create and power the WSH server
const (
DefaultOutputChSize = 32
DefaultInputChSize = 32
)
type WshServer struct{}
func (*WshServer) WshServerImpl() {}
type WshServerMethodDecl struct {
Command string
CommandType string
MethodName string
Method reflect.Value
CommandDataType reflect.Type
DefaultResponseDataType reflect.Type
RequestDataTypes []reflect.Type // for streaming requests
ResponseDataTypes []reflect.Type // for streaming responses
}
var WshServerImpl = WshServer{}
var contextRType = reflect.TypeOf((*context.Context)(nil)).Elem()
var wshCommandDeclMap = wshrpc.GenerateWshCommandDeclMap()
func GetWshServerMethod(command string, commandType string, methodName string, methodFunc any) *WshServerMethodDecl {
methodVal := reflect.ValueOf(methodFunc)
methodType := methodVal.Type()
if methodType.Kind() != reflect.Func {
panic(fmt.Sprintf("methodVal must be a function got [%v]", methodType))
}
if methodType.In(0) != contextRType {
panic(fmt.Sprintf("methodVal must have a context as the first argument %v", methodType))
}
var defResponseType reflect.Type
if methodType.NumOut() > 1 {
defResponseType = methodType.Out(0)
}
var cdataType reflect.Type
if methodType.NumIn() > 1 {
cdataType = methodType.In(1)
}
rtn := &WshServerMethodDecl{
Command: command,
CommandType: commandType,
MethodName: methodName,
Method: methodVal,
CommandDataType: cdataType,
DefaultResponseDataType: defResponseType,
}
return rtn
}
func decodeRtnVals(rtnVals []reflect.Value) (any, error) {
switch len(rtnVals) {
case 0:
return nil, nil
case 1:
errIf := rtnVals[0].Interface()
if errIf == nil {
return nil, nil
func handleDomainSocketClient(conn net.Conn) {
proxy := wshutil.MakeRpcProxy()
go func() {
writeErr := wshutil.AdaptOutputChToStream(proxy.ToRemoteCh, conn)
if writeErr != nil {
log.Printf("error writing to domain socket: %v\n", writeErr)
}
return nil, errIf.(error)
case 2:
errIf := rtnVals[1].Interface()
if errIf == nil {
return rtnVals[0].Interface(), nil
}
return rtnVals[0].Interface(), errIf.(error)
default:
return nil, fmt.Errorf("too many return values: %d", len(rtnVals))
}()
go func() {
// when input is closed, close the connection
defer conn.Close()
wshutil.AdaptStreamToMsgCh(conn, proxy.FromRemoteCh)
}()
rpcCtx, err := proxy.HandleAuthentication()
if err != nil {
conn.Close()
log.Printf("error handling authentication: %v\n", err)
return
}
// now that we're authenticated, set the ctx and attach to the router
log.Printf("domain socket connection authenticated: %#v\n", rpcCtx)
proxy.SetRpcContext(rpcCtx)
wshutil.DefaultRouter.RegisterRoute("controller:"+rpcCtx.BlockId, proxy)
}
func RunWshRpcOverListener(listener net.Listener) {
@@ -98,11 +51,19 @@ func RunWshRpcOverListener(listener net.Listener) {
continue
}
log.Print("got domain socket connection\n")
// TODO deal with closing connection
go wshutil.SetupConnRpcClient(conn, &WshServerImpl)
go handleDomainSocketClient(conn)
}
}
func MakeWshServer(inputCh chan []byte, outputCh chan []byte, initialCtx wshrpc.RpcContext) {
wshutil.MakeWshRpc(inputCh, outputCh, initialCtx, &WshServerImpl)
var waveSrvClient_Singleton *wshutil.WshRpc
var waveSrvClient_Once = &sync.Once{}
// returns the wavesrv main rpc client singleton
func GetMainRpcClient() *wshutil.WshRpc {
waveSrvClient_Once.Do(func() {
inputCh := make(chan []byte, DefaultInputChSize)
outputCh := make(chan []byte, DefaultOutputChSize)
waveSrvClient_Singleton = wshutil.MakeWshRpc(inputCh, outputCh, wshrpc.RpcContext{}, &WshServerImpl)
})
return waveSrvClient_Singleton
}