Guest User

Untitled

a guest
Dec 10th, 2019
94
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1.  
  2. Socket = {}
  3.  
  4. local defaultOptions = {
  5. autoReconnect = false,
  6. connectOnCreate = true,
  7. connectTimeoutMS = 1000,
  8. reconnectRetryMS = 3000,
  9. }
  10.  
  11. local instances = {}
  12. local metatableSocket = { __index = Socket }
  13.  
  14. function Socket:create(hostname, port, options)
  15. assert(type(hostname) == "string", "expected string at argument 1, got ".. type(hostname))
  16. assert(type(port) == "number", "expected number at argument 2, got ".. type(hostname))
  17.  
  18. if type(options) ~= "table" then
  19. options = {}
  20. end
  21.  
  22. for option, default in pairs(defaultOptions) do
  23. if options[option] == nil or type(options[option]) ~= type(default) then
  24. options[option] = default
  25. end
  26. end
  27.  
  28. options.connectTimeoutMS = math.max(50, options.connectTimeoutMS)
  29. options.reconnectRetryMS = math.max(50, options.reconnectRetryMS)
  30.  
  31. local new = {
  32. port = port,
  33. hostname = hostname,
  34. options = options,
  35. handle = false,
  36. listener = {},
  37. timeout = false,
  38. connected = false
  39. }
  40.  
  41. setmetatable(new, metatableSocket)
  42.  
  43. if new.options.connectOnCreate then
  44. new:connect()
  45. end
  46.  
  47. return new
  48. end
  49.  
  50. function Socket:connect()
  51. if self:isConnected() then
  52. return
  53. end
  54.  
  55. self.options.ignoreAutoReconnect = nil
  56. self.handle = sockOpen(self.hostname, self.port)
  57.  
  58. if self.handle then
  59. instances[self.handle] = self
  60. self.timeout = setTimer(Socket.timeout, self.options.connectTimeoutMS, 1, self.handle)
  61. end
  62. end
  63.  
  64. function Socket.timeout(socket)
  65. local instance = instances[socket]
  66. instance:emit("timeout")
  67. instance.timeout = false
  68. sockClose(socket)
  69. end
  70.  
  71. function Socket:disconnect()
  72. if self:isConnected() then
  73. self.options.ignoreAutoReconnect = true
  74. sockClose(self.handle)
  75. end
  76. end
  77.  
  78. function Socket:isConnected()
  79. return self.connected
  80. end
  81.  
  82. function Socket:write(data)
  83. if self:isConnected() then
  84. sockWrite(self.handle, base64Encode(data) .. "\r\n")
  85. end
  86. end
  87.  
  88. function Socket:on(eventName, callback)
  89. assert(type(eventName) == "string", "expected string at argument 1, got ".. type(eventName))
  90. assert(type(callback) == "function", "expected function at argument 2, got ".. type(callback))
  91.  
  92. self.listener[eventName] = callback
  93. end
  94.  
  95. function Socket:emit(eventName, ...)
  96. assert(type(eventName) == "string", "expected string at argument 1, got ".. type(eventName))
  97.  
  98. if self.listener[eventName] then
  99. pcall(self.listener[eventName], self, ...)
  100. end
  101. end
  102.  
  103. addEventHandler("onSockOpened", root,
  104. function (socket)
  105. local instance = instances[socket]
  106.  
  107. if instance then
  108. if instance.timeout and isTimer(instance.timeout) then
  109. killTimer(instance.timeout)
  110. end
  111. instance.connected = true
  112. instance.timeout = false
  113. instance:emit("ready")
  114. end
  115. end
  116. )
  117.  
  118. addEventHandler("onSockClosed", root,
  119. function (socket)
  120. local instance = instances[socket]
  121.  
  122. if instance then
  123. instance.handle = false
  124. instances[socket] = nil
  125.  
  126. if instance.connected then
  127. instance.connected = false
  128. instance:emit("close")
  129. end
  130.  
  131. if not instance.options.ignoreAutoReconnect and instance.options.autoReconnect then
  132. setTimer(
  133. function ()
  134. instance:connect()
  135. end,
  136. instance.options.reconnectRetryMS, 1)
  137. end
  138. end
  139. end
  140. )
  141.  
  142. addEventHandler("onSockData", root,
  143. function (socket, data)
  144. local instance = instances[socket]
  145.  
  146. if instance then
  147. local lines = utf8.split(data, "\r\n")
  148.  
  149. if lines then
  150. for index, line in ipairs(lines) do
  151. line = base64Decode(line)
  152. local json = fromJSON(line)
  153.  
  154. if type(json) == "table" then
  155. if type(json.type) == "string" then
  156. instance:emit("data", json.type, type(json.payload) == "table" and json.payload or {})
  157. end
  158. end
  159. end
  160. end
  161. end
  162. end
  163. )
  164.  
  165. addEventHandler("onResourceStop", resourceRoot,
  166. function ()
  167. for socket, instance in pairs(instances) do
  168. instance:disconnect()
  169. end
  170. end,
  171. false, "low")
RAW Paste Data