@@ -51,12 +51,17 @@ const (
51
51
const (
52
52
// RootNodeID is what sclang uses as the root node ID. See http://doc.sccode.org/Classes/RootNode.html.
53
53
RootNodeID = int32 (0 )
54
+
54
55
// DefaultGroupID is what sclang uses for the default group ID. See http://doc.sccode.org/Reference/default_group.html.
55
56
DefaultGroupID = int32 (1 )
57
+
56
58
// DefaultLocalAddr is the listening address for DefaultClient.
57
59
DefaultLocalAddr = "0.0.0.0:57110"
60
+
58
61
// DefaultScsynthAddr is the remote address for DefaultClient.
59
62
DefaultScsynthAddr = "0.0.0.0:57120"
63
+
64
+ DefaultConnectTimeout = time .Second
60
65
)
61
66
62
67
// Common errors.
@@ -89,7 +94,7 @@ const numDoneHandlers = 8
89
94
// NewClient creates a new SuperCollider client.
90
95
// The client will bind to the provided address and port
91
96
// to receive messages from scsynth.
92
- func NewClient (network , local , scsynth string ) (* Client , error ) {
97
+ func NewClient (network , local , scsynth string , timeout time. Duration ) (* Client , error ) {
93
98
addr , err := net .ResolveUDPAddr (network , local )
94
99
if err != nil {
95
100
return nil , err
@@ -102,7 +107,7 @@ func NewClient(network, local, scsynth string) (*Client, error) {
102
107
addr : addr ,
103
108
nextSynthID : 1000 ,
104
109
}
105
- if err := c .Connect (scsynth ); err != nil {
110
+ if err := c .Connect (scsynth , timeout ); err != nil {
106
111
return nil , err
107
112
}
108
113
return c , nil
@@ -118,7 +123,7 @@ func DefaultClient() (*Client, error) {
118
123
var err error
119
124
120
125
if defaultClient == nil {
121
- defaultClient , err = NewClient ("udp" , DefaultLocalAddr , DefaultScsynthAddr )
126
+ defaultClient , err = NewClient ("udp" , DefaultLocalAddr , DefaultScsynthAddr , DefaultConnectTimeout )
122
127
if err != nil {
123
128
return nil , err
124
129
}
@@ -131,17 +136,30 @@ func DefaultClient() (*Client, error) {
131
136
}
132
137
133
138
// Connect connects to an scsynth instance via UDP.
134
- func (c * Client ) Connect (addr string ) error {
139
+ func (c * Client ) Connect (addr string , timeout time. Duration ) error {
135
140
raddr , err := net .ResolveUDPAddr ("udp" , addr )
136
141
if err != nil {
137
142
return err
138
143
}
139
144
140
- oscConn , err := osc .DialUDP ("udp" , c .addr , raddr )
141
- if err != nil {
142
- return err
145
+ // Attempt connection with a timeout.
146
+ var (
147
+ start = time .Now ()
148
+ timedOut = true
149
+ )
150
+ for time .Now ().Sub (start ) < timeout {
151
+ oscConn , err := osc .DialUDP ("udp" , c .addr , raddr )
152
+ if err != nil {
153
+ time .Sleep (100 * time .Millisecond )
154
+ continue
155
+ }
156
+ c .oscConn = oscConn
157
+ timedOut = false
158
+ break
159
+ }
160
+ if timedOut {
161
+ return errors .New ("connection timeout" )
143
162
}
144
- c .oscConn = oscConn
145
163
146
164
// listen for OSC messages
147
165
go func () {
0 commit comments