Websockets for jsdb, anyone?

25 views
Skip to first unread message

code beat

unread,
Jul 25, 2018, 12:32:08 PM7/25/18
to JSDB
The latest post is dated somewhere 2015 so yeah, dunno anyone will reply on this (in 2018).

I really like jsdb because it is so easy, made some fileservers with it and works pretty well.
Now I made a simple server that can access the com-port, however, want to make the connection to the server as fast as possible.
I want to use websockets for this, so there is permanent connection.

Anyone done this before, is possible anyway?

Thanks for the help, kind regards,
codebeat.


Shanti Rao

unread,
Jul 25, 2018, 12:46:42 PM7/25/18
to js...@googlegroups.com, code beat
Howdy,

It's single-threaded, so you can only talk to one Stream at a time. But there's a really efficient function, system.wait([stream1, stream2, ...], timeout) that sleeps the server until one of the streams receives a request. It returns a list of streams that are signalled.

So you could do something like this to simulate a multithreaded server. As long as none of the responses are too processor-intensive, it works fine as a web server.

s = new Server;
var connections = [s];

while (forever)
{
  var active = system.wait(connections, 2000);
  if (!active) continue; //timeout
  for each(var x in active)
  {
    if (x.constructor.name === 'Server') connections.push(x.accept());
    else if (x.constructor.name === 'Stream') handleRequest(x);
  }
}

Shanti
--
You received this message because you are subscribed to the Google Groups "JSDB" group.
To unsubscribe from this group and stop receiving emails from it, send an email to jsdb+uns...@googlegroups.com.
To post to this group, send email to js...@googlegroups.com.
Visit this group at https://groups.google.com/group/jsdb.
For more options, visit https://groups.google.com/d/optout.

code beat

unread,
Jul 26, 2018, 12:26:56 PM7/26/18
to JSDB
Hai Shanti,

Thanks for your reply! I didn't notice jsdb is single threaded anyway, this because I didn't use any fancy stuff before, just reply to the (single) request which is working fine. I made some.audio fileservers in the past, pretty good.

I understand now that websockets is impossible, because it is single threaded. However is it possible to open a continuous stream with the client? This to eliminate connection delays by polling the server.

About your provided solution, your solution is nice, I discovered two problems with a comport stream:
a) When I call system.wait( <stream var>, <delay> ); get an error "is not a function", meaning the stream is not a function when still created;
b) The comport stream.canRead returns allways false even when there is data on the bus. If I call stream.getByte() I get bytes (also a null byte or sometimes smilies (ASCII character 2) when there is no data (still stream.canRead is false before calling getByte()), memory allocation problem when there are smilies?)


When I call system.wait( <server var>, <delay> );it is working fine. I use this in my server.update() function.

Here is an example how I use it (server class):
this.update = function()
{
 if( !this.running )
  { return false; }

 
 if( !system.wait( this.http, 0 ) )
  { return false; }
 
 if( !this.http.anyoneWaiting )
  { return false; }
 
 system.gc();
 
 var client = this.http.accept();
 
 if( client == null || !client.canRead )
  {
    return false; 
  }

 .......................
 .......................
 etc....
}

And the main loop looks like this:
while (!system.kbhit())
 {
    if( !server.update() )
     {
        serial.update();
     }
 }


However, I can't use system.wait( <stream var>, <delay> ); at serial.update() function and cannot use serial.stream.canRead to determine there is any data because it always returns false.

i decided to use a workaround by calling stream.getByte() however this cause a performance delay because the serial port is initialized with a timeout, however this depends on current port settings. JSDB only gets the current config and configures the baudrate and that's it?

Now I am using stream = new Stream('COM'+comPort+'://'+baudRate, "rwactb" ); and there is no exceptional delay when using stream.getByte(), however I need to run another program that sets the port settings to the correct settings and then create the com stream, this works as expected.

I created a batch file (windows) to set the com parameters before creating the stream.
setcom.bat
@echo off
mode COM%1 baud=%2 parity=n data=8 stop=1 to=off xon=off odsr=off octs=off dtr=off rts=off idsr=off >NUL


To give you some idea how I use it:

function serialStream = function()
{
  ...........................
  ...........................

this.open = function( iComPort, iBaudRate )
  {
   this.close();
  
   this.comPort  = __ifUndef( iComPort , 1 );
   this.baudRate = __ifUndef( iBaudRate, TSS_DEFAULT_BAUD );
  
   system.execute( 'setcom.bat', this.comPort+' '+this.baudRate );
   sleep( 1000 ); // Need some delay to execute, avoid port is in use.    
  
   try { this.stream = new Stream('COM'+this.comPort+'://'+this.baudRate, "rwactb" ); }
   catch( e ) { this.stream = false; }
 
   return ( this.isConnected() );
  };

 .......................
 ......................
}

Anyway, any idea why the stream.canRead always return false (also tried "rwactb+") ?And, althought my comport solution works fine, is there more elegant way to do this?

Some info JSDB:
system builddate: May 17 2012, release: 1.8.0.7, js-version: 1.8

OS:
Windows 7 Ultimate, 64bit, 16GB ram

Thank for any reply, kind regards,
codebeat


Op woensdag 25 juli 2018 18:46:42 UTC+2 schreef Shanti Rao:

Shanti Rao

unread,
Jul 26, 2018, 12:31:00 PM7/26/18
to JSDB
Polling works great for TCP/IP sockets, not so great for comm ports. Windows has always been buggy at that. Here's the code, in rs/io_comm.cpp

bool CommStream::canread()
{
 DWORD mask = 0;
 GetCommMask(File,&mask);
 return (mask & EV_RXCHAR);
// return WaitForSingleObject(File,0) == WAIT_OBJECT_0;
}

If Windows chooses not to implement its own API, there's not much we can do about it. I usually read bytes into a buffer, managed in JS, and then check whether that buffer is full.

code beat

unread,
Jul 26, 2018, 2:50:30 PM7/26/18
to JSDB
Hi, thanks for the answer.

Aha, that's the problem, you need to do this ( assuming File is a handle to a file ):

bool CommStream::canread()
{
  COMSTAT stats;
  DWORD error;
 
 ClearCommError( File, &error, &stats );

 return (stats.cbInQue > 0)?true:false;
};

I use this method in Delphi and C++.as isDataAvailable() and works fine.

Greetz,
codebeat



Op donderdag 26 juli 2018 18:31:00 UTC+2 schreef Shanti Rao:
Reply all
Reply to author
Forward
0 new messages