Giter Club home page Giter Club logo

utopia's Introduction

Utopia

Utopia is a SuperCollider library for the creation of networked music applications, and builds upon the work of the Republic Quark and other existing network systems in SuperCollider. It aims to be modular (features available largely 'à la carte'), secure (provides methods for authentication and encryption), and flexible (to the extent possible, it tries not to impose a particular design or architecture). It provides functionality for synchronisation, communication, code sharing, and data sharing.

utopia's People

Contributors

adcxyz avatar coreyker avatar muellmusik avatar telephon avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

utopia's Issues

Send only to one user when in the network

Is there a method to send only to specific users when they are on the network, for example, how can I do something liek this:
~addrBook[\konstantinos].send('/el1', "Hello");

This doesn't seem to be working.

Persistence of objects after Cmd-.

This needs a think. Currently it's not consistent.

The main issues are to do with sending out signals in Hail, Registrar/-strant, and the Clock classes.

addrBook.me is not kept in sync with the peer's own entry in the address book

Hi Scott (and maybe Julian?),

I'm working with Jonas here in Guangzhou on a new project using two laptops and two BeagleBoards running Utopia for networking. Right now we're doing some basic ad hoc registration with the two laptops and then trying to share server addresses on top of that with an OSCObjectSpace, just to be able to play on each other's servers.

The OSCObjectSpace sync method doesn't work as expected. It tries to look for the first non-local player and make a copy of their object space, but this test fails because the peer contained in the address book has a remote IP, whereas the peer returned by 'addrBook.me' has a local IP. It seems like the latter should automatically be kept in sync with the former, is that right?

For now, to get around the problem we simply changed from this:

syncAddr = addr ?? { addrBook.peers.reject({|peer| peer == addrBook.me }).detect({|peer| peer.online }).addr };

To this:

syncAddr = addr ?? { addrBook.peers.reject({|peer| peer == addrBook[addrBook.me.name] }).detect({|peer| peer.online }).addr };

…so that we're not relying on the addrBook.me at all. But this is not a good long term solution. In general, we're confused as to why the local IP needs be added to the address book at all. Shouldn't the address book only ever contain remote address?

You can check the basic problem for yourself by running the code from Examples.scd:

(
~win = Window("AdHocSociety").front;
~win.layout = VLayout.new.add(~listView = ListView.new);

~addrBook = AddrBook.new;
// to get updates, just add a dependant
~addrBook.addDependant({|addrBook, what, who|
    {~listView.items = addrBook.peers.collectAs({|peer|
        peer.name ++ " | " ++ peer.addr.ip ++ " | " ++ if(peer.online, "online", "offline");
    }, Array)}.defer;
});

~addrBook.addMe; // will automatically add you using your user name

~hail = Hail(~addrBook);
)

Then executing these lines:

~addrBook.me // returns local address
~addrBook[~addrBook.me.name] // returns the remote address contained at the same name

The broader question is, why does addrBook.me have to be defined at all before Hailing. Why not only define it once the hail-reply has been received?

Cheers,
Jonas and Graham

Third Argument to Peer in Examples.scd

Hi all,

Just in the process of testing out these classes, and noticed what appears to be an error in two places in the Examples.scd, as follows:

Line 32:

Peer(\me2, NetAddr.localAddr, s.addr)

Line 63:

Peer(\me2, NetAddr.localAddr, s.addr)

For both these lines, isn't the third argument to Peer supposed to be the online status of the peer? Is there a reason for the server address here at all?

Regards,
Graham

What is the status of the Repulque classes?

I'm just trying to clean things up, as I'd like to do a proper release of Utopia, but I'm not sure what's happening with these classes. There seem to be three sorts of things here:

  • NMLShout - this is generally useful and I would propose to move it into the main class folder
  • Subclasses of Peer and Hail - Are these still valid/useful?
    • these seem mostly to be about alternative addressing approaches, which perhaps they could be done with a PeerGroup or similar approach?
    • Anything that should be moved to the superclasses? e.g. SkipJack for hailing signal is just to make it permanent, or?
  • Classes which seem to be unfinished: RepMap, RepMapGUI, and Reptopia

Alberto and Julian, what do you suggest?

Hail does not account for port changes on recompile

If a client crashes, or needs to do a hard restart of the interpreter, it is possible that it will rejoin the Utopia with a different lang port number. As it stands, Hail checks if the name exists in its AddrBook and only sets online status if it does. This means that the port in the AddrBook will be wrong, and you'll get access from unrecognised address warnings, etc.

I think the simplest solution is to check if the peer is offline, and if so reauthenticate and add again. That would also handle cases where the address changed for some reason (rather more unlikely, but possible if a restart was required and network membership is changeable). Note that authentication is a no-op by default, so there'd be no overhead in normal usage.

Any other thoughts?

Optimised way to share continuous streams of data to users

I am wondering which is the best way to share data with all users on the network, for example generating some values from a master computer and then make these available to everyone providing the solution we have now is a master computer generates the data and parses it to a dictionary then the dictionary is send as OSC message to the rest members using this way:
~addrBook.sendAll('/el', * ~eegBook); or to specific members using peers name and .send method. Is there a more efficient way than that?

still send_to: Host is down

We still get this all the time:

caught exception in primitive NetAddr:sendMsg
ERROR: send_to: Host is downERROR: Primitive '_NetAddr_SendMsg' failed.
Failed.
RECEIVER:
Instance of NetAddr {    (0x12cfb7258, gc=28, fmt=00, flg=00, set=02)
  instance variables [4]
    addr : Integer -1062705559
    port : Integer 57120
    hostname : nil
    socket : nil
}
CALL STACK:
	MethodError:reportError   0x12eba6f38
		arg this = <instance of PrimitiveFailedError>
	Nil:handleError   0x1811bd628
		arg this = nil
		arg error = <instance of PrimitiveFailedError>
	Thread:handleError   0x12f51b188
		arg this = <instance of Thread>
		arg error = <instance of PrimitiveFailedError>
	Object:throw   0x12eb9aa98
		arg this = <instance of PrimitiveFailedError>
	Object:primitiveFailed   0x12b5cd0d8
		arg this = <instance of NetAddr>
	Dictionary:keysValuesArrayDo   0x126a91158
		arg this = <instance of IdentityDictionary>
		arg argArray = [*20]
		arg function = <instance of Function>
		var i = 8
		var j = 2
		var key = nil
		var val = nil
		var arraySize = nil
	Dictionary:keysValuesDo   0x12f4582e8
		arg this = <instance of IdentityDictionary>
		arg function = <instance of Function>
	Dictionary:do   0x1859e9848
		arg this = <instance of IdentityDictionary>
		arg function = <instance of Function>
	AddrBook:sendExcluding   0x12b3f1418
		arg this = <instance of AddrBook>
		arg name = 'liuyawen'
		arg msg = [*4]
	OSCMessageDispatcher:value   0x125f67668
		arg this = <instance of OSCMessageDispatcher>
		arg msg = [*4]
		arg time = 6873.048582305
		arg addr = <instance of NetAddr>
		arg recvPort = 57120
	Main:recvOSCmessage   0x12864c4d8
		arg this = <instance of Main>
		arg time = 6873.048582305
		arg replyAddr = <instance of NetAddr>
		arg recvPort = 57120
		arg msg = [*4]
^^ The preceding error dump is for ERROR: Primitive '_NetAddr_SendMsg' failed.
Failed.
RECEIVER: a NetAddr 

Hail only adds peers when a reply is received. Is this correct?

Hail only adds peers when a reply to its own hailing signal is received, not when it receives a hailing signal.

Changing it so that it did the latter might make AddrBook population more robust when SC has more than one network interface available. The problem can be described as follows:

  • imagine 3 machines
  • two have wired and wireless connections, SC binds to the wired. This seems to mean it broadcasts on the wired, but still receives on the wireless
  • the third machine binds to the wireless.
  • Since the first two send on wired, they don't receive any replies from the third, and don't add it.
  • The third machine can see all three, but only receives its own hailing signals

This sort of situation is one reason (the only?) for the 'invisible machine' problem, and also WARNING: CodeRelay access attempt from unrecognised addr: a NetAddr(192.168.0.101, 57120) and similar warnings.

So would it cause problems to have Hail add Peers when a hailing message is received (and also count those for online status)?

Or (maybe better) use a range of test broadcast addresses, e.g. instead of just 255.255.255.255, perhaps instead/also hail to 192.255.255.255 and 147.255.255.255. This would cover all normal LAN ranges, or?

Is this a sensible way of sending ugen values in Utopia?

A fairly quick question: Is this the folllowing a sensible way of sending the contents of a control rate UGen graph via Utopia or is there a smarter way of doing that ? Thanks!

~updateFreq = 10;

// LFO1
    Ndef(\lfo1, {|f=0.25|
        var sig = SinOsc.kr(f.linexp(0.0,1.0,0.00001,100));
        SendReply.kr(Impulse.kr(~updateFreq), '/mlfo1', sig);
    });

    OSCdef(\lfo1, {|msg, time, addr, port|
        var val = msg[3];
        ~objSpace[\mlfo1] = val;
    }, '/mlfo1');

AddrBook sendExcluding, sendAll, etc. throw an error if a host has left the network

For example, run a BeaconClock and then have one of the computers disconnect from the network.

Should sendAll etc. only send to online peers? This would be a problem if a peer simply became unresponsive.

Alternatively one could use try and catch the PrimitiveFailedError. Possibly there should be more than two states, so maybe online, unresponsive, and down, or something like that.

OSCObjectSpace: Problem Archiving Closed Function

Hey Scott (and whoever else might be working on this!),

I've been experimenting with NML/Utopia and want to share a closed function using an OSCObjectSpace, but I have problems when I execute the following code.

(
~aFunc = {\test.postln};
~peer1 = Peer(\me1, NetAddr.localAddr);
~addrBook1 = AddrBook().addMe(~peer1);
~objSpace1 = OSCObjectSpace(~addrBook1, oscPath:'/objSpace'); // me1's local copy
~objSpace1.put(\me1, ~aFunc); // me1 adds her Server addr
)

Here's the error I get:

ERROR: cannot archive Frames.
ERROR: Primitive '_AsArchive' failed.
Failed.
RECEIVER:
Instance of Function { (0x11479a5d8, gc=88, fmt=00, flg=80, set=02)
instance variables [2]
def : instance of FunctionDef - closed
context : Frame (0x10b903658) of Interpreter:functionCompileContext
}
PATH: /Users/grahambooth/Library/Application Support/SuperCollider/Extensions/Utopia-master/classes/NMLRelays.sc
CALL STACK:
MethodError:reportError 0x1134465d8
arg this =
Nil:handleError 0x113446aa8
arg this = nil
arg error =
Thread:handleError 0x113449a18
arg this =
arg error =
Object:throw 0x1134477b8
arg this =
Object:primitiveFailed 0x11344c408
arg this =
OSCObjectSpace:updatePeers 0x113451ec8
arg this =
arg key = 'me1'
arg value =
AbstractOSCDataSpace:put 0x10b796818
arg this =
arg key = 'me1'
arg value =
OSCObjectSpace:put 0x1134bba68
arg this =
arg key = 'me1'
arg value =
Interpreter:interpretPrintCmdLine 0x114b22218
arg this =
var res = nil
var func =
var code = "(
~aFunc = {\test.postln};
~..."
var doc =
var ideClass =
Process:interpretPrintCmdLine 0x10b741f38
arg this =
^^ The preceding error dump is for ERROR: Primitive '_AsArchive' failed.
Failed.
RECEIVER: a Function

Here's my own attempt to archive the function:

~aFunc.asBinaryArchive

This doesn't throw an error, and return (correctly I think) an Int8Array.

However when the same thing is done in the OSCObjectSpace source (value.asBinaryArchive, where value is apparently the self-same function), the frame error occurs.

updatePeers {|key, value|
        addrBook.sendExcluding(addrBook.me.name, oscPath, key, encryptor.encryptBytes(value.asBinaryArchive));
}

Everything seems okay here:

OSCObjectSpace:updatePeers   0x113451ec8
    arg this = <instance of OSCObjectSpace>
    arg key = 'me1'
    arg value = <instance of Function>

Any ideas? I guess the other way to do it would be archive the function as a compile string and share that using an OSCDataSpace, but that seems clunky.

Any help appreciated.

Regards,
Graham

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.