Talking to server-side PHP Script

BlitzMax Forums/BlitzMax Programming/Talking to server-side PHP Script

VomitOnLino(Posted 2010) [#1]
Hey,

I was wondering if there was a way to talk to a server-side PHP script (which in turn modifies a MYSQL database) without stalling the entire program.

Basically right now as soon as I open the socket to the server, everything comes to a grinding halt until either the server responds and the stream is closed or it times out.

I'm using Vertex BnetEX already, which is a bit better than the built-in functions but still locks up the game badly.

Any ideas?

Rough code snippet below. Doesn't run, just to give you an idea.
Method PutScore:Byte(name:String, score:String, uniqueid:String)
		Local Sucess:Byte = False
		Local Post:TPost = TPost.Init(Server.url, Server.port)
		post.AddInputField("name", name)
		post.AddInputField("score", score)
		post.AddInputField("uuid",uniqueid)

		Local Stream:TTCPStream = PHPHandler.SendData()
		
		If stream
			While Not Stream.Eof()
				If Trim(Upper(Stream.ReadLine())) = "OK" Sucess = True
			Wend
			
			Stream.Close()
		End If
		
		Post = Null
		
		Return Sucess
	End Method


Last edited 2010


Thareh(Posted 2010) [#2]
I think you'd have to simulate a web browser :)

Try
    WriteLine( Stream, "POST /(your php form shizzle) HTTP/1.1" )
    WriteLine( Stream, "Content-Length: (Total length of the data you want to send)" )
    WriteLine( Stream, "Content-Type: text/plain" )

    WriteLine( Stream, "" )

    WriteLine( Stream, "name=(enter name here)" )
    WriteLine( Stream, "score=(enter score here)" )
    WriteLine( Stream, "uuid=(enter unique id here)" )
    CloseStream( Stream )

Catch Error:TStreamWriteException
    CloseStream( Stream )

Endtry


Something like this is what you need to do :)
Needs some tweaking to work properly, but you get the idea :P

Last edited 2010


VomitOnLino(Posted 2010) [#3]
Hey Thareh,

Ah sorry! I worded my question poorly. I already have the server and everything set up and running. Submitting & getting scores works fine, even using some encryption there.

BUT:

Opening a socket and performing readline/writeline commands seems to bring everything else in the game to a screeching halt. Now the user isn't playing when submitting a score obviously, but I still think it's bad interaction...

Any ideas?


Jaydubeww(Posted 2010) [#4]
Isn't this what threading is supposed to solve? Maybe you could create a thread and have it send the scores to your database. Or maybe you should have an option to send it to the database and just have a "please wait a moment while you connect to the database..." screen.


VomitOnLino(Posted 2010) [#5]
Yeah, for now I went with the screen solution.

I don't know about threading, as everything else runs perfectly fine single threaded, and tossing in threading just to have one feature work better seems a bit overkill for small-ish game like that.

But then again I might overestimate the additional headache that threading causes? E.g. compatibility, garbage collector & performance issues.

(When I do a threaded build on my core2duo it seems to run slower...)


Tibit(Posted 2010) [#6]
Establishing a connection in TCP in blitzmax does lock the program due to the lack of an asynchronous approach, however since we do have threads now there might be away around it.

My suggestion is that you only thread the connection-part, to keep it simple. And in my experience the problems with threads are that bugs become difficult to find and that is can become a real hassle to share resources.

But in this case you only need a idle thread that jumps back into your main-thread when the function call is done, so it sure sounds simple to me :)


ima747(Posted 2010) [#7]
This is probably one of the simplest and safest things you can do with threads. You don't need to share any objects really, all you need to do is pass an object to the thread at startup with the data you want to send (player name, score etc.) then have the threaded function connect, parse the passed object, submit and end with a return object to signify success. Then your main thread you just check to see if the thread is completed and if so you close it to retrieve the return object. Since you don't need to actively share resources you don't need to worry about mutexes etc. They run totally independently.

The biggest concern I would have is the different garbage collector with threaded builds. I've found it to be a little sketchy compared to the single threaded GC. But since you're not going to be doing a whole lot that will need collecting in the child thread I wouldn't be concerned.

Another, old school and less elegant option might be creating a thread submitting program that gets executed by your main program. But this could open up some doors for people to submit fake scores in an overly easy fashion... not that it's hard to just sniff the HTTP com anyway but this would literally be handing them a tool to do it, they just have to figure out what the input looks like... but maybe that's a non issue, or you can encrypt the data being fed into the submission app, etc...


RepeatUntil(Posted 2010) [#8]
Another solution: use ETNA (windows only unfortunately) which does exactly what you need (use of a thread so that the program is not stopped)...