Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ; main loop
- Repeat
- ev = NetworkServerEvent(bindPort)
- If ev
- clientID = EventClient()
- Select ev
- Case #PB_NetworkEvent_Connect
- AddElement(clients()) ; adding new client to our list
- clients()\clientID = clientID
- clients()\time = Date()
- clients()\clientIP = GetClientIP(clientID)
- clients()\clientPort = GetClientPort(clientID)
- clientSessID.s = Str(clientID + clientIP + clientPort + ElapsedMilliseconds())
- clients()\clientSessID = MD5Fingerprint(@clientSessID,StringByteLength(clientSessID))
- toLog("[" + clients()\clientSessID + "] new connection from " + IPString(clients()\clientIP))
- Case #PB_NetworkEvent_Data
- ForEach clients()
- If clientID = clients()\clientID
- clients()\time = Date()
- *buffer = AllocateMemory(#rec_buffer)
- ReceiveNetworkData(clientID,*buffer,#rec_buffer)
- request.s = PeekS(*buffer)
- toLog("got new request " + request)
- FreeMemory(*buffer)
- If FindString(request,#nt_hi) = 1 ; the client should send a correct greeting and a version info
- clientVer.s = StringField(request,2,#nt_delim)
- If Len(clientVer) > 0
- clients()\clientVer = clientVer
- workerPort.i = takePort()
- If workerPort
- AddElement(workers())
- workers()\port = workerPort
- workers()\clientIP = clients()\clientIP
- workers()\sessionID = clients()\clientSessID
- workers()\time = Date()
- *worker.worker = AllocateMemory(SizeOf(worker))
- *worker\address = bindAddress
- *worker\clientIP = workers()\clientIP
- *worker\port = workers()\port
- *worker\sessionID = workers()\sessionID
- If bindWorker(*worker\port)
- workers()\tid = CreateThread(@workerThread(),*worker)
- Delay(#worker_startup_sleep) ; give some time to the new worker
- toLog("[" + workers()\sessionID + "] [" + clients()\clientVer + "] spawned new worker on port " + Str(workers()\port) + ", tid " + Str(workers()\tid))
- SendNetworkString(clientID,#nt_conn + #nt_delim + Str(workers()\address) + #nt_delim + Str(workers()\port) + #nt_delim + workers()\sessionID)
- CloseNetworkConnection(clientID)
- DeleteElement(clients())
- Else
- toLog("can't bind new worker to port " + Str(workers()\port),#log_error)
- SendNetworkString(clientID,#nt_wait)
- EndIf
- Else
- SendNetworkString(clientID,#nt_wait)
- EndIf
- Else
- CloseNetworkConnection(clientID)
- toLog("[" + clients()\clientSessID + "] diconnected: unknown request",#log_warn)
- DeleteElement(clients())
- EndIf
- Else
- CloseNetworkConnection(clientID)
- toLog("[" + clients()\clientSessID + "] diconnected: bad client",#log_warn)
- EndIf
- Break
- EndIf
- Next
- Case #PB_NetworkEvent_Disconnect
- ForEach clients()
- If clientID = clients()\clientID
- toLog("[" + clients()\clientSessID + "] diconnected",#log_warn)
- DeleteElement(clients())
- Break
- EndIf
- Next
- EndSelect
- Else
- Delay(#default_sleep_time) ; there is no network activity, time to sleep
- EndIf
- ForEach workers()
- If IsThread(workers()\tid)
- If Date() - workers()\time > #worker_forced_timeout
- KillThread(workers()\tid)
- toLog("[" + workers()\sessionID + "] killed worker with tid " + Str(workers()\tid) + " due to timeout",#log_warn)
- unbindWorker(workers()\port)
- freePort(workers()\port)
- LockMutex(workerResLock)
- ForEach workersRes()
- If workers()\sessionID = workersRes()\sessionID
- DeleteElement(workersRes())
- Break
- EndIf
- Next
- UnlockMutex(workerResLock)
- DeleteElement(workers())
- EndIf
- Else
- foundRes.b = #False
- LockMutex(workerResLock)
- ForEach workersRes()
- If workers()\sessionID = workersRes()\sessionID
- foundRes = #True
- Select workersRes()\code
- Case #code_ok
- toLog("[" + workers()\sessionID + "] session ended successfully")
- export()
- Case #code_binderror
- toLog("[" + workers()\sessionID + "] worker can't bind to port " + Str(workers()\port),#log_error)
- Case #code_timeout
- toLog("[" + workers()\sessionID + "] worker exited due to timeout",#log_warn)
- Default
- toLog("[" + workers()\sessionID + "] worker died for an unknown reason (code " + Str(workersRes()\code) + "), report to the developer",#log_error)
- EndSelect
- Break
- EndIf
- DeleteElement(workersRes())
- Next
- UnlockMutex(workerResLock)
- If Not foundRes
- toLog("[" + workers()\sessionID + "] worker died silently, report to the developer",#log_error)
- EndIf
- unbindWorker(workers()\port)
- freePort(workers()\port)
- DeleteElement(workers())
- EndIf
- Next
- ForEach clients()
- If clients()\time < Date() - #client_timeout
- CloseNetworkConnection(clients()\clientID)
- toLog("[" + clients()\clientSessID + "] disconnected client due to timeout")
- DeleteElement(clients())
- EndIf
- Next
- CompilerIf #PB_Compiler_Debugger
- i = 0
- ForEach ports()
- If ports()\isFree
- i + 1
- EndIf
- Next
- Debug "workers: " + Str(ListSize(workers())) + "/" + Str(maxWorkers) + "; ports: " + Str(i) + "/" + Str(ListSize(ports())) + "; clients: " + Str(ListSize(clients())) + "; workersRes: " + Str(ListSize(workersRes()))
- CompilerEndIf
- ForEver
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement