Non-blocking Sockets with PerlScript on Win XP

T

Tresh

Hello !

I'm developping an application for testing purpose which is based on a
HTML page with perlScript.
This application communicates thru sockets (i'm coding both client and
server version of the application)

Basically, it waits for some message and do some actions when the
correct message has been received.
these actions include a reply to the received message.
perlScript is used here to create powerful scenarios, which can be made
by the users of the application.

The main problem here comes from the blocking read of the socket. For
example, a scenario is launched from the HTML interface. This scenario
connects the client socket to a server and then waits for a message
from this socket. When perl executes this, while waiting, the HTML
interface freezes, so we can't click on the "stop button" of the
scenario.
That's the problem.

I'm giving a part of the code :
function testSocket which checks during 100ms if there is some data to
read on the socket.
function waitMsg which calls testSocket and handles a timeout

sub testSocket()
{
# timeout 100 ms
my $timeout = 0.1;
@ready = $sel->can_read($timeout);
if (@ready > 0)
{
foreach $fh (@ready)
{
if ($fh == $sock)
{
return 1; #data ok : will read it
}
else
{
# Maybe we have finished with the socket
$sel->remove($fh);
$fh->close;
}
}
}
return 0;
}


sub waitMsg(;$)
{
#timeout in ms (now must be a multiple of 100)
my $timeout = shift;
my $res = testSocket();
if ($res == 1)
{
return getMsg();
}
else
{
if ($timeout eq "")
{
# no timeout, infinite wait
return waitMsg();
}
else
{
if ($timeout == 0)
{
#timeout !!!
return (-1, "");
}
#recursive call
return waitMsg($timeout - 100);
}
}


The scenario must NOT continue until we have received a message or
until we reach the timeout. But the HTML-page must also NOT freeze so
that we can use the buttons on the page

Any Idea ?

Thanks !

Tresh
 
N

Nick of course

Tresh said:
Hello !

I'm developping an application for testing purpose which is based on a
HTML page with perlScript.
This application communicates thru sockets (i'm coding both client and
server version of the application)

Basically, it waits for some message and do some actions when the
correct message has been received.
these actions include a reply to the received message.
perlScript is used here to create powerful scenarios, which can be made
by the users of the application.

The main problem here comes from the blocking read of the socket. For
example, a scenario is launched from the HTML interface. This scenario
connects the client socket to a server and then waits for a message
from this socket. When perl executes this, while waiting, the HTML
interface freezes, so we can't click on the "stop button" of the
scenario.
That's the problem.

I'm giving a part of the code :
function testSocket which checks during 100ms if there is some data to
read on the socket.
function waitMsg which calls testSocket and handles a timeout

sub testSocket()
{
# timeout 100 ms
my $timeout = 0.1;
@ready = $sel->can_read($timeout);
if (@ready > 0)
{
foreach $fh (@ready)
{
if ($fh == $sock)
{
return 1; #data ok : will read it
}
else
{
# Maybe we have finished with the socket
$sel->remove($fh);
$fh->close;
}
}
}
return 0;
}


sub waitMsg(;$)
{
#timeout in ms (now must be a multiple of 100)
my $timeout = shift;
my $res = testSocket();
if ($res == 1)
{
return getMsg();
}
else
{
if ($timeout eq "")
{
# no timeout, infinite wait
return waitMsg();
}
else
{
if ($timeout == 0)
{
#timeout !!!
return (-1, "");
}
#recursive call
return waitMsg($timeout - 100);
}
}


The scenario must NOT continue until we have received a message or
until we reach the timeout. But the HTML-page must also NOT freeze so
that we can use the buttons on the page

Any Idea ?

Thanks !

Tresh

You're using recursion where iteration would be more appropriate. If
can_read() never returns true you'll eventually get a stack overflow.
 
T

Tresh

You're using recursion where iteration would be more appropriate. If
can_read() never returns true you'll eventually get a stack overflow.

That's right, I'll fix that. But the problem is about the freeze.

The user script defines a method "playScenario" which is in fact the
scenario itself. I thought i could use threads to execute this method
in a thread detached from the Mmi, but it doesn't work well (I got an
internal error when doing that)
 
X

xhoster

Tresh said:
Hello !

I'm developping an application for testing purpose which is based on a
HTML page with perlScript.
This application communicates thru sockets (i'm coding both client and
server version of the application)

Basically, it waits for some message and do some actions when the
correct message has been received.
these actions include a reply to the received message.
perlScript is used here to create powerful scenarios, which can be made
by the users of the application.

The main problem here comes from the blocking read of the socket.

I don't think that that is the main problem. AFAICT, PerlScript is not
interuptible whether they are blocking on a socket, sleeping, or just
counting to a zillion.
For
example, a scenario is launched from the HTML interface. This scenario
connects the client socket to a server and then waits for a message
from this socket. When perl executes this, while waiting, the HTML
interface freezes, so we can't click on the "stop button" of the
scenario.
That's the problem.

I suspect you have an ActiveX problem, or an ActiveState problem, or
a Microsoft problem, or an ActiveX Scripting problem, or an integration
problem of all of the above.

What you have showed is pure Perl. It doesn't reproduce your problem, as
(to start with) there is no "stop button" in Perl. Some might argue that
this is the not correct place to ask PerlScript questions. I'm not sure if
I agree with that or not, but it certainly isn't the place to ask
PerlScript questions which don't actually show any PerlScript!

Anyway, from my minimal playing, I couldn't get an incredibly simple
PerlScript to yield. It simply locked up until it completed, with no
response to hitting the stop button. This makes me think that the problem
is not Perl related, but higher up the stack.

<html>
<head>
<title>PerlScript Hello World!</title>
</head>
<body bgcolor="#ffffff">
<h2>PerlScript Hello world!</h2>
<script language="PerlScript">
foreach (101..200) {
$window->document->write("Hello world $_!<br>\n");
select undef,undef,undef,0.1;
}
</script>
</body>
</html>


I'm giving a part of the code :
function testSocket which checks during 100ms if there is some data to
read on the socket.
function waitMsg which calls testSocket and handles a timeout

sub testSocket()
{
# timeout 100 ms
my $timeout = 0.1;
@ready = $sel->can_read($timeout);
if (@ready > 0)
{
foreach $fh (@ready)
{
if ($fh == $sock)
{
return 1; #data ok : will read it
}
else
{
# Maybe we have finished with the socket
$sel->remove($fh);
$fh->close;

This doesn't make sense to me. What are you stuffing in $sel that is
going to become readable but is not going to be equal to $sock? And since
you don't care what it is, why are you stuffing it into $sel in the first
place?
}
}
}
return 0;
}

sub waitMsg(;$)
{
#timeout in ms (now must be a multiple of 100)
my $timeout = shift;

REDO: {
my $res = testSocket();
if ($res == 1)
{
return getMsg();
}
else
{
if ($timeout eq "")
{
# no timeout, infinite wait
return waitMsg();

Possibly infinite recursion is bad. Do this instead:

redo REDO;
}
else
{
if ($timeout == 0)
{
#timeout !!!
return (-1, "");
}
#recursive call
return waitMsg($timeout - 100);

Again, avoid infinite/deep recursion.

$timeout-=100;
redo REDO;

Also, there is no guarentee that an unsuccessful select actually
waited the full time, so that subtraction may not be accurate.

Xho
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,042
Latest member
icassiem

Latest Threads

Top