Using HTTPClient in Godot

Hi all,

While I was creating an openclipart plugin for the Godot Engine, I have created an HTTP class for downloading the data and images. Godot has built-in support for HTTP get/post data. An example on how to use the HTTPClient is already available on godot github wiki page.

The plugin loads multiple images simultaneously so I was in need of creating a class for that. Also there are multiple things are loaded, there is a chance of blocking the UI. Here comes multi-threading to the rescue. Godot wiki also has an example for background resource loading in another thread.

I combined these two and now the HTTP class uses a thread to load data. I also added two signals – loading and loaded. The HTTP header ‘Content-length’ is checked using http.get_response_body_length(). So the signal ‘loading’ emits with two values – bytes loaded and bytes total. From those we can find the percent loaded. The signal ‘loaded’ emits with the result value.
Create a new Node in godot and add this script and save it as a scene ‘http.xml’.
extends Node

var t = Thread.new()

func _init():
 var arg_bytes_loaded = {"name":"bytes_loaded","type":TYPE_INT}
 var arg_bytes_total = {"name":"bytes_total","type":TYPE_INT}
 add_user_signal("loading",[arg_bytes_loaded,arg_bytes_total])
 var arg_result = {"name":"result","type":TYPE_RAW_ARRAY}
 add_user_signal("loaded",[arg_result])
 pass

func get(domain,url,port,ssl):
 if(t.is_active()):
  return
 t.start(self,"_load",{"domain":domain,"url":url,"port":port,"ssl":ssl})
 
func _load(params):
 var err = 0
 var http = HTTPClient.new()
 err = http.connect(params.domain,params.port,params.ssl)
 
 while(http.get_status() == HTTPClient.STATUS_CONNECTING or http.get_status() == HTTPClient.STATUS_RESOLVING):
  http.poll()
  OS.delay_msec(100)
  
 var headers = [
  "User-Agent: Pirulo/1.0 (Godot)",
  "Accept: */*"
 ]
 
 err = http.request(HTTPClient.METHOD_GET,params.url,headers)
 
 while (http.get_status() == HTTPClient.STATUS_REQUESTING):
  http.poll()
  OS.delay_msec(500)
# 
 var rb = RawArray()
 if(http.has_response()):
  var headers = http.get_response_headers_as_dictionary()
  while(http.get_status()==HTTPClient.STATUS_BODY):
   http.poll()
   var chunk = http.read_response_body_chunk()
   if(chunk.size()==0):
    OS.delay_usec(100)
   else:
    rb = rb+chunk
    call_deferred("_send_loading_signal",rb.size(),http.get_response_body_length())
  
 call_deferred("_send_loaded_signal")
 http.close()
 return rb

func _send_loading_signal(l,t):
 emit_signal("loading",l,t)
 pass
 
func _send_loaded_signal():
 var r = t.wait_to_finish()
 emit_signal("loaded",r)
 pass

Sample usage:

var http = preload('http.xml').instance()

http.connect("loading",self,"_on_loading")
http.connect("loaded",self,"_on_loaded")


http.get("http://example.com","/page?id=1",80,false) #domain,url,port,useSSL

func _on_loading(loaded,total):
    var percent = loaded*100/total

func _on_loaded(result):
    var result_string = result.get_string_from_ascii()
    print(result_string)

The class now supports only get method. We will look into the ‘post’ method later.

Also Read:   Creating a PHP website using MVC - 1
Thanks.

Never miss any content from Codetuto!

Subscribe to Codetuto Newsletter and be the first to recieve our latest posts and tutorials

Subscribe Now For Free

[Total: 3    Average: 2.7/5]