Multithreded udp-Server vs. Non blocking calls - c++

First questions here. I gave searched for this but haven't found any solution which fully answers my problem here. I'm using c++ and need to write a kind of usp chat (server and client) for programs to interact with one another. Well atm it works quite well.
I'm using Googles protobuf as Messages.
I've written it like that:
Server has a list of users curently logged in as well as a list of messages to process and distrubute.
One thread handles all receiving on its socket (I'm using one socket).
If command var in the message is login,
It looks through the list and checks for this combination of port and IP. If not in, the chat creates a new user entry.
If command logout, the server looks for the user in list and deletes it.
If command is message, the server looks if user is logged in and puts it on the message list.
The 2nd thread is for sending.
It waits till there is a message in the list and then cycles through all users to send this messages to their sockets except the sending one.
The server has set options on its socket to receive from any ip.
My question now is: is this the most performat solution?
I've read about select and poll. But it's always about multiple receiving sockets while I have only one.
I know the receiving thread may be idling all the time but in my environment there would be a high frequent message input.
I'm fairly new to socket programming but I think this was the most elegant solution. I was wondering if I could even create another thread which gets a list from receiving thread to process the messages.
Edit: how could I detect time outs?
I mean I could have a variable in the user list which increases or get set to 0. But what if messages won't come frequently. Maybe a server based ping message? Or maybe a flag on the message which get set to acknowledged and gets resend.
On the user side I need to first broadcast to find the server and then set port and up accordingly to the answer. How could I do that?
Because this should run autonomous. Meaning a client should detect dmthe server, login, sends its commands and detect wether it is still online.
On server side I don't know if this is so important. Possibly there might be a memory issue if there are too many things connected and non get logged off. Maybe I set a 1 h timeout to let it detect idle clients.

Related

c++ socket accept, list of connected clients

I have a few question about socket in c++!
First question, let's say that he writes a server for the game in which he will play 200 people at once, but accept is blocked because he already serves one client, how to deal with it?
Second question, how to download a list of all currently connected clients, so that you can then send a message to everyone?
I have a few question about socket in c++!
For future reference, please post only one question at a time. If you have multiple questions, post them separately.
let's say that he writes a server for the game in which he will play 200 people at once, but accept is blocked because he already serves one client, how to deal with it?
Use sockets in non-blocking mode, using select()/(e)poll() or other callback mechanisms to know which sockets have pending activity and when.
Otherwise, use accept() in a separate thread than other thread(s) used to service connected clients.
how to download a list of all currently connected clients, so that you can then send a message to everyone?
The server is responsible for keeping track of its connected clients. Then it can loop through that list when needed.
If a client wants to send a message to every other client, the best option is for it to send a single message to the server and ask the server to relay the message to every other client.
Otherwise, the client would have to request the list from the server, and then send a message to every other client individually.

How to keep a HTTP long-polling connection open?

I want to implement long polling in a web service. I can set a sufficiently long time-out on the client. Can I give a hint to intermediate networking components to keep the response open? I mean NATs, virus scanners, reverse proxies or surrounding SSH tunnels that may be in between of the client and the server and I have not under my control.
A download may last for hours but an idle connection may be terminated in less than a minute. This is what I want to prevent. Can I inform the intermediate network that an idle connection is what I want here, and not because the server has disconnected?
If so, how? I have been searching around four hours now but I don’t find information on this.
Should I send 200 OK, maybe some headers, and then nothing?
Do I have to respond 102 Processing instead of 200 OK, and everything is fine then?
Should I send 0x16 (synchronous idle) bytes every now and then? If so, before or after the initial HTTP status code, before or after the header? Do they make it into the transferred file, and may break it?
The web service / server is in C++ using Boost and the content file being returned is in Turtle syntax.
You can't force proxies to extend their idle timeouts, at least not without having administrative access to them.
The good news is that you can design your long polling solution in such a way that it can recover from a connection being suddenly closed.
One such design would be as follows:
Since long polling is normally used for event notifications (think the Observer pattern), you associate a serial number with each event.
The client makes a GET request carrying the serial number of the last event it has seen, either as part of the URL or in a cookie.
The server maintains a buffer of recent events. Upon receiving a GET request from the client, it checks if any of the buffered events need to be sent to the client, based on their serial numbers and the serial number provided by the client. If so, all such events are sent in one HTTP response. The response finishes at that point, in case there is a proxy that wants to buffer the whole response before relaying it further.
If the client is up to date, that is it didn't miss any of the buffered events, the server is delaying its response till another event is generated. When that happens, it's sent as one complete HTTP response.
When the client receives a response, it immediately sends a new one. When it detects the connection was closed, it creates a new one and makes a new request.
When using cookies to convey the serial number of the last event seen by the client, the client side implementation becomes really simple. Essentially you just enable cookies on the client side and that's it.

Scalable Chat server in Clojure. Problems with presence and message arrival b/w reconnections

I am trying to build a scalable chat server in Clojure. I am using http-kit, compojure and redis pub/sub to communicate between diffrent nodes (fan-out approach). The server will use websockets for connection b/w client-server with a fallback to long polling. A single user can have multiple connections to chat with one connection per tabs in the browser and message should be delivered to the all the connections.
So basically when the user connects I store the channel in a atom with a random uuid as
{:userid1 [{:socketuuid "random uuid#1 for uerid1" :socket "channel#1 for userid1"}
{:socketuuid "random uuid#2" :socket "channel#2"}]
:userid2 [{:socketuuid "random uuid#1 for userid2" :socket "channel#1 for userid2}]}
the message is POSTed to a common route for both websockets and long polling channels, the message structure looks like
{:from "userid1" :to "userid2" :message "message content"}
the server finds all the channels in the atom for the :from and :to user ids and send the message to the connected channels for the respective users, also it publishes the message over the redis server where the connected nodes look for channels stored in their own atom and deliver message to the respective users.
So the problem I am running into is, how to properly implement presence. Basically http-kit send you a status when a channel disconnects the status can be "server-close" or "client-close", while I can handle server disconnects (the client will reconnect automatically) but I am running into problem when the disconnect happens from client side, for eg. the user navigates to another page and will connect after a few seconds. How do I decide that the user has went offline when the client disconnects. Also I am concerned about message arrival b/w reconnects in long polling mode (my long polling timeout is 30 seconds).
Also please suggest a good presence mechanism for the above architecture. Thanks.
Please comment if you need more info. Thanks
Edit #1:
Can you recommend a good tutorial/ material on implementing presence in a chat server, I cant seem to find anything on it.
My current solution -> I am currently maintaining a global count and a last connected timestamp for the connected channels of a particular userid and when a user disconnects the count is decreased, and a timeout is implemented for 10 seconds which will check if the user has reconnected again (i.e. the last connected stamp is 10 seconds old and count is still zero), if not then the user is said to have gone offline, would you recommend this solution, If not why, or any improvements or better methods are appreciated.
Also please note I am using the timer/scheduled-task in http-kit, would these timeout significant performance effects?
There are two different cases here from client side.
Long Polling. I cannot see how this is a problem, if the client window closes, there wont be no polling anymore. One client less which asks for data.
Websockets. There is a close method available in the protocol. The client should send a notification if you implement it correctly. See here: Closing WebSocket correctly (HTML5, Javascript) for instance.
Does that answer your question?

C++ socket concurrent server

I'm writing a concurrent server that's supposed to have a communication channel and a data channel.
The client initially connects to the communication channel to authenticate, upon successful authentication, the client is then connected to the data channel to access data.
My program is already doing that, and I'm using threads. My only issue is that if I try to connect another client, I get a "cannot bind : address already in use" error.
I have it this way:
PART A
Client connects to port 4567 (and enters his login info). A thread is spawned to handle the client (repeated for each client that connects). In the thread created, I have a function (let's call it FUNC_A) that checks the client's login info (don't worry about how the check is done), if successful, the thread starts the data server (listening on 8976), then sends an OK to the client, once received the client attempts to connect to the data server.
PART B
Once a client connects to the data server, from inside FUNC_A the client is accepted and another thread is spawned to handle the client's connection to the data server (hopefully everything is clear).
Now, all that is working fine. However, if I try to connect with second client when it gets to PART B I get a "cannot bind error: address already in use". I've tried so many different ways, I've even tried spawning a thread to start the data server and accept the client and then start another thread to handle that connection. Still no luck.
Please give me a suggestion as to what I'm doing wrong, how do I go about doing this or what's the best way to implement it.
Thank you
Your problem lies in the following: "...the thread starts the data server(listening on 8976)..."
If I understand you correctly, every time a client connects, you're trying to start listening on port 8976. The problem is, however, that there can be only one socket listening on a given port. When you try to start listening on the same port again, you get that error.
Therefore, you have two options:
Have the server listen on whatever port is free (just specify 0 when binding), and send the port number to the client, so that the client can connect to it.
Start the server only once, at the beginning, and have it accept client connections.
The second option, however, has a big problem: how are you going to tell one client from another? Therefore, I recommend going with the first option.
Some food for thought: what you're describing is pretty much exactly how FTP works. And FTP servers use the first option. Not coincidentally, perhaps? ;-)

HTTP stream server: threads?

I already wrote here about the http chat server I want to create: Alternative http port?
This http server should stream text to every user in the same chat room on the website. The browser will stay connected and wait for further html code. (yes that works, the browser won't reject the connection).
I got a new question: Because this chat server doesn't need to receive information from the client, it's not necessary to listen to the client after the server sent its first response. New chat messages will be send to the server on a new connection.
So I can open 2 threads, one waiting for new clients (or new messages) and one for the html streaming.
Is this a good idea or should I use one thread per client? I don't think it's good to have one thread/client when there are many chat users online, since the server should handle multiple different chats with their own rooms.
3 posibilities:
1. One thread for all clients, send text to each client successive - there shouldn't be much lag since it's only text
this will be like: user1.send("text");user2.send("text"),...
2. One thread per chat or chatroom
3. One thread per chat user - ... many...
Thank you, I haven't done much with sockets yet ;).
Right now, you seem to be thinking in terms of a given thread always carrying out a given (type of) task. While that basic design can make sense, to produce a scalable server like this, it generally doesn't work very well.
Often a slightly more abstract viewpoint works out better: you have tasks that need to get done, and threads that do those tasks -- but a thread doesn't really "care" about what task it executes.
With this viewpoint, you simply need to create some sort of data structure that describes each task that needs to be done. When you have a task you want done, you fill in a data structure to describe the task, and hand it off to get done. Somewhere, there are some threads that do the tasks.
In this case, the exact number of threads becomes mostly irrelevant -- it's something you can (and do) adjust to fit the number of CPU cores available, the type of tasks, and so on, not something that affects the basic design of the program.
I think easiest pattern for this simple app is to have pool of threads and then for each client pick available thread or make it wait until one becomes available.
If you want serious understanding of http server architecture concepts google following:
apache architecture
nginx architecture