Websocket stability handling and duplicate sockets

857 views
Skip to first unread message

Eric Geer

unread,
Dec 16, 2016, 1:46:31 AM12/16/16
to DroidScript
Hi Folks, working to build a robust system to auto-reconnect in the event of socket drop.   I'm taking advantage of app.SetOnError, ws.onclose, and ws.onerror to re-open the socket.  The behavior I've witnessed however, is that the server code tends to remember the prior socket connections even though the client code believes to have closed or errored out.  So what ends up happening, is if you send message using the button, you get response times connections the server believes are open.  My question is, how would you mitigate the server duplicating the connections?  I suppose somehow I'd need to regularly scan the clients array and remove duplicates?


Client Code=====================

var socket = '';

function OnStart()
{
//Open web socket to phone.
app.SetOnError( ws_onerror );
ws_opensocket();
}

function ws_opensocket()
{
    if ( socket == "error" | socket == "closed" ) {
        console.log( "Recovering from " + socket + " socket after 20 seconds" );
        sleep ( 20000 );
    }
ws = new WebSocket( "ws://172.17.0.209:8080/" );
ws.onopen = ws_onopen;
ws.onmessage = ws_onmessage;
ws.onclose = ws_onclose;
ws.onerror = ws_onerror;
}

//Handle socket open.
function ws_onopen()
{
console.log(  "Socket Open" );
socket = "open";
}

//Handle messages from phone.
function ws_onmessage( msg ) 
{
console.log( msg.data );
if ( msg.data == "armstate" ) console.log( "run armstate" );
}

//Other websocket callbacks.
function ws_onclose() { 
    console.log( "Socket Closed" );
    socket = "closed";
    ws_opensocket();
}
function ws_onerror(e) {
    console.log( "Socket Error: " + e.data );
    socket = "error";
    ws_opensocket();
}

function sleep( time )
{
    var now = new Date().getTime();
    console.log( "Sleeping: " + ( time / 1000 ) + "sec");
    while( new Date().getTime() < now + time ) {}
}

end client code==============

server code================

//Called when application is started.
function OnStart()
{
//Check wifi is enabled.
ip = app.GetIPAddress();
if( ip == "0.0.0.0" ) { 
app.ShowPopup( "Please Enable Wi-Fi" ); 
app.Exit();
}
//Prevent wifi from powering down.
    app.PreventWifiSleep();
//Create a layout with objects vertically centered.
lay = app.CreateLayout( "linear", "VCenter,FillXY" );

//Create a text label and add it to layout.
txt = app.CreateText( ip, 0.8, 0.3, "AutoScale,MultiLine" );
txt.SetTextSize( 22 );
lay.AddChild( txt );
//Create a 'Send Message' button.
btn = app.CreateButton( "Send Message", 0.4, 0.1 );
btn.SetMargins( 0, 0.05, 0, 0 );
btn.SetOnTouch( SendMessage );
lay.AddChild( btn );
//Add layout to app.
app.AddLayout( lay );
//Create and run web server on port 8080.
    serv = app.CreateWebServer( 8080 );
    serv.SetFolder( "/sdcard/DroidScript" );
    serv.Start();
//Start timer to show WebSock connections.
setInterval( ShowConnections, 3000 );
}
//Show who is connected.
function ShowConnections()
{
var clients = serv.GetWebSockClients();
if( clients.length > 0 )
{
    //Make a list of clients.
    var list = "";
    for( var i=0; i<clients.length; i++ ) list += clients[i].remoteAddress + "\n";

    //Show client list.
    txt.SetText( list );
}
}

//Send a message to all connected socket clients.
function SendMessage()
{
    //Note: You can send to a specific client by passing
    //the IP address as the second parameter.
serv.SendText( "Hello " + (new Date()).toLocaleString() )
}

end server code============

Charles Wilt

unread,
Dec 16, 2016, 7:22:48 AM12/16/16
to DroidScript
Do the duplicates show up in your client list on the server?

Symbroson Development

unread,
Dec 16, 2016, 10:53:35 AM12/16/16
to DroidScript
Somewhere I've posted an WS Demo before - I've attached ot again
if I run your code the ws isnt opened - maybe I forgot the index.html file
Please give me a feedback if it is working in you use my app.
If it does you could use it bit I'm not sure

Symbroson Development

unread,
Dec 16, 2016, 11:25:53 AM12/16/16
to DroidScript
Sorry i forgot to attach the spk 🙊
Socket Demo.spk

Eric Geer

unread,
Dec 16, 2016, 10:49:10 PM12/16/16
to DroidScript
Correct, they show up in the client lists on the server.

Dave Smart

unread,
Dec 17, 2016, 8:50:23 AM12/17/16
to DroidScript
Hi Eric,

Have you tried using the built-in app.CreateWebSocket() method?  That is designed to keep reliable web sockets open at all times.

P.S. I never got a reply about the results of the app.GetModel() call on your particular Leel Box. (you can just use the DS docs to get the results). I need the model code to make sure DS works on that particular model.

Regards
David

Symbroson Development

unread,
Dec 17, 2016, 9:14:55 AM12/17/16
to DroidScript
If someone found that getModel isnt working he would had informate you.
So for me it is working ;)

Dave Smart

unread,
Dec 17, 2016, 9:20:39 AM12/17/16
to DroidScript
Thanks Alex, but that's not the point.  I need to know the model id of his Leel box so I can make DS behave properly for that device (so you don't need to use a config.json file).

I don't want to hijack this thread, but he has not been replying to my direct messages.

Eric Geer

unread,
Dec 18, 2016, 3:01:13 AM12/18/16
to DroidScript
app.GetModel only responds with  "Leelbox" and nothing else, unfortunately.

FWIW, I've now been able to get my pebble watch to communicate over WebSockets to DroidScript directly.
Reply all
Reply to author
Forward
0 new messages