lua-сокет, обрабатывающий несколько подключений

мой вопрос касается сокетов lua, скажем, у меня есть чат, и я хочу создать бота для этого чата. Но в чате есть несколько комнат, все на разных серверах, которые рассчитываются функцией с именем getServer, функция подключения будет выглядеть так

function connect(room)
   con = socket.tcp()
   con:connect(getServer(room), port)
   con:settimeout(0)
   con:setoption('keepalive', true)
   con:send('auth' .. room)

и функция для цикла будет

function main()
   while true do
     rect, r, st = socket.select({con}, nil, 0.2)
     if (rect[con] ~= nil) then
        resp, err, part = con:receive("*l")
        if not( resp == nil) then
            self.events(resp)
 end
    end
       end
          end

теперь, когда все это работает, он получает данные только из первой комнаты, и я не знаю, как это исправить.


person user3103366    schedule 24.03.2014    source источник
comment
Покажите код, где вы вызываете connect() для каждой комнаты, и основной, не показывайте куски. И исправить плохой отступ.   -  person Oliver    schedule 25.03.2014
comment
Я свяжу его с репозиторием github, потому что файл слишком большой;( ссылка на Github[ссылка] просто добавьте socket.select() и вот что я получил   -  person user3103366    schedule 25.03.2014
comment
Это не то, что я имел в виду. Покажите код, который вызывает connect(room), и код, который вызывает main(). Ссылка, которую вы прикрепили, не содержит ни того, ни другого.   -  person Oliver    schedule 25.03.2014
comment
Извините, функция main() является функцией ch_handler, а соединение вызывается внутри ch_init, а функция ch_init вызывается в example.lua здесь ссылка на example.lua   -  person user3103366    schedule 25.03.2014
comment
Вам необходимо создать SSSCE. Слишком много кода. Возможно, con, который является глобальным набором в ch_connect, а затем используется в ch_handler, но каждое соединение будет перезаписывать ссылку последним соединением?   -  person Oliver    schedule 25.03.2014
comment
затем, если он перезаписывает, как мне это исправить, если бы это был python, я бы просто указал соединение с dict имени комнаты, а затем сделал функцию getCons, которая возвращает списки ключей и значений, тогда я бы создал список читателей и писателей передайте это на выбор, затем повторите список чтения   -  person user3103366    schedule 26.03.2014


Ответы (1)


Попробуйте создать массив соединений. Также может быть полезна карта места для соединений. Пример:

local connections = {}
local roomConnMap = {}

function connect(room)
   local con = socket.tcp()
   con:connect(getServer(room), port)
   con:settimeout(0)
   con:setoption('keepalive', true)
   con:send('auth' .. room)

   table.insert(connections, con)
   roomConnMap[room] = con
end

function main()
   while true do
     local rect, r, st = socket.select(connections, nil, 0.2)
     for i, con in ipairs(rect) do 
        resp, err, part = con:receive("*l")
        if resp ~= nil then
            self.events(resp)
        end
     end
   end
end

Обратите внимание, что rect — это массив элементов, найденных соединений, для которых есть данные для чтения. Таким образом, в цикле for i,con con — это объект соединения, не используйте connections[con] (это не имеет смысла, потому что соединения — это массив, а не карта).

person Oliver    schedule 25.03.2014
comment
Я пробовал это, сначала он говорит, что пытается вызвать значение таблицы, поэтому я сделал for con in ipairs(rect) do, и он никогда не подключается к комнате. - person user3103366; 26.03.2014
comment
не совсем так, когда я запускаю ваш код, он подключается к комнате, но не получает данные, как я, for con in ipairs(rect) do resp, err, part = connection[con]:receive('*l') потому что, насколько я понимаю. socket.select() Использует массив, и этот массив содержит каждое соединение, выбирает задание для ожидания получения данных, а затем выводит это соединение в виде числа, например, соединение содержит два соединения r1, r2. Когда r1 получает данные, значение con равно 1, а когда r2 получает данные, значение con равно 2, верно? Но когда он получает данные, он выводит ошибку. - person user3103366; 27.03.2014
comment
который говорит, attempt to index field '?' (a nil value) и эта ошибка исходит от receive() - person user3103366; 27.03.2014
comment
@user3103366 user3103366 Это потому, что у меня было несколько ошибок в коде, который я добавил. Посмотрите, будет ли это лучше. В коде в вашем комментарии отсутствует i, который я добавил в свой обновленный ответ, и объясните, почему не использовать connection[con]. Обратите внимание, что я использовал connections, а не connection, так как это массив. Надеюсь, теперь это работает. - person Oliver; 27.03.2014
comment
большое спасибо, теперь работает. Забавно то, что я пробовал цикл for таким образом однажды, но я забыл использовать ipairs вместо пар, эта проблема решена. - person user3103366; 27.03.2014
comment
Потрясающе, приятно знать. Не забудьте проголосовать за любые ответы, которые вы считаете полезными (по всем вопросам, которые вы читаете, а не только по своим). - person Oliver; 27.03.2014