@@ -175,7 +175,7 @@ fmt.Printf("Current value: %d\n", client.AddGet(5))
175175```
176176
177177### Reverse Calling Feature
178- The go-jsonrpc library also supports reverse calling, where the server can make calls to the client. This is useful in scenarios where the server needs to notify or request data from the client.
178+ The go-jsonrpc library also supports reverse calling, where the server can make calls to the client. This is useful in scenarios where the server needs to notify, request data from the client, or for subscriptions (e.g. ` eth_subscribe ` ) .
179179
180180NOTE: Reverse calling only works in websocket mode
181181
@@ -246,11 +246,13 @@ if err := client.Call(); err != nil {
246246
247247## Options
248248
249- ### Using ` WithServerMethodNameFormatter `
249+ ### Using method name formatters
250+
251+ #### Using ` WithServerMethodNameFormatter `
250252
251253` WithServerMethodNameFormatter ` allows you to customize a function that formats the JSON-RPC method name, given namespace and method name.
252254
253- There are four possible options:
255+ There are four possible out-of-the-box options:
254256- ` jsonrpc.DefaultMethodNameFormatter ` - default method name formatter, e.g. ` SimpleServerHandler.AddGet `
255257- ` jsonrpc.NewMethodNameFormatter(true, jsonrpc.LowerFirstCharCase) ` - method name formatter with namespace, e.g. ` SimpleServerHandler.addGet `
256258- ` jsonrpc.NewMethodNameFormatter(false, jsonrpc.OriginalCase) ` - method name formatter without namespace, e.g. ` AddGet `
@@ -261,6 +263,8 @@ There are four possible options:
261263> Go exported methods are capitalized, so, the method name will be capitalized as well.
262264> e.g. ` SimpleServerHandler.AddGet ` (capital "A" in "AddGet")
263265
266+ You can also create your own method name formatter by creating a function that implements the ` jsonrpc.MethodNameFormatter ` interface.
267+
264268``` go
265269func main () {
266270 // create a new server instance with a custom separator
@@ -286,7 +290,7 @@ func main() {
286290}
287291```
288292
289- ### Using ` WithMethodNameFormatter `
293+ #### Using ` WithMethodNameFormatter `
290294
291295` WithMethodNameFormatter ` is the client-side counterpart to ` WithServerMethodNameFormatter ` .
292296
@@ -304,6 +308,132 @@ func main() {
304308}
305309```
306310
311+ #### Using ` WithClientHandlerFormatter `
312+
313+ Same as ` WithMethodNameFormatter ` , but for client handlers. Using it you can fully customize the JSON-RPC method name for client handlers,
314+ given namespace and method name.
315+
316+ ``` go
317+ func main () {
318+ closer , err := jsonrpc.NewMergeClient (
319+ context.Background (),
320+ " http://example.com" ,
321+ " SimpleServerHandler" ,
322+ []any{&client},
323+ nil ,
324+ jsonrpc.WithMethodNameFormatter (jsonrpc.NewMethodNameFormatter (false , OriginalCase)),
325+ jsonrpc.WithClientHandler (" Client" , &RevCallTestClientHandler{}),
326+ jsonrpc.WithClientHandlerFormatter (jsonrpc.NewMethodNameFormatter (false , OriginalCase)),
327+ )
328+ defer closer ()
329+ }
330+ ```
331+ ### Using method name alias
332+
333+ You can also create an alias for a method name. This is useful if you want to use a different method name in the JSON-RPC
334+ request than the actual method name for a specific method.
335+
336+ #### Usage of method name alias in the server
337+
338+ ``` go
339+ type SimpleServerHandler struct {}
340+
341+ func (h *SimpleServerHandler ) Double (in int ) int {
342+ return in * 2
343+ }
344+
345+ // create a new server instance
346+ rpcServer := jsonrpc.NewServer ()
347+
348+ // create a handler instance and register it
349+ serverHandler := &SimpleServerHandler{}
350+ rpcServer.Register (" SimpleServerHandler" , serverHandler)
351+
352+ // create an alias for the Double method. This will allow you to call the server's Double method
353+ // with the name "rand_myRandomAlias" in the JSON-RPC request.
354+ rpcServer.AliasMethod (" rand_myRandomAlias" , " SimpleServerHandler.Double" )
355+
356+ ```
357+
358+ #### Usage of method name alias with client handlers
359+
360+ ``` go
361+ // setup the client handler
362+ type ReverseHandler struct {}
363+
364+ func (h *ReverseHandler ) DoubleOnClient (in int ) int {
365+ return in * 2
366+ }
367+
368+ // create a new client instance with the client handler + method name alias
369+ closer , err := jsonrpc.NewMergeClient (
370+ context.Background (),
371+ " http://example.com" ,
372+ " SimpleServerHandler" ,
373+ []any{&client},
374+ nil ,
375+ jsonrpc.WithClientHandler (" Client" , &ReverseHandler{}),
376+ // this allows the server to call the client's DoubleOnClient method using the name "rand_theClientRandomAlias" in the JSON-RPC request.
377+ jsonrpc.WithClientHandlerAlias (" rand_theClientRandomAlias" , " Client.DoubleOnClient" ),
378+ )
379+ ```
380+
381+ #### Usage of a struct tag to define method name alias
382+
383+ There are two cases where you can also use the ` rpc_method ` struct tag to define method name alias:
384+ in the client struct and in the reverse handler struct in the server.
385+
386+ In the client struct:
387+ ``` go
388+ // setup the client struct
389+ var client struct {
390+ AddInt func (int ) int ` rpc_method:"rand_aRandomAlias"`
391+ }
392+
393+ // create a new client instance with the client struct that has the `rpc_method` struct tag
394+ closer , err := jsonrpc.NewMergeClient (
395+ context.Background (),
396+ " http://example.com" ,
397+ " SimpleServerHandler" ,
398+ []any{&client},
399+ nil ,
400+ )
401+
402+ // since we defined the method name alias in the client struct, this will send a JSON-RPC request with "rand_aRandomAlias" as the method name to the
403+ // server instead of "SimpleServerHandler.AddInt".
404+ result , err := client.AddInt (10 )
405+
406+ ```
407+
408+ In the server's reverse handler struct:
409+
410+ ``` go
411+ // Define the client handler interface
412+ type ClientHandler struct {
413+ CallOnClient func (int ) (int , error ) ` rpc_method:"rand_theClientRandomAlias"`
414+ }
415+
416+ // Define the server handler
417+ type ServerHandler struct {}
418+
419+ func (h *ServerHandler ) Call (ctx context .Context ) (int , error ) {
420+ revClient , _ := jsonrpc.ExtractReverseClient [ClientHandler](ctx)
421+
422+ // Reverse call to the client.
423+ // Since we defined the method name alias in the client handler struct tag, this
424+ // will send a JSON-RPC request with "rand_theClientRandomAlias" as the method name to the
425+ // client instead of "Client.CallOnClient".
426+ result , err := revClient.CallOnClient (7 )
427+
428+ // ...
429+ }
430+
431+ // Setup server with reverse client capability
432+ rpcServer := jsonrpc.NewServer (jsonrpc.WithReverseClient [ClientHandler](" Client" ))
433+ rpcServer.Register (" ServerHandler" , &ServerHandler{})
434+ ```
435+
436+
307437## Contribute
308438
309439PRs are welcome!
0 commit comments