0

I am creating a chat app and want a server to broadcast every message that a client sends it, but the client is receiving no data after the server broadcasts the client message. I am using Lua lanes for multithreading, Lua-JSON for json encoding and decoding and Lua socket for networking.

Here is the server code:

local socket = require 'socket'
local json = require 'json'
local log = require '3rd.log'
local connection = require 'src.connection'

local udp = socket.udp()
udp:setsockname('*', 7777) -- Bind to all interfaces with *
log.info('Created server socket.')
local rest_time = 0 -- Everytime the server handles a request, it will rest for X time.
local connections = {}

while true do
    local data, msg_or_ip, port_or_nil = udp:receivefrom()

    if data then
        log.info(string.format('Received data from %s:%d: %s', msg_or_ip, port_or_nil, data))

        local connection_exists = false
        for _, client in pairs(connections) do
            if client.ip == msg_or_ip and client.port == port_or_nil then
                connection_exists = true
                -- Break so then we dont loop through anymore connections (saving time)
                break
            end
        end

        if not connection_exists then
            local new_connection = connection.new()
            new_connection.ip = msg_or_ip
            new_connection.port = port_or_nil
            print(json.encode(new_connection))

            table.insert(connections, new_connection)
            log.info(string.format('Added new connection: %s:%d', new_connection.ip, new_connection.port))
        end

        -- Broadcast message
        for _, client in pairs(connections) do
            print('broad')
            print(json.encode(client))
            udp:sendto(data, client.ip, client.port)
            log.info(string.format('Sent data to %s:%d: %s', client.ip, client.port, data))
        end

    elseif msg_or_ip ~= 'timeout' then
        log.error('Network error: '..tostring(msg_or_ip))
    end

    socket.sleep(rest_time)
end

Here is the client code:

local lanes = require 'lanes'.configure()
local log = require '3rd.log'
local packet = require 'src.packet'

-- Sender thread: sends data
local start_sender = lanes.gen('*', function(linda, address, port)
    local socket = require 'socket'
    local json = require 'json'

    local udp = socket.udp()
    udp:setpeername(address, port)

    local user = 'Unknown'

    while true do
        local msg = io.read()

        if msg == ':quit' then
            -- Send a should_quit signal.
            linda:set('should_quit', true)
            break
        end

        local msg_packet = packet.new()
        msg_packet.msg = msg
        msg_packet.user = user

        local json_data = json.encode(msg_packet)
        udp:send(json_data)
        log.info('Sent JSON data: '..json_data)
    end
end)

local socket = require 'socket'
local address, port = 'localhost', 7777
local udp = socket.udp()
udp:setpeername(address, port)
udp:settimeout(10)

-- Start listener and sender threads
-- Linda is a part of Lanes that lets you essentially send data between threads.
local linda = lanes.linda()
linda:set('should_quit', false)
start_sender(linda, address, port)

-- Wait until we receive a signal from linda that we should quit.
while not linda:get('should_quit') do
    print('a')
    local data, msg = udp:receive()
    print(data)

    if data then
        log.info(string.format('Received data: %s', data))
        print('data gotten')
    elseif msg ~= 'timeout' then
        log.error('Network error: '..tostring(msg))
        print('network error')
    end
    print('b')
end

Thank you!

0

Browse other questions tagged or ask your own question.