koraktor / steam-condenser

A multi-language library for querying the Steam Community, Source, GoldSrc servers and Steam master servers
https://koraktor.de/steam-condenser
Other
356 stars 67 forks source link

A non-blocking socket operation could not be completed immediately #279

Closed Markouz closed 8 years ago

Markouz commented 8 years ago

So earlier I was using Steam Condenser to connect to some gameservers (Garry's Mod) that I have. It's been working without any issues but now for some reason it's giving me this error, basically out of nowhere as I haven't changed anything.

"A non-blocking socket operation could not be completed immediately. (Code: 10035)"

That shows up when it fails to connect. I was not getting this error before on the same server, same IP+port and configuration, and now it seems to not work out of nowhere. I barely changed any code, and when I noticed this error quickly and I undid anything that I would have changed, and unfortunately I'm still having this issue.

So I decided to setting up a server on my laptop. Worked fine, was able to connect. So then I try setting one up on a DigitalOcean server. Same issue. I can't think of anything on these servers' configuration that would cause this, but I don't know if it's an issue with Steam condenser/web-server or the game server itself.

Any ideas?

Markouz commented 8 years ago

So I've discovered that it's something on the webserver. I set up a wamp-server on my laptop (same as the one that wasn't working), copied the files over to my laptop and it connected without a problem. However I'm still interested if anyone knows what's wrong, since it seems likely it will happen again possibly on my laptop.

EDIT: Doesn't work on laptop now. Didn't touch a thing. But now I've discovered that when I remove the $server->rconAuth(), it works fine. But then I can't get some of the player's information (SteamID, ping, etc) like I could before this error started occurring.

koraktor commented 8 years ago

Ok, what version of Steam Condenser are you using?

And does this happen immediately or only after the your application is running for some time?

Markouz commented 8 years ago

Using the latest version.

I have 2 pages set up, one where it checks if the servers are online which works fine. Then the one that get the players of each server (requires RCON password). The one that gets the players loads for a 3-5 seconds then it gives me that error. I've tried restarting the webserver, it does the same thing.

And like I said previously, when I remove the rconAuth() line on that page, it doesn't give me that error. Instead it tells me that I'm unable to access some properties (which I'm assuming become accessible when you provide the RCON password)

koraktor commented 8 years ago

Can you provide more details about your code and the errors you get?

Markouz commented 8 years ago

Okay, so on my page that checks if servers are online.

if ($stmt->execute()){
    $servers_table = "";
    while ($server = $stmt->fetch(PDO::FETCH_ASSOC)){
        try {
            $curserver = new SourceServer($server['IP'], $server['Port']);
            $curserver->initialize();

            $status = "<span style='color:green'>Online</span>";
            $online = true;
        }
        catch(TimeoutException $e){
            $status = "<span style='color:red'>Timed Out</span>";
            $online = false; 
        }
        catch(Exception $e){
            $status = "<span style='color:red'>Offline</span>";
            $online = false; 
        }

        $servers_table .= isset($online) && $online == true ? "<tr class='success'>" : "<tr class='danger'>";
        $servers_table .= "<td>". htmlentities($server['ID']) ."</td>";
        $servers_table .= "<td>". htmlentities($server['Name']) ."</td>";
        $servers_table .= "<td>". htmlentities($server['IP']) ."</td>";
        $servers_table .= "<td>". htmlentities($server['Port']) ."</td>";
        $servers_table .= "<td>". $status ."</td>";
        $servers_table .= "</tr>";
    }
    echo($servers_table);
}

All that works fine.

Then on the page that gets the players, it looks like this

while ($server = $stmt->fetch(PDO::FETCH_ASSOC)){
    $servers_list .= "<div class='card-head style-primary'>
                        <header>". htmlentities($server['Name']). " <small>(". htmlentities($server['IP']) . ":". htmlentities($server['Port']) . ")" ."</small></header>
                    </div>";

    $rconpassword = $server['RCON'];

    try{
        $connect = new SourceServer($server['IP'], $server['Port']);
        $connect->initialize();
        try{    
            $connect->rconAuth($rconpassword);
            $connect->rconExec("status");

            $players = $connect->getPlayers();

            $servers_list .= "<div style='padding-left:20px; padding-top:2px' class='card-body'><table class='table table-condensed table-hover'>";
            $servers_list .= "<tr><th>Name</th><th>SteamID</th><th>Score</th><th>Ping</th>";

            // Load Actions table headers
            if ($rank->hasServerPermission($server['ID'] ,"Kick")){
                $servers_list .= "<th>Kick</th>";
            }

            if ($rank->hasServerPermission($server['ID'] ,"Ban")){
                $servers_list .= "<th>Ban</th>";
            }

            $servers_list .= "</tr>";
            // Stop loading action headers

            foreach ($players as $player){
                $servers_list .= "<tr><td>". htmlentities($player->name) ."</td><td>". htmlentities($player->steamId) ."</td><td>". htmlentities($player->score) ."</td><td>". htmlentities($player->ping) ."</td>";
                // Load Admin Actions
                if ($rank->hasServerPermission($server['ID'] ,"Kick")){
                    $servers_list .= "<td><button name='kick-server-player' data-server='". htmlentities($server['ID']) ."' data-playername='". htmlentities($player->name) ."' data-player='". htmlentities($player->steamId) ."' class='btn btn-warning'>Kick</button></td>";
                }

                if ($rank->hasServerPermission($server['ID'] ,"Ban")){
                    $servers_list .= "<td><button name='ban-server-player' data-server='". htmlentities($server['ID']) ."' data-playername='". htmlentities($player->name) ."' data-player='". htmlentities($player->steamId) ."' class='btn btn-danger'>Ban</button></td>";
                }

                // Stop loading actions
                $servers_list .= "</tr>";
            }       
            $servers_list .= "</div></table>";              
        }
        catch (SocketException $e){
            $servers_list .= $e->getMessage();
        }
        catch(Exception $e){
            $servers_list .= $e->getMessage();
        }

    }
    catch(Exception $e){
        $servers_list .= "<p class='alert alert-danger'>Failed to connect. This server is probably offline or restarting</p>";
    }
}
echo $servers_list;

That's the page where I get the error.

Markouz commented 8 years ago

After hours of working on this I found out it was something on the gameserver, not Steam condenser. Apparently nothing was able to connect to RCON until I added -ip and -port to the startup. Everything is working now :)

koraktor commented 8 years ago

Great you found out yourself.

Nevertheless, here’s a small suggestion for your code:

     try{
         $connect = new SourceServer($server['IP'], $server['Port']);
-        $connect->initialize();
         try{    
             $connect->rconAuth($rconpassword);
-            $connect->rconExec("status");

             $players = $connect->getPlayers();

#initialize() isn’t needed here, because you aren’t interested in the server’s info or ping. Executing status on the server is also unnecessary, because you don’t do anything with the output. This will save you a few requests.