-
Notifications
You must be signed in to change notification settings - Fork 57
Description
Hi, thanks for go-osc, it's great!
I'm working on adding TCP support to go-osc, both on the client and server side. In fact, I've just finished implementing it on my fork. It will be a while before I can make a PR, as I'm still testing the changes I've made. But I figured I would file an issue to give you a heads up and get some feedback about the changes, which I can summarize here.
API level
-
Clients and servers have a
SetNetworkProtocol(NetworkProtocol)method.- NetworkProtocol is a new enum with values UDP and TCP.
- UDP is the default. You can opt in to TCP:
client.SetNetworkProtocol(TCP) - This is the only change you need to make in order to send/receive TCP packets instead of UDP.
-
Added a
NewServerconstructor function that mirrorsNewClient- UDP is the default network protocol, can be overridden with
server.SetNetworkProtocol(TCP)
- UDP is the default network protocol, can be overridden with
-
Incidental: added a
server.CloseConnectionfunction to facilitate testing and give users the ability to forcibly stop a running server.server.servesetsserver.udpConnectionorserver.tcpListenerto the connection after creating it.server.CloseConnectioncloses the appropriate connection if it's not nil.ListenAndServeimplementation includesdefer server.CloseConnection(), ensuring that the connection it creates is closed in the event of an interruption or error.
Implementation level
-
Added the following fields to the Client struct:
laddrTCP *net.TCPAddrnetworkProtocol NetworkProtocol
-
Added the following fields to the Server struct:
udpConnection net.PacketConntcpListener net.Listener
-
client.SetLocalAddrsetsladdrorladdrTCP, depending on the protocol -
Added a
server.ServeTCP(net.Listener)that works likeserver.Serve(net.PacketConn).- Most of the implementation is the same, so I factored it into a common
server.serve(func() (Packet, error))function. - The only thing that's different is the mechanism for reading a packet.
- Most of the implementation is the same, so I factored it into a common
-
Added a
server.ReceiveTCPPacket(net.Listener)that works likeserver.ReceivePacket(net.PacketConn)- I had to do things slightly differently because we can't make assumptions about the size of the packets. So instead of making a 65535-byte array and reading data into it, I used
ioutil.ReadAllto read all of the bytes (until EOF) into a byte array. - Added some tests involving a million-byte message (works with TCP only; UDP has a packet size limit).
- I had to do things slightly differently because we can't make assumptions about the size of the packets. So instead of making a 65535-byte array and reading data into it, I used
-
Adjustments to tests
- Refactoring to enable reusing existing tests to test both UDP and TCP.
- Added a randomly generated string argument to the OSC messages in order to test packets being of a certain size.
- Handled errors in a couple of places where they were being ignored.
- This unearthed an issue where tests fail when the server is stopped, because it was in the middle of trying to read a packet and we closed the connection. I added a workaround to get tests passing.