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!