typescriptgojson-rpc

Connecting to a Typescript JSON RPC server via a Go client


I have a typescript JSON RPC server and a Go client. I followed various tutorials to set up the server and client, however I'm having trouble communicating between the two. I'm currently trying to connect to them locally so I'm using stdin/stdout to communicate between the two.

This is my server code:

import * as jsonrpc from 'vscode-jsonrpc/node';

const connection = jsonrpc.createMessageConnection(
    new jsonrpc.StreamMessageReader(process.stdin),
    new jsonrpc.StreamMessageWriter(process.stdout)
);

connection.onRequest('testRequest', (params: any) => {
    console.log('in test request');
    return 'testRequest response';
});

connection.listen();

console.log('listening...');

And this is my client code (I call ConnectAndSendRequest in main):

package testConnection

import (
    "context"
    "io"
    "os/exec"

    "github.com/sourcegraph/jsonrpc2"
)

type stdrwc struct {
    in  io.WriteCloser
    out io.ReadCloser
}

func (c *stdrwc) Read(p []byte) (int, error) {
    return c.out.Read(p)
}

func (c *stdrwc) Write(p []byte) (int, error) {
    return c.in.Write(p)
}

func (c *stdrwc) Close() error {
    if err := c.in.Close(); err != nil {
        return err
    }
    return c.out.Close()
}

func ConnectAndSendRequest() error {
    cmd := exec.Command("<my server>")
    stdout, err := cmd.StdoutPipe()
    if err != nil {
        return nil, err
    }

    stdin, err := cmd.StdinPipe()
    if err != nil {
        return nil, err
    }

    if err := cmd.Start(); err != nil {
        return nil, err
    }

    conn := jsonrpc2.NewConn(context.Background(), jsonrpc2.NewBufferedStream(&stdrwc{stdin, stdout}, jsonrpc2.VSCodeObjectCodec{}), nil)
    defer conn.Close()

    var res string
    err := p.Ev2LSConnection.Call(context.Background(), "testRequest", &res)
    if err != nil {
        return err
    }
    log.Println(res)
    return nil
}

When I run my go program, I can see the listening... log in the server cmd prompt, but not in test request. The go program just hangs until I close the server cmd prompt. When the server's closed, I just get err: jsonrpc2: connection is closed on my go cmd prompt.

My suspicion is that my stdin/stdout on either the server or client has been setup incorrectly, so the server isn't receiving the requests from the client. Does anyone with experience in this have any idea what could be wrong?


Solution

  • I figured out the issues now. There were a few problems.

    First problem, the path to the server (<<my server>>) was wrong, so when I tried creating a connection, nothing was actually created. When I tried sending requests, I would see the jsonrpc2: connection is closed error.

    Second problem was that I was sending logs (using console.log()) in the Typescript server, however I was also using the Typescript console for communicating between the server and client, so the go client couldn't understand the output. Once I removed the logs on the TS side, everything was working end to end.