How do I respond to multiple gRPC clients? - go

I am building an application which can have multiple gRPC servers and definitely will have multiple gRPC clients, I wanted to know, how to identify on server side that this is the client I am talking to and only send data to that client. I am using bidirectional streaming RPC and right now the data gets broadcasted to every client and I don't want that. What functions in go gRPC make it possible or how can I implement it?

There are two ways to read this question. One way is to read it as the auth problem as answered before. The second way is how I read it, as a connection/session problem.
When the client connects, the grpc server will invoke a function to implement the call in its own goroutine, and that function will be only talking to the client that initiated that call. So, the struct you registered as your grpc server will be shared among many connections, but each connection will run in its own goroutine, and will only talk to the client that initiated it. That also means you have to make sure the grpc server implementation is thread-safe.
You mentioned data is being broadcasted to every client? There is no broadcast in grpc, are you sure that's what's happening?

This sounds like a common authentication/authorization problem that ultimately won't have much to do with gRPC or Go.
You need a way for a client to indicate who they are. Personally I'm a fan of JWTs. In a standard HTTP request, there are authorization headers that can indicate who is making the request. Similarly, gRPC supports meta data attached to each remote call. In my current work project, every call must have a JWT in the meta data or else I don't process the request. Every call except the login endpoint that is.
I haven't looked into how to get details like a gRPC client's IP address or other information about a client's connection but chances are that anything provided by gRPC's generated code is something potentially faked by the client. When architected correctly, JWTs can offer cryptographic confidence that the client is who they claim to be.

Related

Service to intercept client-server websocket communication for purposes of API-untangling

I'm writing a custom client for an existing framework but in a different language than the supported client. Now I would like to intercept the traffic of the existing client-server connection to get a better grasp of the API intrinsics, which is always quite tedious if you have to extract it from the code alone. I had a look at postman but it doesn't seem to allow interception of websocket messages (https appears to be possible thorugh postman interceptor. Is there a similar tool for websockets?
Basically what I'm looking for is just a relay that forwards every request as-is to the server and vice-versa for the response.

The theory of websockets with API

I have an API running on a server, which handle users connection and a messaging system.
Beside that, I launched a websocket on that same server, waiting for connections and stuff.
And let's say we can get access to this by an Android app.
I'm having troubles to figure out what I should do now, here are my thoughts:
1 - When a user connect to the app, the API connect to the websocket. We allow the Android app only to listen on this socket to get new messages. When the user want to answer, the Android app send a message to the API. The API writes itself the received message to the socket, which will be read back by the Android app used by another user.
This way, the API can store the message in database before writing it in the socket.
2- The API does not connect to the websocket in any way. The Android app listen and write to the websocket when needed, and should, when writing to the websocket, also send a request to the API so it can store the message in DB.
May be none of the above is correct, please let me know
EDIT
I already understood why I should use a websocket, seems like it's the best way to have this "real time" system (when getting a new message for example) instead of forcing the client to make an HTTP request every x seconds to check if there are new messages.
What I still don't understand, is how it is suppose to communicate with my database. Sorry if my example is not clear, but I'll try to keep going with it :
My messaging system need to store all messages in my API database, to have some kind of historic of the conversation.
But it seems like a websocket must be running separately from the API, I mean it's another program right? Because it's not for HTTP requests
So should the API also listen to this websocket to catch new messages and store them?
You really have not described what the requirements are for your application so it's hard for us to directly advise what your app should do. You really shouldn't start out your analysis by saying that you have a webSocket and you're trying to figure out what to do with it. Instead, lay out the requirements of your app and figure out what technology will best meet those requirements.
Since your requirements are not clear, I'll talk about what a webSocket is best used for and what more traditional http requests are best used for.
Here are some characteristics of a webSocket:
It's designed to be continuously connected over some longer duration of time (much longer than the duration of one exchange between client and server).
The connection is typically made from a client to a server.
Once the connection is established, then data can be sent in either direction from client to server or from server to client at any time. This is a huge difference from a typical http request where data can only be requested by the client - with an http request the server can not initiate the sending of data to the client.
A webSocket is not a request/response architecture by default. In fact to make it work like request/response requires building a layer on top of the webSocket protocol so you can tell which response goes with which request. http is natively request/response.
Because a webSocket is designed to be continuously connected (or at least connected for some duration of time), it works very well (and with lower overhead) for situations where there is frequent communication between the two endpoints. The connection is already established and data can just be sent without any connection establishment overhead. In addition, the overhead per message is typically smaller with a webSocket than with http.
So, here are a couple typical reasons why you might choose one over the other.
If you need to be able to send data from server to client without having the client regular poll for new data, then a webSocket is very well designed for that and http cannot do that.
If you are frequently sending lots of small bits of data (for example, a temperature probe sending the current temperature every 10 seconds), then a webSocket will incur less network and server overhead than initiating a new http request for every new piece of data.
If you don't have either of the above situations, then you may not have any real need for a webSocket and an http request/response model may just be simpler.
If you really need request/response where a specific response is tied to a specific request, then that is built into http and is not a built-in feature of webSockets.
You may also find these other posts useful:
What are the pitfalls of using Websockets in place of RESTful HTTP?
What's the difference between WebSocket and plain socket communication?
Push notification | is websocket mandatory?
How does WebSockets server architecture work?
Response to Your Edit
But it seems like a websocket must be running separately from the API,
I mean it's another program right? Because it's not for HTTP requests
The same process that supports your API can also be serving the webSocket connections. Thus, when you get incoming data on the webSocket, you can just write it directly to the database the same way the API would access the database. So, NO the webSocket server does not have to be a separate program or process.
So should the API also listen to this websocket to catch new messages
and store them?
No, I don't think so. Only one process can be listening to a set of incoming webSocket connections.

How do I pass the response writer and http request to an executable in Go?

I want to run a simple webserver in Go doing some basic authorisation and routing to multiple apps.
Is it possible to have the webserver running as a standalone executable and pass the response writer and http request to other executables?
The idea is that the app binaries can hopefully be compiled and deployed independently of the webserver.
Memory areas of running applications are isolated: a process cannot just read or write another application's memory (Wikipedia: Process isolation).
So just passing the response writer and the http request is not so easy. And even if you would implement it (e.g. serializing them into binary or text data, sending/passing them over somehow, and reconstructing them on the other side) serving an HTTP request in the background is more than just interacting with the ResponseWriter and Request objects: it involves reading from and writing to the underlying TCP connection... so you would also have to "pass" the TCP connection or create a bridge between the real HTTP client and the application you forward to.
Another option would be to send a redirect back to the client (HTTP 3xx status codes) after doing the authentication and routing logic. With this solution you could have authentication and certain routing logic implemented in your app, but you would lose further routing possibilities because further request would go directly to the designated host.
Essentially what you try to create is the functionality of a proxy server which have plenty of implementations out there. Given the complexity of a good proxy server, it should not be feasible to reproduce one.
I suggest to either utilize an existing proxy server or "refactor" your architecture to avoid this kind of segmentation.

Making request using WebSockets in sails but not receiving response from the server

I'm starting with Websockets and I have a problem.
I have a sails.js application that uses sockets to update the client side.
On the client side it makes an API call using socket.get("/api/v1/actor...") to bring all the items of the database. When I see what the WebSocket's traffic on the Chrome console:
As you can see, the connection has been established and the API call has been correctly done through the socket.
The problem is, there is no answer from the server, not even an error.
If I make the same API call using ajax, I get response, but it doesn't work using WebSockets.
Any idea what might be producing this behavior?
EDIT: I add here the code here that processes the request and this one here that sends the request, but the problem is that it never execute this code. I think we we are closer to the find the cause, since we think it has to do with a network problem. We figured there is an F5 reverse-proxy which is not properly set up to handle websockets
The answer didn't make any sense now that I've seen the code that's why I've edited it. I only answered because I could't comment on your question and ask you for the code.
Your calling code seems correct and the server side of things the process of response should be handled automatically by the framework, you only need to return some JSON in the controller method.
I instantiated a copy of the server (just changed the adapters to run it locally) and the server replied to the web socket requests (although I only tested the route '/index').
Normally when the problems are caused by a reverse proxy the socket simply refuses to connect and you can't even send data to server. Does the property "socket.socket.connected" returns true?
The best way to test is to write a small node application with socket.io client and test it in the same machine that the application server is running, then you can exclude network problems.

ZeroMQ for basic signalling?

Maybe I missed this in the docs, but how do you use ZeroMQ for simple signaling between multiple nodes? Something like REQ to REQ, with no REPs.
Example: I sometimes want to tell all other nodes to invalidate cache pages or notify them that something happened.
Request-reply won't work because I don't want the requester to block waiting for an empty response. I want to allow multiple signals to build up at the server.
Publish-subscribe feels wrong because I'd have to subscribe to everything, and start two sockets, one for each direction of communication.
PAIRs don't support automatically reconnecting and have other limitations.
Is pub-sub the best way to go? Or am I better just to use a traditional socket, write to both ends, and handle disconnections/reconnecting?
What you want is a dealer socket in your client side and a dealer socket on your server side. If you want to be able to send message to a specific node from the server side, then you better use a router socket in the server.

Resources