Re: [twsocket] using Twsocket with a few thousand clients
> why when i give each client its own DataAvaialbe i hav eno problems at all > what is the diffrence ? and should i do that with all other events ? Your question is not clear. Please reformulate it and keep a SHORT summary of the previous message, just enough to understand what you ask. To have a good answer, you have to ask a good question... -- francois.pie...@overbyte.be The author of the freeware multi-tier middleware MidWare The author of the freeware Internet Component Suite (ICS) http://www.overbyte.be -- To unsubscribe or change your settings for TWSocket mailing list please goto http://lists.elists.org/cgi-bin/mailman/listinfo/twsocket Visit our website at http://www.overbyte.be
Re: [twsocket] using Twsocket with a few thousand clients
why when i give each client its own DataAvaialbe i hav eno problems at all what is the diffrence ? and should i do that with all other events ? في الأحد، 12 أغسطس 2018 في 7:48 م تمت كتابة ما يلي بواسطة عاشقه كبريائي < madamma...@gmail.com>: > I will do the logging I am just a bit confused because this is my first > time to use ics , > > Is there any clear demo to run tcp server in threaded manner ? The demos > in the source confused me too much is there any updated demo to better serv > tcp with threading as you suggested ? > > On Sat, Aug 11, 2018, 1:01 PM عاشقه كبريائي wrote: > >> i have created a tcp server using Twsocket but after 40 clients connected >> the server stopped from listing >> >> i dont use any VCL inside the server i just do some database query and >> send some data to all connected clients >> >> >> i dont know what i am doing wrong >> >> here is my server code >> >> >> unit Mainserv; >> >> interface >> >> uses >> Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, >> System.Classes, Vcl.Graphics, >> Vcl.Controls, Vcl.Forms, Vcl.Dialogs, IdGlobal, Vcl.StdCtrls, >> Vcl.ExtCtrls, >> Vcl.Imaging.GIFImg, Vcl.Imaging.pngimage, JPEG, System.DateUtils, >> OverbyteIcsWndControl, OverbyteIcsWSocket, OverbyteIcsWSocketS; >> >> >> const >> Sep = '~'; >> >> type >> TConnection = class(TWSocketClient) >> private >> procedure ISALIVE; >> >> >> >> >> >> >>public >> cName: String; >> cpassword : string; >> IP: String; >> Connected: TDateTime; >> Cuserid: string; >> CisLoggedin : string; >> CANENETR : string; >> status : integer; >> ForceDC : String; >> >> procedure broadcastleft(const usernameleft: string); >> procedure SendCommandWithParams(const Command: String); >> procedure HandleLogin; >> procedure broadcastjoin; >> procedure broadcastmsg(const msgtxt: String); >> procedure SendClientsList; >> >> >> >> >> >> >> end; >> >> >> type >> TForm3 = class(TForm) >> Panel1: TPanel; >> Edit1: TEdit; >> Button1: TButton; >> Button2: TButton; >> servertcp: TWSocketServer; >> procedure FormDestroy(Sender: TObject); >> procedure Button1Click(Sender: TObject); >> procedure Button2Click(Sender: TObject); >> procedure servertcpBgException(Sender: TObject; E: Exception; >> var CanClose: Boolean); >> procedure servertcpClientConnect(Sender: TObject; Client: >> TWSocketClient; >> Error: Word); >> procedure servertcpClientDisconnect(Sender: TObject; Client: >> TWSocketClient; >> Error: Word); >> procedure servertcpDataAvailable(Sender: TObject; ErrCode: Word); >> >> private >> >> procedure UpdateBindings; >> { Private declarations } >> public >> { Public declarations } >> end; >> >> var >> Form3: TForm3; >> >> implementation >> uses crypto, mysql_qry, constant; >> >> {$R *.dfm} >> >> { TConnection } >> >> >> >> procedure TForm3.Button1Click(Sender: TObject); >> begin >> >> >> UpdateBindings; >> >> >> servertcp.ClientClass := TConnection; >> LastUniqueID := 100; >> end; >> >> procedure TForm3.Button2Click(Sender: TObject); >> begin >> servertcp.Close; >> end; >> >> procedure TForm3.FormDestroy(Sender: TObject); >> begin >> servertcp.Close; >> end; >> >> >> >> >> >> >> >> >> >> procedure TConnection.ISALIVE; >> var >> I: integer; >> uclient: TConnection; >> begin >> >> if self.CnotAllowed = 'YES' then >> begin >> exit; >> end; >> >> >> >> self.Connected := Now; >> >> >> >> for i := 0 to TWSocketServer(Server).ClientCount -1 do >> begin >> uclient := TConnection(TWSocketServer(Server).Client[i]); >> if (sametext(uclient.Chatname, self.Chatname)) >> And (uclient.ForceDC = 'NO') >> And (SecondsBetween(Now, uclient.Connected) >= 75) then >> begin >> uclient.ForceDC := 'YES'; >> uclient.Close; >> >> end; >> end; >> >> >> end; >> >> >> >> procedure TForm3.servertcpDataAvailable(Sender: TObject; ErrCode: Word); >> var >> CCLIENT: TConnection; >> Command: String; >> cmdhandle : string; >> Startercommand : String; >> Params: array [1 .. 200] of String; >> ParamsCount, P: integer; >> ReceiveParams: BOOLEAN; >> I: integer; >> DECODES : String; >> >> begin >> >> CCLIENT := Sender as TConnection; >> >> >> >> >> >> Startercommand := CCLIENT.ReceiveStrW(CP_UTF8); >> >> Command := Startercommand; >> >> >> >> >> if Command = '' then >> begin >> exit; >> end; >> >> Command := replace(Command,#13,''); >> Command := replace(Command,#10,''); >> >> >> >> ReceiveParams := False; >> >> >> //Command Type >> >> if Command[1] = '1' then // none crypted >> begin >> Command := Copy(Command, 2, MaxInt); >> ReceiveParams := true; >> end else >> if Command[1] = '2' then // crypted >> begin >> Command := Copy(Command, 2, MaxInt); >> Command := Decryptstrs(Command); >> ReceiveParams := true; >> end; >> >> >> >> >> if ReceiveParams = true then // params is incomming >> begin >> DECODES := Command; >> >> ParamsCount := 0; >> while (DECODES <> '') and (ParamsCount
Re: [twsocket] using Twsocket with a few thousand clients
Hello, I already had a similar problem. If you are on Windows plateform, there a limit of message that can be queued, for so many user maybe you reached that one. That was my case with only 30 clients but a lot of small data sent for each one. When i reach this limit the TWSocketServer simply do not accept no connection and totally stop working, but the rest of my program was working perctly. To avoid that i simply avoid to send lot of message so i concatenated to call the minimum of Write(String); MSDN Source : https://msdn.microsoft.com/fr-fr/library/windows/desktop/ms644944(v=vs.85).a spx There is a limit of 10,000 posted messages per message queue. This limit should be sufficiently large. If your application exceeds the limit, it should be redesigned to avoid consuming so many system resources. To adjust this limit, modify the following registry key. Good luck ! Moro Alexandre. -Message d'origine- De : TWSocket [mailto:twsocket-boun...@lists.elists.org] De la part de François Piette Envoyé : dimanche 12 août 2018 17:02 À : 'ICS support mailing' Objet : Re: [twsocket] using Twsocket with a few thousand clients I forget to say that to support a few thousand simultaneous client, it is likely that yu should pour TWSocketServer code into a thread to service, let's say, 500 client per thread. And you should probably NOT use the main thread to run TWSocketServer code. Be aware that ICS is asynchronous and it will multitask (cooperatively) nicely within a thread and serve a lot of connections in a single thread. But this is not infinite : Windows has his limits (Nothing in ICS limit the number of connections nor the number of threads). If you are used with some other socket component, you should probably forget everything you know. ICS has a totally and unique programming model. What is good for a synchronous blocking socket is NOT what you should do with ICS which is asynchronous, non-blocking and event driven. -- francois.pie...@overbyte.be The author of the freeware multi-tier middleware MidWare The author of the freeware Internet Component Suite (ICS) http://www.overbyte.be -- To unsubscribe or change your settings for TWSocket mailing list please goto http://lists.elists.org/cgi-bin/mailman/listinfo/twsocket Visit our website at http://www.overbyte.be -- To unsubscribe or change your settings for TWSocket mailing list please goto http://lists.elists.org/cgi-bin/mailman/listinfo/twsocket Visit our website at http://www.overbyte.be
Re: [twsocket] using Twsocket with a few thousand clients
> Is there any clear demo to run tcp server in threaded manner ? > The demos in the source confused me too much is there any updated > demo to better serv tcp with threading as you suggested ? Don't worry about a threaded server until you reach a slow down on your non-threaded version, get the basics working first. ICS does have an old demo that uses one thread per client, but not one that uses one thread per x hundred clients. And using threads slows down applications, avoid if possible. The simplest 'threaded' version is two copies running on two servers for load sharing and redundancy. Angus -- To unsubscribe or change your settings for TWSocket mailing list please goto http://lists.elists.org/cgi-bin/mailman/listinfo/twsocket Visit our website at http://www.overbyte.be
Re: [twsocket] using Twsocket with a few thousand clients
I will do the logging I am just a bit confused because this is my first time to use ics , Is there any clear demo to run tcp server in threaded manner ? The demos in the source confused me too much is there any updated demo to better serv tcp with threading as you suggested ? On Sat, Aug 11, 2018, 1:01 PM عاشقه كبريائي wrote: > i have created a tcp server using Twsocket but after 40 clients connected > the server stopped from listing > > i dont use any VCL inside the server i just do some database query and > send some data to all connected clients > > > i dont know what i am doing wrong > > here is my server code > > > unit Mainserv; > > interface > > uses > Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, > System.Classes, Vcl.Graphics, > Vcl.Controls, Vcl.Forms, Vcl.Dialogs, IdGlobal, Vcl.StdCtrls, > Vcl.ExtCtrls, > Vcl.Imaging.GIFImg, Vcl.Imaging.pngimage, JPEG, System.DateUtils, > OverbyteIcsWndControl, OverbyteIcsWSocket, OverbyteIcsWSocketS; > > > const > Sep = '~'; > > type > TConnection = class(TWSocketClient) > private > procedure ISALIVE; > > > > > > >public > cName: String; > cpassword : string; > IP: String; > Connected: TDateTime; > Cuserid: string; > CisLoggedin : string; > CANENETR : string; > status : integer; > ForceDC : String; > > procedure broadcastleft(const usernameleft: string); > procedure SendCommandWithParams(const Command: String); > procedure HandleLogin; > procedure broadcastjoin; > procedure broadcastmsg(const msgtxt: String); > procedure SendClientsList; > > > > > > > end; > > > type > TForm3 = class(TForm) > Panel1: TPanel; > Edit1: TEdit; > Button1: TButton; > Button2: TButton; > servertcp: TWSocketServer; > procedure FormDestroy(Sender: TObject); > procedure Button1Click(Sender: TObject); > procedure Button2Click(Sender: TObject); > procedure servertcpBgException(Sender: TObject; E: Exception; > var CanClose: Boolean); > procedure servertcpClientConnect(Sender: TObject; Client: > TWSocketClient; > Error: Word); > procedure servertcpClientDisconnect(Sender: TObject; Client: > TWSocketClient; > Error: Word); > procedure servertcpDataAvailable(Sender: TObject; ErrCode: Word); > > private > > procedure UpdateBindings; > { Private declarations } > public > { Public declarations } > end; > > var > Form3: TForm3; > > implementation > uses crypto, mysql_qry, constant; > > {$R *.dfm} > > { TConnection } > > > > procedure TForm3.Button1Click(Sender: TObject); > begin > > > UpdateBindings; > > > servertcp.ClientClass := TConnection; > LastUniqueID := 100; > end; > > procedure TForm3.Button2Click(Sender: TObject); > begin > servertcp.Close; > end; > > procedure TForm3.FormDestroy(Sender: TObject); > begin > servertcp.Close; > end; > > > > > > > > > > procedure TConnection.ISALIVE; > var > I: integer; > uclient: TConnection; > begin > > if self.CnotAllowed = 'YES' then > begin > exit; > end; > > > > self.Connected := Now; > > > > for i := 0 to TWSocketServer(Server).ClientCount -1 do > begin > uclient := TConnection(TWSocketServer(Server).Client[i]); > if (sametext(uclient.Chatname, self.Chatname)) > And (uclient.ForceDC = 'NO') > And (SecondsBetween(Now, uclient.Connected) >= 75) then > begin > uclient.ForceDC := 'YES'; > uclient.Close; > > end; > end; > > > end; > > > > procedure TForm3.servertcpDataAvailable(Sender: TObject; ErrCode: Word); > var > CCLIENT: TConnection; > Command: String; > cmdhandle : string; > Startercommand : String; > Params: array [1 .. 200] of String; > ParamsCount, P: integer; > ReceiveParams: BOOLEAN; > I: integer; > DECODES : String; > > begin > > CCLIENT := Sender as TConnection; > > > > > > Startercommand := CCLIENT.ReceiveStrW(CP_UTF8); > > Command := Startercommand; > > > > > if Command = '' then > begin > exit; > end; > > Command := replace(Command,#13,''); > Command := replace(Command,#10,''); > > > > ReceiveParams := False; > > > //Command Type > > if Command[1] = '1' then // none crypted > begin > Command := Copy(Command, 2, MaxInt); > ReceiveParams := true; > end else > if Command[1] = '2' then // crypted > begin > Command := Copy(Command, 2, MaxInt); > Command := Decryptstrs(Command); > ReceiveParams := true; > end; > > > > > if ReceiveParams = true then // params is incomming > begin > DECODES := Command; > > ParamsCount := 0; > while (DECODES <> '') and (ParamsCount < 200) do > begin > Inc(ParamsCount); > P := Pos(Sep, DECODES); > if P = 0 then > Params[ParamsCount] := DECODES > else > begin > Params[ParamsCount] := Copy(DECODES, 1, P - 1); > Delete(DECODES, 1, P); > end; > end; > end; > > cmdhandle := Params[1]; > > > > > > if cmdhandle = '' then > begin > Exit; > end; > > > > if cmdhandle = 'LGN' then > begin > if Paramscount <> 3 then > begin > exit; > end; > CCLIENT.cName := Params[2]; > CCLIENT.cpassword := Params[3]; >
Re: [twsocket] using Twsocket with a few thousand clients
I forget to say that to support a few thousand simultaneous client, it is likely that yu should pour TWSocketServer code into a thread to service, let's say, 500 client per thread. And you should probably NOT use the main thread to run TWSocketServer code. Be aware that ICS is asynchronous and it will multitask (cooperatively) nicely within a thread and serve a lot of connections in a single thread. But this is not infinite : Windows has his limits (Nothing in ICS limit the number of connections nor the number of threads). If you are used with some other socket component, you should probably forget everything you know. ICS has a totally and unique programming model. What is good for a synchronous blocking socket is NOT what you should do with ICS which is asynchronous, non-blocking and event driven. -- francois.pie...@overbyte.be The author of the freeware multi-tier middleware MidWare The author of the freeware Internet Component Suite (ICS) http://www.overbyte.be -- To unsubscribe or change your settings for TWSocket mailing list please goto http://lists.elists.org/cgi-bin/mailman/listinfo/twsocket Visit our website at http://www.overbyte.be
Re: [twsocket] using Twsocket with a few thousand clients
> Its stopped from listening when I start loop through clients and > send back data to each one of connected cient > > I have a similar server that created with indy with the same code > logic and can run 1200 clients per port . The ICS server has been tested with over 1,200 simultaneous clients in a single thread, look back in the mailing list, search for ComGen which uses the TMagIpLog component I mentioned. So the problem is your use of the ICS code, no error handling or logging, so you have no idea why it is not responding. But you never mentioned whether your 40 clients were simultaneous or sequential. TWSocketServer is a single thread server. If you run long blocking SQL operations (more than 100ms) responding to clients, then the server is unable to process other clients at that moment and everything will slow down. But without any logging, you currently have no idea what is blocking your server, or even how many clients are connected. My ICS web server logs it's SQL activity, so I know it's not taking too long: 07:55:01 EXEC post_codes_lst_part2 'GU84DN' 07:55:01 SQL proc took 31ms 07:55:01 SQL Search Post Codes: GU84DN - Records Returned 1 If SQL is slow, the solution is run your SQL operation is a client thread, so the server can keep responding, look at the ICS web server which uses a thread to compress files and calculate CRCs to avoid blocking other clients. Angus -- To unsubscribe or change your settings for TWSocket mailing list please goto http://lists.elists.org/cgi-bin/mailman/listinfo/twsocket Visit our website at http://www.overbyte.be
Re: [twsocket] using Twsocket with a few thousand clients
Well I am running this on dedicated server with 64 gb of ram and 10 gb of vrak this is a huge server Its stopped from listening when I start loop through clients and send back data to each one of connected cient I have a similar server that created with indy with the same code logic and can run 1200 clients per port . On Sat, Aug 11, 2018, 1:01 PM عاشقه كبريائي wrote: > i have created a tcp server using Twsocket but after 40 clients connected > the server stopped from listing > > i dont use any VCL inside the server i just do some database query and > send some data to all connected clients > > > i dont know what i am doing wrong > > here is my server code > > > unit Mainserv; > > interface > > uses > Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, > System.Classes, Vcl.Graphics, > Vcl.Controls, Vcl.Forms, Vcl.Dialogs, IdGlobal, Vcl.StdCtrls, > Vcl.ExtCtrls, > Vcl.Imaging.GIFImg, Vcl.Imaging.pngimage, JPEG, System.DateUtils, > OverbyteIcsWndControl, OverbyteIcsWSocket, OverbyteIcsWSocketS; > > > const > Sep = '~'; > > type > TConnection = class(TWSocketClient) > private > procedure ISALIVE; > > > > > > >public > cName: String; > cpassword : string; > IP: String; > Connected: TDateTime; > Cuserid: string; > CisLoggedin : string; > CANENETR : string; > status : integer; > ForceDC : String; > > procedure broadcastleft(const usernameleft: string); > procedure SendCommandWithParams(const Command: String); > procedure HandleLogin; > procedure broadcastjoin; > procedure broadcastmsg(const msgtxt: String); > procedure SendClientsList; > > > > > > > end; > > > type > TForm3 = class(TForm) > Panel1: TPanel; > Edit1: TEdit; > Button1: TButton; > Button2: TButton; > servertcp: TWSocketServer; > procedure FormDestroy(Sender: TObject); > procedure Button1Click(Sender: TObject); > procedure Button2Click(Sender: TObject); > procedure servertcpBgException(Sender: TObject; E: Exception; > var CanClose: Boolean); > procedure servertcpClientConnect(Sender: TObject; Client: > TWSocketClient; > Error: Word); > procedure servertcpClientDisconnect(Sender: TObject; Client: > TWSocketClient; > Error: Word); > procedure servertcpDataAvailable(Sender: TObject; ErrCode: Word); > > private > > procedure UpdateBindings; > { Private declarations } > public > { Public declarations } > end; > > var > Form3: TForm3; > > implementation > uses crypto, mysql_qry, constant; > > {$R *.dfm} > > { TConnection } > > > > procedure TForm3.Button1Click(Sender: TObject); > begin > > > UpdateBindings; > > > servertcp.ClientClass := TConnection; > LastUniqueID := 100; > end; > > procedure TForm3.Button2Click(Sender: TObject); > begin > servertcp.Close; > end; > > procedure TForm3.FormDestroy(Sender: TObject); > begin > servertcp.Close; > end; > > > > > > > > > > procedure TConnection.ISALIVE; > var > I: integer; > uclient: TConnection; > begin > > if self.CnotAllowed = 'YES' then > begin > exit; > end; > > > > self.Connected := Now; > > > > for i := 0 to TWSocketServer(Server).ClientCount -1 do > begin > uclient := TConnection(TWSocketServer(Server).Client[i]); > if (sametext(uclient.Chatname, self.Chatname)) > And (uclient.ForceDC = 'NO') > And (SecondsBetween(Now, uclient.Connected) >= 75) then > begin > uclient.ForceDC := 'YES'; > uclient.Close; > > end; > end; > > > end; > > > > procedure TForm3.servertcpDataAvailable(Sender: TObject; ErrCode: Word); > var > CCLIENT: TConnection; > Command: String; > cmdhandle : string; > Startercommand : String; > Params: array [1 .. 200] of String; > ParamsCount, P: integer; > ReceiveParams: BOOLEAN; > I: integer; > DECODES : String; > > begin > > CCLIENT := Sender as TConnection; > > > > > > Startercommand := CCLIENT.ReceiveStrW(CP_UTF8); > > Command := Startercommand; > > > > > if Command = '' then > begin > exit; > end; > > Command := replace(Command,#13,''); > Command := replace(Command,#10,''); > > > > ReceiveParams := False; > > > //Command Type > > if Command[1] = '1' then // none crypted > begin > Command := Copy(Command, 2, MaxInt); > ReceiveParams := true; > end else > if Command[1] = '2' then // crypted > begin > Command := Copy(Command, 2, MaxInt); > Command := Decryptstrs(Command); > ReceiveParams := true; > end; > > > > > if ReceiveParams = true then // params is incomming > begin > DECODES := Command; > > ParamsCount := 0; > while (DECODES <> '') and (ParamsCount < 200) do > begin > Inc(ParamsCount); > P := Pos(Sep, DECODES); > if P = 0 then > Params[ParamsCount] := DECODES > else > begin > Params[ParamsCount] := Copy(DECODES, 1, P - 1); > Delete(DECODES, 1, P); > end; > end; > end; > > cmdhandle := Params[1]; > > > > > > if cmdhandle = '' then > begin > Exit; > end; > > > > if cmdhandle = 'LGN' then > begin > if Paramscount <> 3 then > begin > exit; > end; > CCLIENT.cName := Params[2]; >
Re: [twsocket] using Twsocket with a few thousand clients
> i have created a tcp server using Twsocket but after 40 clients connected > the server stopped from listing There is nothing in ICS which limits the numbers of simultaneous client. Only machine and operating system resources are limiting. To handle a few thousands simultaneous connections, it is likely that you need a Windows SERVER operating system, not a Windows workstation. The most limiting factor in the number of socket you may open is the memory. Each socket needs memory in non-paged memory and the amount of non-paged memory is directly linked to the total amount of memory the system has. Of course, your application may be limited by other limits on systems resources. Beware of what you do for each connection. For example, you may quickly exhaust the number of available handles if you don't program correctly. As Angus said, you sould test for errors everywhere and get error code using GetLastError to know which limit you exhausted? -- francois.pie...@overbyte.be The author of the freeware multi-tier middleware MidWare The author of the freeware Internet Component Suite (ICS) http://www.overbyte.be -- To unsubscribe or change your settings for TWSocket mailing list please goto http://lists.elists.org/cgi-bin/mailman/listinfo/twsocket Visit our website at http://www.overbyte.be
Re: [twsocket] using Twsocket with a few thousand clients
> i have created a tcp server using Twsocket but after 40 clients > connected the server stopped from listing How do you know that, I don't see anything in your code to check if the server is listening. And there is no error handling or logging, so you don't really know what is happening with your server. For instance you ignore Error in ClientConnect and ClientDisconnect. If you want to make your life easier, try using my TMagIpLog component from: https://www.magsys.co.uk/delphi/magics.asp which hides most of the server code from you, and just calls events when data is available from a new remote client. There is a demo which you can run to listen to your existing remote clients and make a single line response, obviously you need more code to do it properly. Angus -- To unsubscribe or change your settings for TWSocket mailing list please goto http://lists.elists.org/cgi-bin/mailman/listinfo/twsocket Visit our website at http://www.overbyte.be