Client-Server how to identify two different methods - networking

I am writing a code for Client-Server and there are two possibilities.
The user will request a specific information A to be transmitted.
The user will request a specific information B to be transmitted.
I would like to identify what the client want in my server side and how the client will do that.
Any other ideas?

I know is quite old question but I think what will be a good idea is to use the Chain of Responsibility Design Pattern!
The idea is that you can use a single port and send your request to Receiver 1, Receiver 1 will decide if can handle this request if not, will pass the request to the Receiver 2, Receiver 2 will have to do the same decision and if can handle the request, then will send the response back to the Sender.
So we have the following properties:
One port is required
The Sender(or the Client in other words) is only aware of the 1st Receiver.
The responsible receiver will return a response directly to the sender/client even if the sender/client is not aware of that specific receiver.
Reduced coupling
Dynamically manage the request handlers.
Furthermore, at the end of the chain, you can add behavior to indicate something like a final response, or a default response if the request send has no responsible class to handle it.
UML
Example

Depending on the size of the information, you can always transmit both information through one pipe and then decipher the needed one on the user side

string data = // .. data transmitted.
string[] dataSplit = data.Split(SEPARATOR);
// dataSplit[0] is type of information
switch(dataSplit[0]) {
case 'Name':
...
break;
case 'OS':
...
break;
}
Do you understand ?

Related

How GRPC handle pointer that appear more then once?

For example (golang):
type {
Product struct {
Name string
}
Customer struct {
Name string
Products []*Product
}
}
Which is the correct behavior:
GRPC honor the *Product pointer and transfer it only once.
GRPC will transfer the same *Product as many times as it associated to different Customer.
Michael,
It is not clear on your message, but I am assuming that you will send a Customer as part of your request to a gRPC server.
Golang will marshal the struct into []byte (https://godoc.org/github.com/golang/protobuf/proto#Marshal), so the message will not have such thing as a pointer. It will be just an encoded message. (see
https://github.com/golang/protobuf/blob/master/proto/wire.go#L22).
gRPC is not a Golang thing, so a pointer on a side (e.g. server) does not mean it must be a point on the other side (e.g. client).
Finally, answering your question, the expected behavior is 2. However, you may take a deeper look into proto buff serialization (https://developers.google.com/protocol-buffers/docs/encoding). I have no idea how it works, but maybe the message is compressed, so repeated []bytes maybe be discarded.

Does C++ Actor Framework guarantee message order?

Can C++ Actor Framework be used in such a way that it guarantees message ordering between two actors? I couldn't find anything about this in the manual.
If you have only two actors communicating directly, CAF guarantees that messages arrive in the order they have been sent. Only multi-hop scenarios can cause non-determinism and message reordering.
auto a = spawn(A);
self->send(a, "foo");
self->send(a, 42); // arrives always after "foo"
At the receiving end, it is possible to change the message processing order by changing the actor behavior with become:
[=](int) {
self->become(
keep_behavior,
[=](const std::string&) {
self->unbecome();
}
);
}
In the above example, this will process the int before the string message, even though they have arrived in opposite order at the actor's mailbox.

How to Use ServeMux with ServerConn?

Im creating a Networking API and want people to be able to route requests to specific endpoints using a ServeMux. Instead of using a Server instance, I need to use my own low level ServerConn. This is because I am receiving both incoming HTTP requests and plain text data from the same port.
The problem, however, is that if I want to forward a request using my ServeMux, I would use it's ServeHTTP method. For this, I need to provide a ResponseWriter, which I don't know how to create an instance of since it is an interface, not a struct. Should a I create my own ResponseWriter struct? Is there one given by the Golang Standard Library? Or is there an alternate solution to this altogether?
I would avoid doing this altogether if at all possible. Mixing protocols on the same connection is bound to lead to hard-to-trace bugs, and unexpected behavior. If you really want to do it, and have all the http/1.1 mechanisms work correctly, leave as much as possible to the http package.
Since ResponseWriter is an interface, you would implement your own type to satisfy it. Look at the unexported response type in the http package for a full example. There's a lot to get right, and using it in combination with a ServerConn (which is documented as "do no use") is probably not a good idea.
The place to do this at a lower level would be in Accept inside the Server's net.Listener. Since you're going to have to parse the start of every request twice, you would need a net.Conn that can be "rewound" partly.
Make yourself a net.Listener that checks the start of the stream on a new connection, and if it looks like an http request, return a net.Conn that replays the first chunk you read off the wire on its first Reads. Something like:
type replayConn struct {
net.Conn
buf []byte
pos int
}
func (c *replayConn) Read(b []byte) (int, error) {
if c.pos < len(c.buf) {
n := copy(b, c.buf[c.pos:])
c.pos += n
return n, nil
}
return c.Conn.Read(b)
}
If the connection isn't http, then send the connection off to your other type of handler, and continue blocking on Accept.

TCP server: will payload delivery happen in pieces?

I am writing a TCP server app in Dart. When doing similar things in other languages, I've noticed that even if I send a byte buffer of size X, my onData() receive function will probably be called multiple times with smaller buffers that add up to X. If I'm not mistaken, this happens because of Flow Control. So usually my payload's header contains the payload size, and I use that to wait until I've read the full payload before processing it.
Do I have to handle this manually in Dart too? So far, I have not had issues and I've received the entire payload in a single call to onData(), but I'd rather ask.
I didn't have issues either, but you could start processing the data while the response is not yet fully received.
If the response is huge, all data needs to be buffered. This way you aren't able to receive data that is bigger than your available RAM. For example downloading a movie wouldn't be possible this way.
Yes. While I'm not sure the exact size of the data transferred to a request, there may be times when you have to completely drain the stream before accessing the data being sent via a POST or other method. (For the body of the http request). See the Creating a server section of the Dart Tutorial. In particular you can see how the stream is drained under Handling POST requests. Normally rather than writing back the pieces as the example shows, they are added directly to a buffer as follows:
var buff = [];
req.listen(buff.addAll,
onDone: () {
print('Received: ${String.fromCharCodes(buff)}');
});
See more information on HttpRequest class documentation.
As an alternative, you can use the http_server package which will automatically drain the stream for you and handle the data load properly depending on the headers which are passed with the request. It does this by applying a stream transformer to the incoming HttpRequests stream to convert them to HttpRequestBody. See below for an example. For more details see the HttpBodyHandler API.
HttpServer.bind(...).then((server) {
server.transform(new HttpBodyHandler())
.listen((HttpRequestBody body) {
// each request is now an HttpRequestBody
// which has already drained the stream
print(body.type);
print(body.body);
body.request.response..statusCode = HttpStatus.OK
..writeln('Got it!')
..close();
});
});

Send message to set of users within a group with SignalR

Is it possible to send a message to a selection of clients within a Group in SignalR?
...without having to maintain your own lists of subscribers and using context.Clients.Clients(includeConnectionIds[])
SignalR does not have state by default, or they actually do with groups... But it is not very dynamic. I had the same issue as you are having. I needed to send a message to a subset of a group.. Or actually I needed to send to clients where age was between x and y...
This is impossible with groups so you have to implement the functionality your self.
Bloated and ugly...
I actually ended up using Xsocket.net instead where I can target client with lambda expressions without messing around with custom static lists/groups etc.
Do not know your requirements but sending to any subset if clients is done by:
this.SendTo(p => p.Age > x && p.Age < y, new {Message="hello world"},"message");
//Signature of the extension method is...
//SendTo<T>(this IXSocketController socket, Func<T, bool> expression, object obj, string eventname)
//So you can actually send to clients on any controller is specifying T
Best of luck with whatever you choose.
In SignalR 2.0 you can send to a many groups or many connections in a single call via Clients.Groups or Clients.Clients.

Resources