So I was writing a tcp server in nim, I am new to the language and really love it so far. But I cannot figure out why when I run the code below:
Why does does it say 0 users after a client leaves but we still have a client connected:
Client connected to notification server from: 192.168.0.10
Users after connect: 1
Client connected to notification server from: 192.168.0.14
Users after connect: 1
192.168.0.10 has disconnected.
Users after delete: 0
import threadpool
import std/net
import user
let socket = newSocket()
socket.bindAddr(Port(32748))
socket.listen()
var The_Clients {.threadvar.}: seq[UserSocket]
proc Client_Loop(client: Socket, address: string) {.thread.} =
var MyUser = UserSocket()
MyUser.SetSocket(client)
# Add user object to
The_Clients.add(MyUser)
echo "Users after connect: ", The_Clients.len
# Listen for data
while true:
var data = ""
try:
data = client.recvLine()
except:
break
if data == "":
echo address, " has disconnected."
break
else:
echo "C -> S : ", data
MyUser.HandleData(data, The_Clients)
# remove user
var myindex = The_Clients.find(MyUser)
The_Clients.delete(myindex)
echo "Users after delete: ", The_Clients.len
var client: Socket
var address = ""
while true:
socket.acceptAddr(client, address)
echo "Client connected to notification server from: ", address
spawn Client_Loop(client, address)
From what I could find online I need to use orc gc for shared heaps so this is what I use when compiling but I'm a little lost on why my The_Clients seq doesn't seem to be shared.
Because it is a "threadvar" which means every thread has its own copy. You need to remove the threadvar annotation and instead use a lock to protect the variable.
But in Nim 2.0 times you should use Malebolgia and its new Locker[T] abstraction, it's just so much better than what the stdlib offers.