so, im learning about socket progamming, and im trying to make a simple tcp chatroom server in lua.
It connects fine to a single client, but when aother client tries to join the server, it waits until the other client quits and then it joins
server.lua
require('socket')
server = assert(socket.bind('localhost', 69420))
clients = {}
--data = {} --use later
function broadcast(message)
if message then
for _, client in pairs(clients) do
client:send(message .. '\n')
end
end
end
function handle(client)
while 1 do
local buff, err = client:receive()
if err then
print(err)
client:send("error occurred = ".. err)
client:close()
break
else
print(buff)
broadcast(buff)
end
end
end
function recieve()
while 1 do
server:settimeout(0.01) -- tried adding this, still didn't worked
local client = server:accept()
if client then
table.insert(clients, client)
print("a new client entered")
broadcast("a new client has joined us\n")
coroutine.wrap(handle)(client) --this was supposed to handle the clients
end
end
end
print("localhost server listening on port 69420... nice")
recieve()
also, im using this client script:
client.lua
-- simple script just to check for server errors
require('socket')
client = socket.tcp()
client:connect("localhost", 69420)
client:send("hello\n")
while 1 do
local s, status, partial = client:receive()
print(s or partial)
if status == "closed" then
break
end
end
client:close()
I suggest using a multithreaded library, such as Lanes. If you only want to use LuaSocket, you need to follow the order below (pseudocode):
while 1 do
server:accept()
...
for i,client in ipairs(clients) do
client:receive()
...
client:send()
...
end
end
You can use socket.select
to filter out the clients that have already received data or ready to send data, thus avoiding having to loop through all clients each time:
local recvt, sendt, err = socket.select(clients, clients, 0.01)
if not err then
if recvt then
-- Calling receive on clients in this table will immediately return.
for k,c in ipairs(recvt) do
local line, err = c:receive()
end
end
if sendt then
-- Same as recvt
for k,c in ipairs(sendt) do
end
end
end