I need some brave betatesters for a proof of concept.
For this test you can send text from a website form straight to maxscript.
How to make it work:
edit: you’ll have to run the script twice, first time you’ll get an error, second time works, and make sure not run it more then twice!
Copy/paste this maxscript in the script-editor and set node_id="" to something unique, use your forum name or something.
Save your work and run the script and watch the listener, it should state something like this:
“28-10-2011 11:29:54: Connected to 83.84.108.218:4015”
“28-10-2011 11:29:54: new connection”
“28-10-2011 11:29:54: received data”
“28-10-2011 11:29:54: MissionControl: Welcome, you’re registered as ‘GBL’”
“28-10-2011 11:30:00: received data”
(make sure to run the script only once, it doesn’t check for double/left over background workers etc yet… )
After that go to http://home.jdbgraphics.nl/maxlink/connect.php
Fill in your unique node_id and some random text in the data field, when you press ‘send’ it should show up in the listener like so:
“28-10-2011 11:39:37: received data”
“28-10-2011 11:39:37: Hello world!”
(use ‘ALL’ (caps) as node_id to send to all connected nodes, we can use the listener as a multi user chat box
)
send an ‘EXIT’ (caps) to make a clean exit.
This is how it works
[multiple max] <-> [socket server] <-> [ multiple (php <- web) ]
/* MaxControl proof of concept 1.0 */
/*Jonathan de Blok - www.jdbgraphics.nl */
clearlistener()
gc()
BackgroundWorker=""
ip_address = "83.84.108.218"
port = 4015
node_id="" -- ***insert unique ID here ****
-- void warranty below--
mySock="";
/* eventHandler for incomming data, data is a string, socket is source from which it came */
fn recEvent data socket = (
logEvent(data)
)
/* eventHandler for incomming new connections */
fn connectEvent socket = (
logEvent("new connection")
)
/* eventHandler for closing */
fn closeEvent sender socket = (
logEvent("closing..")
socket.Close()
sender.CancelAsync()
sender.Dispose()
)
---void warranty below----
/* simple function for logging events */
fn logEvent ev = (
print (localtime+": "+ev)
)
/* connect to existing socket using IP:PORT */
fn SocketConnect ip_address port =(
socket = dotNetObject "System.Net.Sockets.Socket" ( dotnetclass "System.Net.Sockets.AddressFamily" ).InterNetwork ( dotnetclass "System.Net.Sockets.SocketType" ).Stream ( dotnetclass "System.Net.Sockets.ProtocolType" ).Tcp
logEvent ("Connecting to "+ip_address +":"+(port as string))
while socket.connected!=true do (
try(
socket.connect ip_address port
) catch (
logEvent ("failed, retrying..")
sleep 2
)
)
logEvent("Connected to "+ip_address +":"+(port as string))
socket
)
-- connection manager
Fn receiveData sender e =
(
ip_address=e.Argument[1]
port=e.Argument[2]
callback_data=e.Argument[3]
callback_connect=e.Argument[4]
callback_close=e.Argument[5]
node_id=e.Argument[6]
recData=""
socket="";
Encoding = DotnetClass "System.Text.Encoding"
while recData!="EXIT" do
(
try (
theByteStream = DotNetObject "System.Byte[]" 4096
socket.Receive theByteStream -- blocking until it receives something
logEvent "received data"
recData = Encoding.UTF8.GetString(theByteStream)
execute ("cb="+callback_data)
cb recData socket -- call callback with received data as argument
) catch
(
--no socket yet or connection lost, try (re)connecting
socket = dotNetObject "System.Net.Sockets.Socket" ( dotnetclass "System.Net.Sockets.AddressFamily" ).InterNetwork ( dotnetclass "System.Net.Sockets.SocketType" ).Stream ( dotnetclass "System.Net.Sockets.ProtocolType" ).Tcp
logEvent ("Connecting to "+ip_address +":"+(port as string))
while socket.connected!=true do (
try(
socket.connect ip_address port
) catch (
logEvent ("Connecting...")
sleep 2
)
)
ascii_encoder = dotNetObject "System.Text.ASCIIEncoding"
bytes = ascii_encoder.GetBytes ( ("@manager:register:"+node_id) as string )
socket.Send bytes
logEvent("Connected to "+ip_address +":"+(port as string))
execute ("cb="+callback_connect)
cb socket
)
)
execute ("cb="+callback_close)
cb sender socket
)
/* Setup background worker with receiver function and user defined callback, callback is a string with the name of the function,not a pointer to the function itself */
fn SocketConnectFullDuplex ip_address port callback_data callback_connect callback_close node_id=
(
BackgroundWorker = DotNetObject "System.ComponentModel.BackgroundWorker"
DotNet.AddEventHandler BackgroundWorker "DoWork" receiveData
BackgroundWorker.WorkerSupportsCancellation = true
BackgroundWorker.RunWorkerAsync #(ip_address, port, callback_data, callback_connect, callback_close, node_id)
BackgroundWorker
)
/* Send a string to a socket */
fn SocketSend socket data = (
try (
ascii_encoder = dotNetObject "System.Text.ASCIIEncoding"
bytes = ascii_encoder.GetBytes ( data as string )
socket.Send bytes
logEvent ("data send")
) catch (
logEvent ("error sending data")
)
)
/*----------------------*/
if (node_id!="") then
(
--SocketCreate ip_address port "connectEvent" "recEvent" "closeEvent" -- create a new socket
SocketConnectFullDuplex ip_address port "recEvent" "connectEvent" "closeEvent" node_id -- start listening in the background for data, recieved is send to callback function
) else(
print "set node_id to something unique! exiting.."
)