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 – 2 Creating the Controller and Template
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]