SHARE
TWEET

Untitled

a guest Dec 10th, 2019 77 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
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top