We have an application in which we are listening on a socket. When clients connect, we need to know the per client “fd” and the peer address. This info can be fetched using the socket monitors. Subsequently, we need to send data separately for each client. (not send same data to all clients). Is there a standard API to get socket structure from “fd” which we can use in send API?
My understanding is that fd is only used as a field of the zmq_pollitem_t struct used in zmq_poll or other pollers. There it is used for when you want to interface ZMQ sockets with other non-ZMQ pollers (so if you're using zmq_poll it shouldn't be set to anything other than 0). So, in the case you are using a non-ZMQ poller, you're setting the fd value, not getting it.
Is this the use of fd you're referring to? If not, could you update your question to be more specific?
Related
In golang, when you make a client/server combination with Listen/Accept on the server and Dial on the client, as far as I can tell writing to the client doesn't actually guarantee the full transmission chain. IE when you say:
_len, _err := conn.Write([]byte("sent"))
it is possible that the text you send may reach the buffer of the client machine but not the client itself. In other words, if the client becomes unavailable, _err may still be unset and _len may still show the correct length of bytes being sent. I noticed this by killing the connection between my server and client and monitoring the return status of conn.Write() manually and seeing that it didn't show an error.
In other words, just using these tools out of the box won't guarantee delivery, and I was hoping that there was a go library that implemented a client acknowledgement to insure this further guarantee. I'd like to say something like:
_len, _err := _write(conn, "sent\n")
and have guarantees that if the client goes away that _err will be set accordingly - assuming a specific timeout between the send and an acknowledgement from the client.
Is there a standard library like this? I could write my own wrapper to do this, but I have a feeling the logic to do this correctly would be somewhat intricate.
thanks much again for any info,
Ed
Is there a standard library like this?
There is no standard library for this. How application level acknowledgements are done is specified in the specific application protocol, i.e. a protocol like HTTP (web), SMTP (mail delivery), SIP (VoIP) etc. And this protocol must be spoken in both client and server. There is no way for a client to enforce some application level acknowledgement if it is not part of the protocol specification and the server will not explicitly send it.
Therefore you either need to pick an application protocol which supports the semantics you need and use it on both client and server. Or you need to define your own application protocol which supports the exact semantics you need and implement it yourself on both sides.
I am trying to send a message to a WebSocket by referencing it's specific connection, which I maintain in a map of map[*websocket.Conn]bool. I do not want to broadcast the message using a channel but instead want to send a direct message to a specific connection.
(godebug) p clients.conn
map[*websocket.Conn]bool{(*websocket.Conn)(0xc420126000):true, (*websocket.Conn)(0xc4200f86c0):true}
I have opted out of Gorilla for now and am using the x/net/websocket sub-repository.
Any tips would be appreciated.
Right now I'm using socket.io with mandatory websockets as the transport. I'm thinking about moving to raw websockets but I'm not clear on what functionality I will lose moving off of socket.io. Thanks for any guidance.
The socket.io library adds the following features beyond standard webSockets:
Automatic selection of long polling vs. webSocket if the browser does not support webSockets or if the network path has a proxy/firewall that blocks webSockets.
Automatic client reconnection if the connection goes down (even if the server restarts).
Automatic detection of a dead connection (by using regular pings to detect a non-functioning connection)
Message passing scheme with automatic conversion to/from JSON.
The server-side concept of rooms where it's easy to communicate with a group of connected users.
The notion of connecting to a namespace on the server rather than just connecting to the server. This can be used for a variety of different capabilities, but I use it to tell the server what types of information I want to subscribe to. It's like connection to a particular channel.
Server-side data structures that automatically keep track of all connected clients so you can enumerate them at any time.
Middleware architecture built-in to the socket.io library that can be used to implement things like authentication with access to cookies from the original connection.
Automatic storage of the cookies and other headers present on the connection when it was first connected (very useful for identifying what user is connected).
Server-side broadcast capabilities to send a common message to either to all connected clients, all clients in a room or all clients in a namespace.
Tagging of every message with a message name and routing of message names into an eventEmitter so you listen for incoming messages by listening on an eventEmitter for the desired message name.
The ability for either client or server to send a message and then wait for a response to that specific message (a reply feature or request/response model).
ZeroMQs Pub/Sub pattern makes it easy for the server to reply to the right client. However, it is less obvious how to handle communication that cannot be resolved within two steps, i.e. protocols where multiple request/reply pairs are necessary.
For example, consider a case where the client is a worker which asks the server for new work of a specific type, the server replies with the parameters of the work, the client then sends the results and the server checks these and replies whether they were correct.
Obviously, I can't just use recv,send,recv,send sequentially and assume that the first and the second recv are from the same client. What would be the idiomatic way to use multiple recv,send pairs without having to handle messages from other clients inbetween?
Multiple Request/Reply pairs can be made through the use of ZMQ_ROUTER sockets. I recommend using ZMQ_REQ sockets on the clients for bidirectional communication.
If you want to have multiple clients accessing a single server you could use a router socket on the server and request sockets on the clients.
Check out the ZMQ guide's section on this pattern:
http://zguide.zeromq.org/php:chapter3#The-Asynchronous-Client-Server-Pattern
All the clients will interact with the server in the same pattern as Pub/Subs except they will all point at a single server Router socket.
The server on the other hand will receive three messages for every single message a client sends. These parts represent:
Part0 = Identity of connection (random number of which client it is)
Part1 = Empty frame
Part2 = Data of the ZMQ message.
Reference:
http://zguide.zeromq.org/php:chapter3#ROUTER-Broker-and-REQ-Workers
The identity can be used to differentiate between clients accessing on a single port. Repacking the message in the same order and responding on the router socket (with a different data frame) will automatically route it to the client who sent the message.
How can a client both subscribe and listen to replies with zeromq?
That is, on the client side I'd like to run a loop which only receives messages and selectively sends requests, and on the server side I'd like to publish most of the time, but to sometimes receive requests as well.
It looks like I'll have to have two different sockets - one for each mode of communication. Is it possible to avoid that and on the server side receive "request notifications" from the socket on a zeromq callback thread while pushing messages to the socket in my own thread?
I am awfully new to ZeroMQ, so I'm not sure if what you want is considered best-practice or not. However, a solution using multiple sockets is pretty simple using zmq_poll.
The basic idea would be to have both client and server:
open a socket for pub/sub
open a socket for req/rep
multiplex sends and receives between the two sockets in a loop using zmq_poll in an infinite loop
process req/rep and pub/sub events within the loop as they occur
Using zmq_poll in this manner with multiple sockets is nice because it avoids threads altogether. The 0MQ guide has a good example here. Note that in that example, they use a timeout of -1 in zmq_poll, which causes it to block until at least one event occurs on any of the multiplexed sockets, but it's pretty common to use a timeout of x milliseconds or something if your loop needs to do some other work as well.
You can use 2 threads to handle the different sockets. The challenge is that if you need to share data between threads, you need to synchronize it in a safe way.
The alternative is to use the ZeroMQ Poller to select the sockets that have new data on them. The process would then use a single loop in the way bjlaub explained.
This could be accomplished using a variation/subset of the Majordomo Protocol. Here's the idea:
Your server will be a router socket, and your clients will be dealer sockets. Upon connecting to the server, the client needs to send some kind of subscription or "hello" message (of your design). The server receives that packet, but (being a router socket) also receives the ID of that client. When the server needs to send something to that client (through your design), it sends it to that ID. The client can send and receive at will, since it is a dealer socket.