I am trying to implement an inter-process communication.
The model: Part A -> Sends messages to Part B.
I have implemented this using Client-Server example from ZMQ tutorial (code attached bellow), but facing issues that the process is "locked".
What is the best practice to implement this kind of model?
It is not classic "Client-Server". Actually just one part sends data to the second part, and second part uses it.
Is there an option to send a message with a timeout, that it will not lock the process?
Any input / example will be very appreciated!
Server:
zmq::context_t context(1);
zmq::socket_t socket(context, ZMQ_REP);
socket.bind("tcp://*:5555");
..
socket.recv(&request); // SERVER.receives first
socket.send(reply); // SERVER.sends next to Client
.. // .analyze .recv'd data
Client:
requester = context.socket(ZMQ.REQ);
requester.connect("tcp://localhost:5555");
requester.send(str.getBytes(), 0); // CLIENT.sends
byte[] reply = requester.recv(0); // CLIENT.receives
Related
To me it looks like there is no out of the box support with mixed websocket/native socket for Netty 4. I'm using custom binary protocol on my server and it is supposed to support both native and websocket on the same port. Here is what I'm trying in my ServerInitializer:
#Override
public void initChannel(SocketChannel ch) {
System.out.println("channel initialized");
ChannelPipeline pipeline = ch.pipeline();
pipeline.addLast(new HttpServerCodec());
pipeline.addLast(new HttpObjectAggregator(65536));
// client decoders cannot be singleton....
pipeline.addLast(new WebSocketDecoder(), new ClientCommandDecoder());
pipeline.addLast(this.webSocketEncoder, this.serverCommandEncoder);
pipeline.addLast(this.roomHandler);
}
The WebSocketDecoder is taken from the examples, however it seems to use a handshaker which handles only FullHttpRequests which makes use of HttpObjectAggregator mandatory.
However both HttpServerCodec and HttpObjectAggregator don't seem to pass the input data by if it is not HTTP requests. So here is what I wonder:
Can I write custom implementations of given classes and override logic in order to pass the input data if it is not web socket but native
Or can I somehow detect if input data is from websocket and swerve to two different flows (one with HTTP support, other without)
You will need to adjust the pipeline on the fly depending on your input.
Please check our PortUnification example...
TLDR: Can I register callback functions in golang to get notified if a struct member is changed?
I would like to create a simple two-way-binding between a go server and an angular client. The communication is done via websockets.
Example:
Go:
type SharedType struct {
A int
B string
}
sharedType := &SharedType{}
...
sharedType.A = 52
JavaScript:
var sharedType = {A: 0, B: ""};
...
sharedType.A = 52;
Idea:
In both cases, after modifying the values, I want to trigger a custom callback function, send a message via the websocket, and update the value on the client/server side accordingly.
The sent message should only state which value changed (the key / index) and what the new value is. It should also support nested types (structs, that contain other structs) without the need of transmitting everything.
On the client side (angular), I can detect changes of JavaScript objects by registering a callback function.
On the server side (golang), I could create my own map[] and slice[] implementations to trigger callbacks everytime a member is modified (see the Cabinet class in this example: https://appliedgo.net/generics/).
Within these callback-functions, I could then send the modified data to the other side, so two-way binding would be possible for maps and slices.
My Question:
I would like to avoid things like
sharedType.A = 52
sharedType.MemberChanged("A")
// or:
sharedType.Set("A", 52) //.. which is equivalent to map[], just with a predifined set of allowed keys
Is there any way in golang to get informed if a struct member is modified? Or is there any other, generic way for easy two-way binding without huge amounts of boiler-plate code?
No, it's not possible.
But the real question is: how do you suppose to wield all such magic in your Go program?
Consider what you'd like to have would be indeed possible.
Now an innocent assignment
v.A = 42
would—among other things—trigger sending stuff
over a websocket connection to the client.
Now what happens if the connection is closed (client disconnected),
and the sending fails?
What happens if sending fails to complete before a deadline is reached?
OK, suppose you get it at least partially right and actual modification of the local field happens only if sending succeeds.
Still, how should sending errors be handled?
Say, what should happen if the third assignment in
v.A = 42
v.B = "foo"
v.C = 1e10-23
fails?
you could try using server sent events (SSE) to send realtime data to the frontend, while sending a single post request with ur changes. That way you can monitor in the back and send data every second.
I`m using zero mq 3.2.0 C++ libary. I use zmq_connect to connect a port before zmq_bild. But this function return success. How can I know connect fail? My code is:
void *ctx = zmq_ctx_new(1);
void *skt = zmq_socket(ctx, ZMQ_SUB);
int ret = zmq_connect(skt, "tcp://192.168.9.97:5561"); // 192.168.9.97:5561 is not binded
// zmq_connect return zero
This is actually a feature of zeromq, connection status and so on is abstracted away from you. There is no exposed information you can check to see if you're connected or not AFAIK. This means that you can connect even if the server is temporarily down, and zeromq will handle everything when the server comes available later. This can be both a blessing and a curse.
What most people end up doing if they need to know connection status is to implement some sort of heartbeat. REQ/REP ping/pong for example.
Have a look at the lazy pirate pattern for an example of how to ensure reliability from a client perspective.
Iam using telosB motes for implementation.
I have come across one of the way for acknowledging the packets,
task void send() {
call PacketAcknowledgements.requestAck(&myMsg);
if(call AMSend.send(1, &myMsg, 0) != SUCCESS) {
post send();
}
}
event void AMSend.sendDone(message_t *msg, error_t error) {
if(call PacketAcknowledgements.wasAcked(msg))
// do something if packet was acked
else
// do something else if packet was not acked (possibly resend)
}
Actually my doubt is, the receiving mote should have to acknowledge the packet or it should have PacketAcknowledgements interface in its application in order to send ACKs.
How this type of acknowledgement works?
And I have checked with my own type of acknowledgement, it works like after receiving the packet the mote acknowledge the packets, if source mote does not receive positive ack in certain time frame then re transmit the packet .
So which is better way of doing?
Please guide & thanks,
In TinyOS acknowledgements are implemented on the lowest communication abstraction level - active message[1]. This means that any component that operates with active messages has a built in support for synchronous acknowledgements.
Actually my doubt is, the receiving mote should have to acknowledge
the packet or it should have PacketAcknowledgements interface in its
application in order to send ACKs.
If you used PacketAcknowledgements.requestAck(&myMsg) to request acknowledgement, then you don't have to write extra code in Receive.receive event handler to process acks as this is done for you by underlying communication layer. All you need to do is wire PacketAcknowledgements interface that your component/module uses to one of the providers (AMSenderC or ActiveMessageC).
How this type of acknowledgement works?
The high level idea is following - calling PacketAcknowledgements.requestAck(&myMsg) sets a flag in a packet header and tells sender component not to signal sendDone event until ack was received (or timed out). When receiver component handles the packet on the other end it reads the flag and sends and ack if requested.
Having said all that, description of your way of acknowledging packets seems very similar to what PacketAcknowledgements offers, so personally I would avoid writing extra code for handling acknowledgements myself and stick with the tools provided.
I would like to broadcast a message to all open sockets as a result of a non-socket related event, e.g. as a result of a timeout. How do I do this? Should I keep an array of all open sockets and send them a message one by one? Is there a better way?
Note: The broadcasting example in socket.io guide sends a broadcast message in response to a socket connection, so it has a handle to a socket. Even then it says
Broadcasting means sending a message to everyone else except for the socket that starts it.
Edit
To clarify my question - I want to "send a message" to all open sockets. This action is NOT triggered by any socket, so there is no "this socket". For example, some business logic on the server decides that an order is now executed. This information needs to be sent to all open sockets. What's the best way to do this? (This is not "broadcasting" as socket.io defines it.)
So basically you need to get all connected clients to your socket
var clients = io.sockets.clients(); // This returns an array with all connected clients
for ( i = 0; i < clients.length; i++ ) {
clients[i].emit('event', { data: 'message' });
}
This will emit to all of your connected clients.
socket.broadcast.emit('event name', { data : 'your data' });
It will broadcast to all open sockets, except this socket.