Skip to content

Commit e4a5f2d

Browse files
committed
client handler / reverse handler alias support
1 parent ee66ac2 commit e4a5f2d

File tree

3 files changed

+110
-6
lines changed

3 files changed

+110
-6
lines changed

client.go

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,7 @@ func websocketClient(ctx context.Context, addr string, namespace string, outs []
229229
var hnd reqestHandler
230230
if len(config.reverseHandlers) > 0 {
231231
h := makeHandler(defaultServerConfig())
232+
h.aliasedMethods = config.aliasedHandlerMethods
232233
for _, reverseHandler := range config.reverseHandlers {
233234
h.register(reverseHandler.ns, reverseHandler.hnd)
234235
}
@@ -534,7 +535,7 @@ func (fn *rpcFunc) handleRpcCall(args []reflect.Value) (results []reflect.Value)
534535
req := request{
535536
Jsonrpc: "2.0",
536537
ID: id,
537-
Method: fn.client.namespace + "." + fn.name,
538+
Method: fn.name,
538539
Params: params,
539540
}
540541

@@ -590,17 +591,27 @@ func (fn *rpcFunc) handleRpcCall(args []reflect.Value) (results []reflect.Value)
590591
return fn.processResponse(resp, retVal())
591592
}
592593

594+
const (
595+
ProxyTagRetry = "retry"
596+
ProxyTagRPCMethod = "rpc_method"
597+
)
598+
593599
func (c *client) makeRpcFunc(f reflect.StructField) (reflect.Value, error) {
594600
ftyp := f.Type
595601
if ftyp.Kind() != reflect.Func {
596602
return reflect.Value{}, xerrors.New("handler field not a func")
597603
}
598604

605+
name := c.namespace + "." + f.Name
606+
if tag, ok := f.Tag.Lookup(ProxyTagRPCMethod); ok {
607+
name = tag
608+
}
609+
599610
fun := &rpcFunc{
600611
client: c,
601612
ftyp: ftyp,
602-
name: f.Name,
603-
retry: f.Tag.Get("retry") == "true",
613+
name: name,
614+
retry: f.Tag.Get(ProxyTagRetry) == "true",
604615
}
605616
fun.valOut, fun.errOut, fun.nout = processFuncOut(ftyp)
606617

options.go

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ type Config struct {
2323
paramEncoders map[reflect.Type]ParamEncoder
2424
errors *Errors
2525

26-
reverseHandlers []clientHandler
26+
reverseHandlers []clientHandler
27+
aliasedHandlerMethods map[string]string
2728

2829
httpClient *http.Client
2930

@@ -40,6 +41,8 @@ func defaultConfig() Config {
4041
pingInterval: 5 * time.Second,
4142
timeout: 30 * time.Second,
4243

44+
aliasedHandlerMethods: map[string]string{},
45+
4346
paramEncoders: map[reflect.Type]ParamEncoder{},
4447

4548
httpClient: _defaultHTTPClient,
@@ -94,6 +97,14 @@ func WithClientHandler(ns string, hnd interface{}) func(c *Config) {
9497
}
9598
}
9699

100+
// WithClientHandlerAlias creates an alias for a client HANDLER method - for handlers created
101+
// with WithClientHandler
102+
func WithClientHandlerAlias(alias, original string) func(c *Config) {
103+
return func(c *Config) {
104+
c.aliasedHandlerMethods[alias] = original
105+
}
106+
}
107+
97108
func WithHTTPClient(h *http.Client) func(c *Config) {
98109
return func(c *Config) {
99110
c.httpClient = h

rpc_test.go

Lines changed: 84 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1142,10 +1142,39 @@ func TestIDHandling(t *testing.T) {
11421142
}
11431143
}
11441144

1145+
func TestAliasedCall(t *testing.T) {
1146+
// setup server
1147+
1148+
rpcServer := NewServer()
1149+
rpcServer.Register("ServName", &SimpleServerHandler{n: 3})
1150+
1151+
// httptest stuff
1152+
testServ := httptest.NewServer(rpcServer)
1153+
defer testServ.Close()
1154+
1155+
// setup client
1156+
var client struct {
1157+
WhateverMethodName func(int) (int, error) `rpc_method:"ServName.AddGet"`
1158+
}
1159+
closer, err := NewMergeClient(context.Background(), "ws://"+testServ.Listener.Addr().String(), "Server", []interface{}{
1160+
&client,
1161+
}, nil)
1162+
require.NoError(t, err)
1163+
1164+
// do the call!
1165+
1166+
n, err := client.WhateverMethodName(1)
1167+
require.NoError(t, err)
1168+
1169+
require.Equal(t, 4, n)
1170+
1171+
closer()
1172+
}
1173+
11451174
// 1. make server call on client **
11461175
// 2. make client handle **
1147-
// 3. alias on client
1148-
// 4. alias call on server
1176+
// 3. alias on client **
1177+
// 4. alias call on server **
11491178
// 6. custom/object param type
11501179
// 7. notif mode proxy tag
11511180

@@ -1208,3 +1237,56 @@ func TestReverseCall(t *testing.T) {
12081237

12091238
closer()
12101239
}
1240+
1241+
type RevCallTestServerHandlerAliased struct {
1242+
}
1243+
1244+
func (h *RevCallTestServerHandlerAliased) Call(ctx context.Context) error {
1245+
revClient, ok := ExtractReverseClient[RevCallTestClientProxyAliased](ctx)
1246+
if !ok {
1247+
return fmt.Errorf("no reverse client")
1248+
}
1249+
1250+
r, err := revClient.CallOnClient(8) // multiply by 2 on client
1251+
if err != nil {
1252+
return xerrors.Errorf("call on client: %w", err)
1253+
}
1254+
1255+
if r != 16 {
1256+
return fmt.Errorf("unexpected result: %d", r)
1257+
}
1258+
1259+
return nil
1260+
}
1261+
1262+
type RevCallTestClientProxyAliased struct {
1263+
CallOnClient func(int) (int, error) `rpc_method:"rpc_thing"`
1264+
}
1265+
1266+
func TestReverseCallAliased(t *testing.T) {
1267+
// setup server
1268+
1269+
rpcServer := NewServer(WithReverseClient[RevCallTestClientProxyAliased]("Client"))
1270+
rpcServer.Register("Server", &RevCallTestServerHandlerAliased{})
1271+
1272+
// httptest stuff
1273+
testServ := httptest.NewServer(rpcServer)
1274+
defer testServ.Close()
1275+
1276+
// setup client
1277+
1278+
var client struct {
1279+
Call func() error
1280+
}
1281+
closer, err := NewMergeClient(context.Background(), "ws://"+testServ.Listener.Addr().String(), "Server", []interface{}{
1282+
&client,
1283+
}, nil, WithClientHandler("Client", &RevCallTestClientHandler{}), WithClientHandlerAlias("rpc_thing", "Client.CallOnClient"))
1284+
require.NoError(t, err)
1285+
1286+
// do the call!
1287+
1288+
e := client.Call()
1289+
require.NoError(t, e)
1290+
1291+
closer()
1292+
}

0 commit comments

Comments
 (0)