How do I connect sclang to an already running server?

I have tried starting a server using various means, e.g.,:

o = ServerOptions.new;
o.maxLogins = 100;
s = Server(\myserver, NetAddr("127.0.0.1", 57110), o);
s.boot;
❯ /Applications/SuperCollider.app/Contents/Resources/scsynth -u 57110 -a 1024 -i 2 -o 2 -R 0 -l 100  -B 127.0.0.1          
Number of Devices: 4
   0 : "Built-in Microph"
   1 : "Built-in Output"
   2 : "Background Music"
   3 : "Background Music (UI Sounds)"

"Built-in Microph" Input Device
   Streams: 1
      0  channels 2

"Built-in Output" Output Device
   Streams: 1
      0  channels 2

SC_AudioDriver: sample rate = 44100.000000, driver's block size = 512
SuperCollider 3 server ready.

But I can’t get sclang to connect to this server non-interactively. In interactive usage, using:

Server.default.addr.port = 57110;

s.startAliveThread({SinOsc.ar([400, 404])}.play);

Works, but running the same using sclang tmp.scd produces these errors:

compiling class library...
	Found 850 primitives.
	Compiling directory '/Applications/SuperCollider.app/Contents/Resources/SCClassLibrary'
	Compiling directory '/Users/evar/Library/Application Support/SuperCollider/Extensions'
	numentries = 817296 / 11914364 = 0.069
	5362 method selectors, 2222 classes
	method table size 13037592 bytes, big table size 95314912
	Number of Symbols 12022
	Byte Code Size 360460
	compiled 322 files in 0.67 seconds
compile done
localhost : setting clientID to 0.
internal : setting clientID to 0.
Class tree inited in 0.01 seconds


*** Welcome to SuperCollider 3.11.0. *** For help type cmd-d.
localhost server not running!
WARNING: server 'localhost' not running.
ERROR: Message 'wait' not understood.
RECEIVER:
   nil
ARGS:
PATH: a.sclang

PROTECTED CALL STACK:
	Meta_MethodError:new	0x11813cd80
		arg this = DoesNotUnderstandError
		arg what = nil
		arg receiver = nil
	Meta_DoesNotUnderstandError:new	0x11813ed40
		arg this = DoesNotUnderstandError
		arg receiver = nil
		arg selector = wait
		arg args = [  ]
	Object:doesNotUnderstand	0x1198ed8c0
		arg this = nil
		arg selector = wait
		arg args = nil
	a FunctionDef	0x119250280
		sourceCode = "<an open Function>"
	Routine:prStart	0x1188ca780
		arg this = a Routine
		arg inval = 0.936724161

CALL STACK:
	DoesNotUnderstandError:reportError
		arg this = <instance of DoesNotUnderstandError>
	< closed FunctionDef >
		arg error = <instance of DoesNotUnderstandError>
	Integer:forBy
		arg this = 0
		arg endval = 0
		arg stepval = 2
		arg function = <instance of Function>
		var i = 0
		var j = 0
	SequenceableCollection:pairsDo
		arg this = [*2]
		arg function = <instance of Function>
	Scheduler:seconds_
		arg this = <instance of Scheduler>
		arg newSeconds = 0.955014329
	Meta_AppClock:tick
		arg this = <instance of Meta_AppClock>
		var saveClock = <instance of Meta_SystemClock>
	Process:tick
		arg this = <instance of Main>
^^ The preceding error dump is for ERROR: Message 'wait' not understood.
RECEIVER: nil

http://doc.sccode.org/Classes/Server.html#*remote – which refers to “another machine” but the “remote” address may be localhost.

Also make sure the server had been started with enough maxLogins (in ServerOptions). If you started the server with only one available login, then another sclang will not be able to connect to it. ok, you did that :+1:

hjh

This works when I do it interactively, but it still doesn’t produce any sound when I run it as a script:

Server.default.addr.port = 57110;
o = ServerOptions.new;
o.maxLogins = 100;
r = Server.remote(\myserver, NetAddr("127.0.0.1", 57110), o);
Server.default = r;

{SinOsc.ar([400, 404])}.play(r);

Here is the output:

❯ sclang a.sclang                                                                                                         
compiling class library...
	Found 850 primitives.
	Compiling directory '/Applications/SuperCollider.app/Contents/Resources/SCClassLibrary'
	Compiling directory '/Users/evar/Library/Application Support/SuperCollider/Extensions'
	numentries = 817296 / 11914364 = 0.069
	5362 method selectors, 2222 classes
	method table size 13037592 bytes, big table size 95314912
	Number of Symbols 12022
	Byte Code Size 360460
	compiled 322 files in 1.00 seconds
compile done
localhost : setting clientID to 0.
internal : setting clientID to 0.
Class tree inited in 0.02 seconds


*** Welcome to SuperCollider 3.11.0. *** For help type cmd-d.
myserver : setting clientID to 0.
WARNING: server 'myserver' not running.
Requested notification messages from server 'myserver'
myserver: server process has maxLogins 128 - adjusting my options accordingly.
myserver: keeping clientID (0) as confirmed by server process.

I tried r.waitForBoot{ {SinOsc.ar([400, 404])}.play }; but this kills the server and starts a new one.

Not well documented, but it should be like this:

(
fork {
	var cond, runResponder;
	
	Server.default = s = Server.remote(\remote, NetAddr("127.0.0.1", 57110));
	
	cond = Condition({ s.serverRunning });
	
	// 'signal' will allow the forked routine to advance
	// only when 'serverRunning' finally becomes true
	runResponder = SimpleController(s).put(\serverRunning, { cond.signal });
	
	cond.wait;
	
	runResponder.remove;
	a = { SinOsc.ar(440, 0, 0.1).dup }.play;
};
)

hjh

1 Like

Thanks, this works! I get a lot of FAILURE IN SERVER /g_new negative node IDs are reserved errors on the server. Is that normal?

AFAICS in the code, this shouldn’t happen in the class library.

What is the highest client ID you’re actually being assigned? Look for a message like “setting clientID to (number).”

Btw maxLogins shouldn’t be > 32. Currently it allows you to set maxLogins = 100 but once you get past clientID 31 (the 32nd user) you’ll get an error from the node ID allocator.

hjh