From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on ip-172-31-65-14.ec2.internal X-Spam-Level: X-Spam-Status: No, score=-3.2 required=3.0 tests=BAYES_00,NICE_REPLY_A, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 Path: eternal-september.org!reader01.eternal-september.org!.POSTED!not-for-mail From: "Dmitry A. Kazakov" Newsgroups: comp.lang.ada Subject: Re: Broadcast / iterate to all Connection objects via Simple Components? Date: Wed, 8 Feb 2023 09:55:12 +0100 Organization: A noiseless patient Spider Message-ID: References: <392dd5d3-4df1-403f-b703-ee6f750dbc81n@googlegroups.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit Injection-Date: Wed, 8 Feb 2023 08:55:11 -0000 (UTC) Injection-Info: reader01.eternal-september.org; posting-host="ec93abd9fe313c475d9184d379c2c1be"; logging-data="121742"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/PH4XSmKirnC9ywMT0HQjtrLGqdN33aPY=" User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:102.0) Gecko/20100101 Thunderbird/102.6.1 Cancel-Lock: sha1:aeTc573gATPwiiazpU5VWKgc7UY= In-Reply-To: <392dd5d3-4df1-403f-b703-ee6f750dbc81n@googlegroups.com> Content-Language: en-US Xref: reader01.eternal-september.org comp.lang.ada:64902 List-Id: On 2023-02-07 21:29, A.J. wrote: > In an effort to better learn network programming in Ada, I've been working through the Protohacker Challenges (https://protohackers.com/), and the current challenge (number 3) is to create a chat server. > > I am using a TCP Connections Server with Simple Components, specifically a Connection_State_Machine, but I've run into a problem.  I'm trying to send a message received via "procedure Process_Packet (Client : in out Server_Connection)" to all connected Clients. > > My (potentially incorrect) thought on how to accomplish this is to iterate through all of the clients currently connected, and use Send to send the message received to those clients.  I've been struggling with how to actually do this though, since I couldn't use "function Get_Clients_Count (Listener : Connections_Server) return Natural" from within Process_Packets. > > Another thought I had could be to just place every message received in a central queue, and then once all of the packets have been received, to then process that queue and send the results to every connected client. > > I tried overriding "procedure On_Worker_Start (Listener : in out Connections_Server)", thinking that I could use it to read such a queue, but it never seemed to be called from within my program and I'm still unsure how to iterate through the Connection objects anyway. > > Am I approaching this the right way, or am I missing something very obvious?  I've read the test files that came with Simple Components, including the data server but couldn't see a way to get each client to interact with each other. If I didn't explain this well enough, please let me know, I'll be happy to clarify. Short answer, clients never interact, but nothing prevents you from maintaining a list of clients, e.g. in the factory of. Long answer. If you have to create a messages board, that is lot more than mere TCP/IP clients. Clients are only a carrier of messages. I presume you would need: - Some archive of messages, persistent or not maintained by the server. - Identification of recipients, which come and go. Usually a client authenticates itself upon connection to the server via one of countless schemas user/password/hash/challenge etc. - Thus you need some user authentication store/database, again, persistent or not. Or use an external one, like LDAP etc. - The messages stored by the server need unique identifiers and likely time stamp, and likely poster identification, and the list of the recipients. E.g. in the authentication store each user would have the list of received message identifiers. - The server runs a task (or tasks) dispatching messages from the store to all users connected through currently active clients. The task walks messages list and the list of all clients, for each client it looks if the message was successfully sent to the client's user. If not, the task sends it. Since all communication is asynchronous the message receipt is too asynchronous to sending. On confirmation of receipt, the user messages list is updated. You might need more than Boolean receipt flag. E.g. "sending in progress" to prevent multiple sending and/or repeated messages filter on the client side. And server /= socket listener, there could be many client /= user, client plays a role of some authenticated user -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de