httpc库

httpc库基于cf框架都内部实现的socket编写的http client库.

httpc 特性

  • 支持设置httpc连接、请求超时设置、头部;

  • 支持http与https请求, 根据传参自动判断是否需要进行安全TCP连接;

  • 支持ipv4/ipv6协议, 手写ipv6需要将ipv6地址语法加入到[]内部, 如: http://[::1]:80;

  • 内置GET、POST、JSON、FILE几种请求模式, 优化代码编写效率与代码可读性;

  • 支持多种请求模式: 无需初始化的一次性请求、socket复用的长连接请求、多接口并发请求;


httpc的全局TIMEOUT时间

全局超时时间为TIMEOUT(默认为15秒).

httpc.get(domain, HEADER, ARGS, TIMEOUT)

get方法将会对domain发起一次http GET请求.

HEADER为一个key-value数组{[1] = key, [2] = value}, 不支持Content-Type与Content-Length等设置;

ARGS为请求参数, httpc框架将为使用者自动构建http GET 查询参数;

TIMEOUT为请求的最大超时时间(optional);

使用示例:

  1. local code, body = httpc.get("http://localhost:8080/api?page=1&limit=10", {{"Auth", "admin"}})
  2. local code, body = httpc.get("http://localhost:8080/api", {{"Auth", "admin"}}, {{'page', 1}, {'limit', 10}})
  3. local code, body = httpc.get("http://localhost:8080/api", {{"Auth", "admin"}}, {{'page', 1}, {'limit', 10}}, 3)

此方法有2个返回值, code为返回的http 状态码, body为response body;

当code为nil时, body为出错信息; 当code为number时请自行判断; (不支持302与301)

httpc.post(domain, HEADER, BODY, TIMEOUT)

post方法将会对domain发起一次http POST请求.

HEADER为一个key-value数组{[1] = key, [2] = value}, 不支持Content-Type与Content-Length等设置;

BODY为一个key-value数组{[1] = key, [2] = value}, Content-Type为application/x-www-form-urlencoded;

TIMEOUT为请求的最大超时时间(optional);

使用示例:

  1. local code, body = httpc.post("http://[::ffff:127.0.0.1]:8080/api", {{"Auth", "admin"}}, {{'page', 1}, {'limit', 10}}, 3)

此方法有2个返回值, code为返回的http 状态码, body为response body;

当code为nil时, body为出错信息; 当code为number时请自行判断; (不支持302与301)

httpc.json(domain, HEADER, JSON, TIMEOUT)

json方法将会对domain发起一次http POST请求.

HEADER为一个key-value数组{[1] = key, [2] = value}, 不支持Content-Type与Content-Length等设置;

JSON为一个json格式的字符串, 需要使用者自行进行格式化; Content-Type为application/json;

TIMEOUT为请求的最大超时时间(optional);

使用示例:

  1. local code, body = httpc.json("http://localhost:8080/api", {{"Auth", "admin"}}, json.encode({page=1, limit=10}))

此方法有2个返回值, code为返回的http 状态码, body为response body;

当code为nil时, body为出错信息; 当code为number时请自行判断; (不支持302与301)

httpc.file(domain, HEADER, FILES, TIMEOUT)

file方法将会对domain发起一次http POST请求.

HEADER为一个key-value数组{[1] = key, [2] = value}, 不支持Content-Type与Content-Length等设置;

FILES为一个file数组{name = name, filename = filename, file = file}; 其中file为文件内容, application/文件类型

TIMEOUT为请求的最大超时时间(optional);

使用示例:

  1. local code, body = httpc.file('http://localhost:8080/view', nil, {
  2. {name='1', filename='1.jpg', file='1', type='abc'},
  3. {name='2', filename='2.jpg', file='2', type='abc'},
  4. })

此方法有2个返回值, code为返回的http 状态码, body为response body;

当code为nil时, body为出错信息; 当code为number时请自行判断; (不支持302与301)

httpc class 对象

httpc class为0.3版本新增请求方法, 在特定场景能提高大约50%~80%的性能:

  1. * 多次对同域名、同端口、同协议的不同接口进行请求.
  2. * 对多个无相互依赖的接口进行请求;

同样, 他们的返回值也是根据接口请求顺序返回为一个数组的.

httpc class与httpc的区别在于, httpc由框架管理socket, httpc class 需要手动管理(显示关闭).

http class需要创建一个名为httpc.class的对象, 然后使用者根据以下API对其进行使用.

httpc:new(opt)

http class 创建方法, opt是一个table类型参数. 为其传递一个timeout值可设置接口最大请求时间.

httpc:get(…)

同httpc.get, 其差别是不会主动关闭socket套接字.

httpc:post(…)

同httpc.post, 其差别是不会主动关闭socket套接字.

httpc:json(…)

同httpc.json, 其差别是不会主动关闭socket套接字.

httpc:file(…)

同httpc.file, 其差别是不会主动关闭socket套接字.

httpc:close()

所有httpc class 创建后必须在请求完成/出错之后使用此方法关闭连接.

httpc:multi_request(opts)

multi_request 为一次并发多个请求提供了可能, 在多个不相关的接口中快速获得数据. 以减少网络延迟带来的并发问题.

opts是一个请求数组, 每个item代表一个请求链接.

opt.domain 为用户请求domain;

opt.method 为用户指定请求方法, 目前仅支持httpc上述四种:["get", "post", "json", "file"];

opt.headers 为用户请求头部;

opt.args 为用户请求参数(get特有);

opt.body 为用户请求体(post特有);

opt.json 为用户请求体(json特有);

opt.file 为用户请求体(file特有);

此方法为使用者参数类型与上述的请求方法相同.

httpc 0.3版本也有此方法. 调用方式为httpc.multi_request(opt), 参数的类型一样.

httpc class使用示例

更多完善的示例, 请参考项目内的文件:script/test_httpc.lua

  1. local cf = require "cf"
  2. local httpc = require "httpc"
  3. local http = require "httpc.class"
  4. local json = require "json"
  5. local system = require "system"
  6. local now = system.now
  7.  
  8. require "utils"
  9.  
  10. cf.timeout(3, function ()
  11. cf.fork(function ( ... )
  12. local hc = http:new {}
  13. local t1 = now()
  14. print("开始时间:", t1)
  15.  
  16. local code, data = hc:get("localhost:8080/api?a=1&b=2")
  17. print(code, data)
  18.  
  19. local code, data = hc:get("localhost:8080/api?a=3&b=4")
  20. print(code, data)
  21.  
  22. local ok, response = httpc.multi_request {
  23. -- local ok, response = hc:multi_request {
  24. {
  25. domain = "http://localhost:8080/api",
  26. method = "get",
  27. headers = {{"Auth", "admin"}},
  28. args = {{'page', 1}, {'limit', 10}}
  29. },
  30. {
  31. domain = "http://localhost:8080/api",
  32. method = "post",
  33. headers = {{"Auth", "admin"}},
  34. body = {{'page', 1}, {'limit', 10}}
  35. },
  36. {
  37. domain = "http://localhost:8080/api",
  38. method = "json",
  39. headers = {{"Auth", "admin"}},
  40. json = json.encode({page=1, limit=10})
  41. },
  42. {
  43. domain = "http://localhost:8080/api",
  44. method = "file",
  45. headers = {{"Auth", "admin"}},
  46. files = {
  47. {name='1', filename='1.jpg', file='1', type='abc'},
  48. {name='2', filename='2.jpg', file='2', type='abc'},
  49. }
  50. }
  51. }
  52. local t2 = now()
  53. print("结束时间:", t1, "总耗时:", t2 - t1)
  54.  
  55. require('logging'):new():DEBUG(response, "回应数量: " .. #response)
  56. hc:close()
  57. end)
  58. end)

最后

需要注意的事:

  1. 1. httpc不会为用户解析response body;
  2. 2. 不支持重定向自行跳转, 需要使用者自行解决与判断;
  3. 3. 暂时不支持除以上API外的其它请求方法;