gsrv2

introduction

gsrv2 is an OSC message hub. it supports plain osc messages over the UDP protocol as used in most (all?) OSC-supporting applications, and a special plaintext protocol over TCP that was developed to support flash clients which dont do UDP sockets.

the main function is dispatching of incoming messages to hosts that ""subscribed" to these messages. basically you set up some progam to throw messages at the gsrv2. then, set up a program to receive some of theses messages. then you tell the server that your program ist interested in some of theses messages. all matching incoming messages are the delivered to your receiving program.

every message other than a gsrv specific command (which are very few) will be registered in the server. the / command lists all available (all ever seen) messages on the server.

gsrv2 uses sdl - simple directmedia layer:
a very useful lib that abstracts away the intrinsics of graphics, sound (to an extent), threads and network operations in a platform independent way. its running on linux currently, but it should be possible with a minimum amount of work to port it to win32 and osx.

an api on top of sdl_net is used as well: net2, a clever skeleton for high-performance (game-) servers. no graphic functions are used, this is accomplished by the use of the sdl dummy video driver. sdl is designed to be a game engine and the use of video is somewhat vorgeschrieben. the dummy driver does not add noticeable overhead to the program. and who knows, if gfx are needed any tme in the future - zack: nema problema.

its implemented c++. no discussion please.

the main app handles lists of instances of a few classes, namely Message, Client, Subscription.
each client has a list of subscriptions. a subscription is an osc-compatible pattern, i.e. "/bla", "/blurz/plopp/*" or similar.

on each incoming message the server scans the subscription lists and applies the pattern matching. if that resolves to true, the message is sent to the client.

each of these have some vital attributes:

Message

name - the name of the message, including the OSC-style / at the beginning

statistical data: history of seen parameter signatures, max/min/avrg of all values seen to date etc.

timeout - if we dont receive a message for a long time, it gets killed from the list of active messages. in the future, data probably gets swapped out on timeout to some form of non-volatile storage and could be read in again (ja! serialisieren!). data could survive server reboots as well with such a mechanism. this is all not implemented yet...

Client

ip address

statistical data like firstcontact, lastcontact, messages received

protocol: osc/upd, plaintext/tcp.

socket - necessary for tcp connections

timeout - for clients with udp protocols there has to be a timeout to simulate a "dropped connection". in tcp land, there is no doubt about the state of a connection.

subscriptions: list of patterns to be matched with incoming messages. this is not implemented yet.

Subscription

pattern

some statistical data (not done yet)

open questions:

whats the deal with timetags? should be transparently multiplexed. the server does not know anything about fine grained osc time units. neither does the to-be-defined- plain text protocol, the latter could pose a problem if clients really schedule things to happen a week into the future.

whats the deal with bundles? bundles would have to be dissected into single messages on receive and handled as single messages after that. this is by far not an elegant solution, but its simple. this would require some deeper changes on the server side, so we leave that for the future. an easy route would be dissection of the bundle on reception, and process single messages afterwards. there is a potential problem here because in theory it is possible that messages change their order of reception. we maybe can get away by just pretending that this never happens. if the bundle is timestamped, we could tamper with the timestamp to exure we preserve the right order of execution.

connections. for various reasons it would be good to maintain a list of active connections, a term which is only loosely defined when it comes to udp messages, since ther is no connection on the network layer by definition. one would have to deal with timeouts and cascading deletes if a message or client times out. timeout values get stored already.

preserving state across reboots. the server should handle restarts gracefully by writing client and message objects to disk and reread them at boot time. ahh, serialization fun! what is with tcp-based clients? they cannot be restored because the tcp connection cannot be restored. so only udp-based clients and all the messages get persistent storage?

the response ports are the ports to which a response (the result of a request type dialogue like the / message) is sent by default, since simple clients (sendOSC, pd, etc) might have a hard time reading from the same port they have sent the request message from.

ex: a client sends a / command, the multplexer server responds with a list of message strings and sends it to the calling ip and the standard response port for the protocol.

gsrv2 understands these messages

the most important commands here: sub/unsubscription fpr messages. note that you subscribe to a pattern. if you subscribe to /* then you get ALL messages delivered.

/sub

/unsub

/unsuball for convenience method to sign off

each of these three respond with multiple messages. at the end a "/endofcmd clients|subscriptions|messages is sent.

/

/clients

/subscriptions

each responds with a list of messages|clients|subscriptions.

not done / not sure:

/forward (TCP socket return port handling for e.g. /map requests?). this is not there yet.

/annotate messagename well behaving message providers could send an annotation message on startup to describe what they have to offer. is this the way to go? or should the provider be asked for this info and answer via the /forward mechanism?

/resetserver for resetting the server, cutting off all clients and clearing all messages. possibly password protected in some way. some kind of notification should be sent as well.

internal messages available to subscribe:

gsrv2 generates some messages on its own, giving some info about the internal state changes. its possible (soon) to assign a name to the gsrv instance on startup. this name will be prepended to all of these messages to have a potential distinction between sveral running gsrvs.

/_gservname_/new/message

/_gservname_/new/client

/_gservname_/new/subscription

/_gservname_/delete/message

/_gservname_/delete/client

/_gservname_/delete/subscription

these are messages generated by the server. each of these is followed by some specific data.

the plaintext protocol

this was developed for flash clients on tcp connections. there is some demo code for this: GulizEr. data is transmitted via url-encoded strings. there is always a message parameter (m), a typetag parameter (t) and 0..n data fields (p0..pn).

examples:

OSC message /hey,3,4,5,hopp

PT message m=/hey&t=iiis&p0=3&p1=4&p2=5&p3=hopp

this is easy to parse on the flash side with built-in functions. the whole thing was inspired by the FLOSC server project, which does the same, but converts to xml documents. this leads to sluggish performance and seems like raping the decidedly lightweight and easy OSC protocol.