Sockets for AGS (alpha 1) -- testers required!

Started by Wyz, Sun 08/09/2013 20:22:38

Previous topic - Next topic

Khris

Ok, that explains it :)
I got base64 decoding to work after a few hiccups and got AGS to display an image loaded from a server, the implications of that alone... :D
When I tried a bigger image, agser.me borked though, but it did work from localhost. Now to parse chunked data...
Unfortunately, AGS can't create DynamicSprites from PNGs, but that's another story.

Nice timing btw, I was literally about to hit the sleep button and go to bed when I saw your reply, and I stayed up for a couple of hours to try it immediately :D

Khris

Alright, I'm running into a serious problem.
I'm trying to transfer a bigger image; it's a PCX with a file size of about 45k. What happens is khris.agser.me sends base64 data, about 60k.
I've tried both text/plain and text/base64, as well as HTTP/1.0 and HTTP/1.1. The first option has no effect, but when I use 1.1, the server breaks it up into chunks. So far, no problem there, what happens is I'm only getting about 12k. At this point server.Recv() apparently returns null, because AGS stops reading. I'm positive this isn't an error in my code because reading the same data from localhost works fine and I'm getting the entire 60k.
The error is also not with the remote server, because when I request the document in Firefox, I'm getting the full 60k in text format.

In this vain, if I wanted to read the data asynchronously, is server.Recv() non-blocking? Because if I have a slow connection, how is it ensured that Recv() will always return something as fast as I'm calling it?

Wyz

Sorry to have deprived you from sleep. ;) Whoah, you are fast :D

Yes Recv is non-blocking. When there is nothing in the buffer because it is still under way Recv will return null. Note that this is different from an empty string which would signal that the connection is closed. There are two scenarios that would return null: an error has occurred (LastError > 0) or the call 'would block' which means you have to wait for new data to arrive (LastError == 0).
Life is like an adventure without the pixel hunts.

Khris

Thanks, I should've realized that. On the upside, I managed to download a 1.1 MB file and save it to the game dir :) Unfortunately, decoding base64 takes over a minute with filesizes like that so I'll wait till you implement RecvData(). :D

Monsieur OUXX

Is there a macro defined when the plugin is present? That would be very useful to enable or disable some code in the AGS script.

 

Wyz

Not yet but I've added a define for the next version.  :-D
Code: ags
#define AGSSOCK
Life is like an adventure without the pixel hunts.

Monsieur OUXX

Quote from: Wyz on Tue 25/02/2014 20:15:57
Not yet but I've added a define for the next version.  :-D
Code: ags
#define AGSSOCK


So when do you release it?
 

Wyz

I can't give an estimation unfortunately.  :( You can add the flag manually for now I guess.
Life is like an adventure without the pixel hunts.

Monsieur OUXX

Quote from: Wyz on Tue 04/03/2014 02:18:24
I can't give an estimation unfortunately.  :( You can add the flag manually for now I guess.

Sure, will do. Thanks for the answer. Please, it would be cool it it weren't too long -- I'm not really interested in the new features, but that flag is important for our compilation/releasing process, to avoid a lot of human operations and human mistakes.
 

Crimson Wizard

#29
[SCRAPPED] Sorry, I just realized that's not really something that was needed here.

Crimson Wizard

#30
May anyone (WyZ?) please elaborate, how do I use asynchronous connection to address?
This is how I begin async connection:
Code: ags

sock.Connect(addr, true);

But how do I know that/when connection was established? Should I check some property over time, or call any function? Recv() maybe?

Secondly, do I understand this right that getting "" from Socket.Recv() is the correct way to know that the remote socket has disconnected? Is there any property that indicates this fact for certain?

Wyz

Quote from: Crimson Wizard on Thu 21/08/2014 23:18:56
May anyone (WyZ?) please elaborate, how do I use asynchronous connection to address?

Yes it's all undocumented for the time being unfortunately  :-[, I've kept close to the Berkeley sockets for as far as I could. The trick is to call Connect multiple times.
If you call Connect asynchronously (with async == true) one of three things can happen:

  • Connect returned false and LastError == 0: The connection is not yet established, you need to call Connect again.
  • Connect returned false and LastError != 0: Some error occurred and the connection could not be established. (You could use ErrorString to see what went wrong)
  • Connect returned true: The connection is established, the socket is ready to be used.

I believe for this to work correctly you need to use the same SockAddr object for each call. I don't remember if I ever tested this but I advise you to do so.

Quote from: Crimson Wizard on Thu 21/08/2014 23:18:56
Secondly, do I understand this right that getting "" from Socket.Recv() is the correct way to know that the remote socket has disconnected? Is there any property that indicates this fact for certain?

Getting "" from Recv is the way to know the remote end closed the connection gracefully: "hey I wan't to stop transmitting". Some clients simply cut the connection which makes it impossible for them to check if everything they sent really came through. However since they are out there you probably also want to deal with clients not closing gracefully. In that case (but also other cases) Recv returns null and the LastError is set to something non-zero. There are error codes that will tell you the connection has been cut specifically ("connection reset by peer") but since error codes are platform specific I don't really want to go into that.

I hope that helps you. :)
Life is like an adventure without the pixel hunts.

Crimson Wizard

#32
I found following issue.
When I call Sock.Connect(addr, true) for the first time, it returns false and LastError = 0. When I call it for the second time, it returns false and LastError is 10056, which is "Socket is already connected".
Another game instance that ran "server mode" detected that connection was made.

Regarding error code and strings, I think they are unusable like this. Not only error code is OS-specific, as you say, but also error string is in OS language and may contain characters unsupported by game font.


Wyz

I guess that is either a flaw in my plugin or I remembered incorrectly how this is supposed to be done (it has been a while). I will look into this for sure but for now I guess the work around is to see if you can read or write after Connect returns false. If not either the connection was closed immediately or it was never connected to begin with.

I'm aware that error codes themselves are pretty useless this way and can only be used effectively to see if there were any errors or not. Since there is no standard at all for error codes and some are very platform specific I don't really know how to deal with them other then to just pass them. That way it doesn't stop other people from making platform specific modules to wrap around them. The error string is there to aid the developer in debugging and I wouldn't recommend them to be passed to the end-user. I didn't really think about the localization problem; I guess they are in Cyrillic for you which AGS wouldn't be able to render I assume: I'll see if I can force them to be shown in English.
Life is like an adventure without the pixel hunts.

Crimson Wizard

At the moment I am writing error strings into file. This lets me to read them if I set right code page when opening the file.

Dualnames

I've open sourced the AGS ceremony files, so perhaps they can be of some help??
Worked on Strangeland, Primordia, Hob's Barrow, The Cat Lady, Mage's Initiation, Until I Have You, Downfall, Hunie Pop, and every game in the Wadjet Eye Games catalogue (porting)

Crimson Wizard

Quote from: Dualnames on Mon 25/08/2014 10:24:29
I've open sourced the AGS ceremony files, so perhaps they can be of some help??
I wasn't aware they use this very plugin; I am going to check them, thank you.

Crimson Wizard

Quote from: Crimson Wizard on Sat 02/11/2013 15:41:03
Every now and then I am getting an error when starting AGS:

Quote
There was an error loading plugin 'agssock.dll'.

Unable to load plugin 'agssock.dll'. It may depend on another DLL that is missing.

After some time (or maybe some actions) it loads fine.

A small update on this problem.
I was working on my project on different computer for few days, and this error never occured to me (although it was reoccuring every now and then before).
The difference is that it has Windows Vista installed (as opposed of Win7) and not a part of any net (nor connected to Internet).

Wyz

That's very interesting, thanks for sharing! ;-D
When I was working on another plugin not too long ago I had the same error btw. I have strong reasons to believe it has something to do with the compiler I'm using. Unfortunately I'm still completely lost why it happens. For release versions I'm going to use a different compiler I guess; it's a pain however. :(
Life is like an adventure without the pixel hunts.

Sledgy


SMF spam blocked by CleanTalk