Lua попытка вызова собственного метода (нулевое значение) - PullRequest
0 голосов
/ 06 августа 2020

Я написал небольшой класс для приема данных по TCP, но периодически (не постоянно, иногда скрипт работает достаточно долго и получает данные) я получаю сообщение об ошибке:

.\modules\tcp.lua:83: attempt to call method '_parsing' (a nil value)

Я не могу понять почему объект теряет метод, который он имел в себе и который работал. При создании класса я использую модуль https://github.com/kikito/middleclass

После создания объекта я вызываю while l oop:

feed:receive()

Пример класса

os.setlocale("C")
package.path  = package.path .. ";./libs/?.lua";
package.path  = package.path .. ";./libs/luasocket/lua/?.lua";
package.cpath = package.cpath .. ";./libs/luasocket/?.dll";
package.cpath = package.cpath .. ";./libs/luasocket/mime/?.dll";
package.cpath = package.cpath .. ";./libs/luasocket/socket/?.dll";

local class    = require "middleclass";
local socket   = require "socket";
local struct   = require "struct";
local msgpack  = require "msgpack";

local type     = type
local table    = table
local string   = string


local TCP = class("TCP")


function TCP:initialize(address, port, logger, onOpen, onClose, onMessages)
    self.address = address
    self.port = port
    self.logger = logger
    self.onOpen = onOpen
    self.onClose = onClose
    self.onMessages = onMessages

    self.socket = nil
    self.connected = false

    self.seq_in = 0
    self.chunk_in = ""
    self.seq_out = 0
    self.chunk_out = ""
end

function TCP:_connection_made()
    if not self.socket then
        self.socket = socket.tcp()
        local status, _ = self.socket:connect(self.address, self.port)
        if status then
            self.socket:setoption("reuseaddr", true)
            self.socket:setoption("tcp-nodelay", true)
            self.socket:setoption("keepalive", true)
            self.socket:settimeout(0)
            self.logger:info("Connection open "..self.address..":"..self.port.."")
            self.connected = true
            if self.onOpen then
                self.onOpen()
            end
        else
            self.socket = nil
        end
    end
end

function TCP:_connection_close()
    self.logger:info("Connection close "..self.address..":"..self.port.."")
    self.socket = nil
    self.connected = false

    self.seq_in = 0
    self.chunk_in = ""
    self.seq_out = 0
    self.chunk_out = ""
    if self.onClose then
        self.onClose()
    end
end

function TCP:_receive()
    local data, error, partial = self.socket:receive("*a")
    if (not data) and (error ~= "timeout") then
        self.logger:error("Connection error "..error)
        self:_connection_close()
        return nil, error
    end
    data = data or partial
    if not data then
        return nil, error
    else
        return self:_parsing(data)
    end
end;

function TCP:_parsing(data)
    local messages = {}
    if self.chunk_in ~= "" then
        data = self.chunk_in..data
        self.chunk_in = ""
    end
    while string.len(data) ~= 0 do
        if string.len(data) >= 10 then
            local size, seq = struct.unpack("<HL", data)
            if string.len(data) >= size + 10 then
                if seq ~= self.seq_in + 1 then
                    self.logger:warn("Connection expected seq: "..(self.seq_in + 1)..", received seq: "..seq)
                end
                self.seq_in = seq
                local msg = msgpack.unpack(string.sub(data, 11, 10 + size))
                data = string.sub(data, 11 + size)
                table.insert(messages, msg)
            else
                self.chunk_in = self.chunk_in..data
                data = ""
            end
        else
            self.chunk_in = self.chunk_in..data
            data = ""
        end
    end
    if self.onMessages then
        self.onMessages(messages)
    else
        return messages, ""
    end
end;

function TCP:_send(msg)
    self.logger:debug("Try to send message", msg)
    if type(msg) == "table" then
        local data = msgpack.pack(msg)
        self.seq_out = self.seq_out + 1
        local frame = struct.pack("<HL", string.len(data), self.seq_out)
        local index, error = self.socket:send(frame..data)
        if error then
            self.logger:error("Connection send error "..error)
            if error == "closed" then
                self:_connection_close()
            end
        end
    end
end

function TCP:open()
    if not self.connected then
        self:_connection_made()
    end
end

function TCP:close()
    if self.connected then
        self:_connection_close()
    end
end

function TCP:receive()
    if not self.connected then
        self:_connection_made()
    else
        return self:_receive()
    end
end

function TCP:send(msg)
    if not self.connected then
        return nil
    else
        return self:_send(msg)
    end
end

return TCP
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...