I'm implementing a client sending and receiving unixpackets and interacting with a server which was already implemented in C++.
So far, the client can receive and send packet to server successfully. But I used a for loop to keep calling Recv to see if there is a new message.
I implemented a Packet class so that the client and server can follow the same rules to encode and decode the message. Transport is a struct wrapping a net.Conn
. Client is consisted of Transport, receiving Packet and sending Packet.
I used a for loop to keep calling Recv to see if there's a new message arriving at net.Conn
.
type Packet struct {
Length uint32
Data []byte
ReadOffset uint32
WriteOffset uint32
}
type Transport struct {
url string
conn net.Conn
}
// connect to url
func (transport *Transport) Dial(url string) error {
c, err := net.Dial("unixpacket", url)
if err != nil {
return err
}
transport.url = url
transport.conn = c
return nil
}
// sending Packet
func (transport *Transport) Send(p *Packet) bool {
readBuffer := (p.Data)[p.ReadOffset : p.WriteOffset]
_, err := transport.conn.Write(readBuffer)
if err != nil {
return false
}
return true
}
// receiving Packet
func (transport *Transport) Recv(p *Packet) bool {
writeBuffer := (p.Data)[p.WriteOffset :]
_, err := transport.conn.Read(writeBuffer)
if err != nil {
return false
}
return true
}
type Client struct {
Transport *Transport
RecvPacket *Packet
SendPacket *Packet
}
// keep checking transport
func (c *Client) ReadFromTransport() {
for {
time.Sleep(20 * time.Millisecond)
if c.Transport.Recv(c.RecvPacket) == false {
continue
}
}
}
Is there a method to have the net.Conn
get notified when a new message arriving instead of using a for loop?
Is there a method to have the net.conn get notified when a new message arriving net.conn instead of using a for loop?
No, not in the standard packages.
Read()ing from net.Conn in a loop is the usual way to detect message arrival. If you need to perform multiple concurrent tasks, you can encapsulate the loop in a goroutine writing to a channel and wrap a for-loop plus select around reading from that channel.
Outside of standard packages, you can explore event-driven IO with projects like https://github.com/tidwall/evio