sockethelper.lua 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. local socket = require "skynet.socket"
  2. local skynet = require "skynet"
  3. local readbytes = socket.read
  4. local writebytes = socket.write
  5. local sockethelper = {}
  6. local socket_error = setmetatable({} , { __tostring = function() return "[Socket Error]" end })
  7. sockethelper.socket_error = socket_error
  8. local function preread(fd, str)
  9. return function (sz)
  10. if str then
  11. if sz == #str or sz == nil then
  12. local ret = str
  13. str = nil
  14. return ret
  15. else
  16. if sz < #str then
  17. local ret = str:sub(1,sz)
  18. str = str:sub(sz + 1)
  19. return ret
  20. else
  21. sz = sz - #str
  22. local ret = readbytes(fd, sz)
  23. if ret then
  24. return str .. ret
  25. else
  26. error(socket_error)
  27. end
  28. end
  29. end
  30. else
  31. local ret = readbytes(fd, sz)
  32. if ret then
  33. return ret
  34. else
  35. error(socket_error)
  36. end
  37. end
  38. end
  39. end
  40. function sockethelper.readfunc(fd, pre)
  41. if pre then
  42. return preread(fd, pre)
  43. end
  44. return function (sz)
  45. local ret = readbytes(fd, sz)
  46. if ret then
  47. return ret
  48. else
  49. error(socket_error)
  50. end
  51. end
  52. end
  53. sockethelper.readall = socket.readall
  54. function sockethelper.writefunc(fd)
  55. return function(content)
  56. local ok = writebytes(fd, content)
  57. if not ok then
  58. error(socket_error)
  59. end
  60. end
  61. end
  62. function sockethelper.connect(host, port, timeout)
  63. local fd
  64. if timeout then
  65. local drop_fd
  66. local co = coroutine.running()
  67. -- asynchronous connect
  68. skynet.fork(function()
  69. fd = socket.open(host, port)
  70. if drop_fd then
  71. -- sockethelper.connect already return, and raise socket_error
  72. socket.close(fd)
  73. else
  74. -- socket.open before sleep, wakeup.
  75. skynet.wakeup(co)
  76. end
  77. end)
  78. skynet.sleep(timeout)
  79. if not fd then
  80. -- not connect yet
  81. drop_fd = true
  82. end
  83. else
  84. -- block connect
  85. fd = socket.open(host, port)
  86. end
  87. if fd then
  88. return fd
  89. end
  90. error(socket_error)
  91. end
  92. function sockethelper.close(fd)
  93. socket.close(fd)
  94. end
  95. function sockethelper.shutdown(fd)
  96. socket.shutdown(fd)
  97. end
  98. return sockethelper