HTTP 客户端类

HTTPClient 提供了对HTTP通信的低层次访问. 对于一个更高级的接口, 你可能需要看看 HTTPRequest , 它有一个可用的教程 here.

警告

导出到 Android 时,在导出项目或使用一键部署之前,确保在 Android 导出预设中启用 INTERNET 权限。否则,Android 系统会阻止该程序任何形式的网络通信。

这是使用 HTTPClient 类的示例. 它只是一个脚本, 因此它可以通过执行以下命令来运行:

GDScriptC#

  1. c:\godot> godot -s http_test.gd
  1. c:\godot> godot -s HTTPTest.cs

它将连接并获取一个网站.

GDScriptC#

  1. extends SceneTree
  2. # HTTPClient demo
  3. # This simple class can do HTTP requests; it will not block, but it needs to be polled.
  4. func _init():
  5. var err = 0
  6. var http = HTTPClient.new() # Create the Client.
  7. err = http.connect_to_host("www.php.net", 80) # Connect to host/port.
  8. assert(err == OK) # Make sure connection is OK.
  9. # Wait until resolved and connected.
  10. while http.get_status() == HTTPClient.STATUS_CONNECTING or http.get_status() == HTTPClient.STATUS_RESOLVING:
  11. http.poll()
  12. print("Connecting...")
  13. await get_tree().process_frame
  14. assert(http.get_status() == HTTPClient.STATUS_CONNECTED) # Check if the connection was made successfully.
  15. # Some headers
  16. var headers = [
  17. "User-Agent: Pirulo/1.0 (Godot)",
  18. "Accept: */*"
  19. ]
  20. err = http.request(HTTPClient.METHOD_GET, "/ChangeLog-5.php", headers) # Request a page from the site (this one was chunked..)
  21. assert(err == OK) # Make sure all is OK.
  22. while http.get_status() == HTTPClient.STATUS_REQUESTING:
  23. # Keep polling for as long as the request is being processed.
  24. http.poll()
  25. print("Requesting...")
  26. await get_tree().process_frame
  27. assert(http.get_status() == HTTPClient.STATUS_BODY or http.get_status() == HTTPClient.STATUS_CONNECTED) # Make sure request finished well.
  28. print("response? ", http.has_response()) # Site might not have a response.
  29. if http.has_response():
  30. # If there is a response...
  31. headers = http.get_response_headers_as_dictionary() # Get response headers.
  32. print("code: ", http.get_response_code()) # Show response code.
  33. print("**headers:\\n", headers) # Show headers.
  34. # Getting the HTTP Body
  35. if http.is_response_chunked():
  36. # Does it use chunks?
  37. print("Response is Chunked!")
  38. else:
  39. # Or just plain Content-Length
  40. var bl = http.get_response_body_length()
  41. print("Response Length: ", bl)
  42. # This method works for both anyway
  43. var rb = PackedByteArray() # Array that will hold the data.
  44. while http.get_status() == HTTPClient.STATUS_BODY:
  45. # While there is body left to be read
  46. http.poll()
  47. # Get a chunk.
  48. var chunk = http.read_response_body_chunk()
  49. if chunk.size() == 0:
  50. await get_tree().process_frame
  51. else:
  52. rb = rb + chunk # Append to read buffer.
  53. # Done!
  54. print("bytes got: ", rb.size())
  55. var text = rb.get_string_from_ascii()
  56. print("Text: ", text)
  57. quit()
  1. using Godot;
  2. public partial class HTTPTest : SceneTree
  3. {
  4. // HTTPClient demo.
  5. // This simple class can make HTTP requests; it will not block, but it needs to be polled.
  6. public override async void _Initialize()
  7. {
  8. Error err;
  9. HTTPClient http = new HTTPClient(); // Create the client.
  10. err = http.ConnectToHost("www.php.net", 80); // Connect to host/port.
  11. Debug.Assert(err == Error.Ok); // Make sure the connection is OK.
  12. // Wait until resolved and connected.
  13. while (http.GetStatus() == HTTPClient.Status.Connecting || http.GetStatus() == HTTPClient.Status.Resolving)
  14. {
  15. http.Poll();
  16. GD.Print("Connecting...");
  17. OS.DelayMsec(500);
  18. }
  19. Debug.Assert(http.GetStatus() == HTTPClient.Status.Connected); // Check if the connection was made successfully.
  20. // Some headers.
  21. string[] headers = { "User-Agent: Pirulo/1.0 (Godot)", "Accept: */*" };
  22. err = http.Request(HTTPClient.Method.Get, "/ChangeLog-5.php", headers); // Request a page from the site.
  23. Debug.Assert(err == Error.Ok); // Make sure all is OK.
  24. // Keep polling for as long as the request is being processed.
  25. while (http.GetStatus() == HTTPClient.Status.Requesting)
  26. {
  27. http.Poll();
  28. GD.Print("Requesting...");
  29. if (OS.HasFeature("web"))
  30. {
  31. // Synchronous HTTP requests are not supported on the web,
  32. // so wait for the next main loop iteration.
  33. await ToSignal(Engine.GetMainLoop(), "idle_frame");
  34. }
  35. else
  36. {
  37. OS.DelayMsec(500);
  38. }
  39. }
  40. Debug.Assert(http.GetStatus() == HTTPClient.Status.Body || http.GetStatus() == HTTPClient.Status.Connected); // Make sure the request finished well.
  41. GD.Print("Response? ", http.HasResponse()); // The site might not have a response.
  42. // If there is a response...
  43. if (http.HasResponse())
  44. {
  45. headers = http.GetResponseHeaders(); // Get response headers.
  46. GD.Print("Code: ", http.GetResponseCode()); // Show response code.
  47. GD.Print("Headers:");
  48. foreach (string header in headers)
  49. {
  50. // Show headers.
  51. GD.Print(header);
  52. }
  53. if (http.IsResponseChunked())
  54. {
  55. // Does it use chunks?
  56. GD.Print("Response is Chunked!");
  57. }
  58. else
  59. {
  60. // Or just Content-Length.
  61. GD.Print("Response Length: ", http.GetResponseBodyLength());
  62. }
  63. // This method works for both anyways.
  64. List<byte> rb = new List<byte>(); // List that will hold the data.
  65. // While there is data left to be read...
  66. while (http.GetStatus() == HTTPClient.Status.Body)
  67. {
  68. http.Poll();
  69. byte[] chunk = http.ReadResponseBodyChunk(); // Read a chunk.
  70. if (chunk.Length == 0)
  71. {
  72. // If nothing was read, wait for the buffer to fill.
  73. OS.DelayMsec(500);
  74. }
  75. else
  76. {
  77. // Append the chunk to the read buffer.
  78. rb.AddRange(chunk);
  79. }
  80. }
  81. // Done!
  82. GD.Print("Bytes Downloaded: ", rb.Count);
  83. string text = Encoding.ASCII.GetString(rb.ToArray());
  84. GD.Print(text);
  85. }
  86. Quit();
  87. }
  88. }