Manejo de conexión de servidor multiusuario -- ++ campo con server campo con qt campo con client camp codereview Relacionados El problema

Multi-user server connection handling


3
vote

problema

Español

Estoy escribiendo un programa y tengo un servidor que necesita poder manejar múltiples conexiones de cliente a la vez realizando muchas cosas diferentes.

Estoy usando la biblioteca QT, así que manejo nuevas conexiones como esta:

En el constructor del servidor:

  Server::Server(QObject* parent): QObject(parent) {   connect(&server, SIGNAL(newConnection()), //&server is a QTcpServer object           this, SLOT(acceptConnection()));    qDebug() << "[" << currentTime() << "] " << "Server started.";   server.listen(QHostAddress::Any, PORT_NUMBER);   qDebug() << "[" << currentTime() << "] " << "Server listening."; }   

El acceptConnection Slot:

  void Server::acceptConnection() {   client = server.nextPendingConnection(); //client is a QTcpSocket* object    connect(client, SIGNAL(readyRead()), //When there is data to be read     this, SLOT(startRead())); }   

EL startRead Slot:

  void Server::startRead() {      char serverReceiveBuf[65536]; //A buffer for the data sent to the server     client->read(serverReceiveBuf, client->bytesAvailable());     handleConnection(serverReceiveBuf); //Do something with that data }   

No voy a dar la función handleConnection8 porque es un poco largo y no creo que sea necesario para la pregunta.

Mi preocupación es la latencia. Si tengo uno o dos usuarios, está bien. Pero no he probado muchos usuarios concurrentes. Hay una señal de sincronización enviada por el cliente que le pide al servidor que verifique los datos que el cliente ha coincide con los datos en el servidor. Estoy enviando esta solicitud cada 250 ms, por lo que con algunos usuarios más concurrentes, el cliente puede terminar esperando demasiado tiempo cada 250 ms debido a los otros clientes que envían en las solicitudes de sincronización.

al menos, eso es lo que creo. QT es bastante poderoso, pero no estoy totalmente seguro de si cuando se recibe una señal de que se crea automáticamente un hilo nuevo para manejar la conexión. Si no me equivoco, la forma en que manejo las conexiones implica hacer cola, de modo que cuando el servidor reciba una señal, procesará las solicitudes en el pedido recibido. Es importante tener en cuenta que no llamo client->close() hasta que el cliente termina la conexión, por lo que una vez 99887776655443310 se llama getTitle() > 01 siempre existirá hasta El cliente lo termina.

¿Es esta una buena manera de manejar múltiples conexiones, dado que tendré regularmente que los usuarios envíen solicitudes de sincronización a menudo? Si no, ¿cómo debo manejar las conexiones en su lugar?

Original en ingles

I'm writing a program and I have a server that needs to be able to handle multiple client connections at once doing many different things.

I'm using the Qt library, so I handle new connections like this:

In the server constructor:

Server::Server(QObject* parent): QObject(parent) {   connect(&server, SIGNAL(newConnection()), //&server is a QTcpServer object           this, SLOT(acceptConnection()));    qDebug() << "[" << currentTime() << "] " << "Server started.";   server.listen(QHostAddress::Any, PORT_NUMBER);   qDebug() << "[" << currentTime() << "] " << "Server listening."; } 

The acceptConnection slot:

void Server::acceptConnection() {   client = server.nextPendingConnection(); //client is a QTcpSocket* object    connect(client, SIGNAL(readyRead()), //When there is data to be read     this, SLOT(startRead())); } 

The startRead slot:

void Server::startRead() {      char serverReceiveBuf[65536]; //A buffer for the data sent to the server     client->read(serverReceiveBuf, client->bytesAvailable());     handleConnection(serverReceiveBuf); //Do something with that data } 

I'm not going to give the handleConnection function because it's a bit long and I don't think it's necessary for the question.

My worry is latency. If I have one or two users, it's fine. But I haven't tested many concurrent users. There's a synchronization signal sent by the client that asks the server to verify the data the client has matches the data on the server. I'm sending this request every 250 ms, so with a few more concurrent users the client may end up waiting too long every 250 ms because of the other clients sending in synchronization requests.

At least, that's what I believe. Qt is pretty powerful, but I'm not entirely sure if when a signal is received that a new thread is automatically created to handle the connection. If I'm not mistaken, the current way I handle connections involves queueing, so that when the server receives a signal it'll process the requests in the order received. It's important to note that I don't call client->close() until the client terminates the connection themselves, so once client = server.nextPendingConnecting(); is called client will always exist until the client terminates it.

Is this a good way of handling multiple connections, given that I'll be regularly having users send synchronization requests often? If not, how should I handle the connections instead?

           
         
         

Lista de respuestas

2
 
vote

No pude encontrar esta pregunta, así que déjame intentar dar una respuesta aquí:

una idea general:

Dependiendo de la naturaleza de los datos que están sincronizando, podría ser mejor que el servidor envíe una señal de sincronización y los clientes sincronizan a los datos recibidos del servidor.

detalles del código de la pregunta

Veo dos problemas en la función de ranura $(function(){ var ans ={ source:"../json/getmchpersonjson.php", select: function(e,u){ sysformbuild(u); }, minLength:1 }; $("#employeename").autocomplete(ans); }); 6 De acuerdo con La documentación :

  1. La función $(function(){ var ans ={ source:"../json/getmchpersonjson.php", select: function(e,u){ sysformbuild(u); }, minLength:1 }; $("#employeename").autocomplete(ans); }); 7 puede devolver 0. Esto puede llevar a un problema con la siguiente declaración de conexión. Debes verificar la respuesta 0.
  2. $(function(){ var ans ={ source:"../json/getmchpersonjson.php", select: function(e,u){ sysformbuild(u); }, minLength:1 }; $("#employeename").autocomplete(ans); }); 8 no devolverá la misma conexión con la que se envió la señal, solo devuelve "la siguiente". Esto puede llevar a un problema cuando se realizan múltiples conexiones al mismo tiempo, o su código no puede manejar a uno de ellos a tiempo. Puede ser mejor que maneje todas las conexiones pendientes en un bucle.

Con estas adiciones, su código tal vez se vería así:

  $(function(){ var ans ={ source:"../json/getmchpersonjson.php", select: function(e,u){     sysformbuild(u);     },     minLength:1 }; $("#employeename").autocomplete(ans);        }); 9  

Esto nos lleva directamente al siguiente problema: el // Base Variables0 variable - Supongo que esta es una variable de miembro del // Base Variables1 clase - se sobrescribirán para cada nueva conexión .

El mejor enfoque es seguir los consejos en la documentación y anular // Base Variables2 . Podríamos subclase // Base Variables3 e implementar las funciones // Base Variables4 desde allí. La documentación describe lo que normalmente lo hace la función de clase base.

 

I was not able to find this question on SO, so let me try to give an answer here:

A general idea:

Depending on the nature of the data your are synchronizing, it might be better that the server sends out a synchronization signal and the clients synchronize to the data received from the server.

Specifics to the code of the question

I see two problems in the slot function acceptConnection() according to the documentation:

  1. the function nextPendingConnection() may return 0. This may lead to a problem with the following connect statement. You should check for 0 response.
  2. nextPendingConnection() will not return the exact same connection for which the signal was sent, it just returns "the next one". This may lead to a problem when multiple connections are made at the same time, or your code cannot handle one of them in time. It might be better that you handle all pending connections in a loop.

With these additions your code would perhaps look like this:

void Server::acceptConnection() {    while(client = server.nextPendingConnection()) //client is a QTcpSocket*     {        connect(client, SIGNAL(readyRead()), this, SLOT(startRead()));    } } 

This brings us directly to the next problem: the client variable - I assume that this is a member variable of the Server class - will be overwritten for each new connection.

The Better approach is to follow the advice in the documentation and override incomingConnection(). We could subclass QTcpSocket and implement the handleConnection() functions from there. The documentation describes what the base class function normally does.

 
 
 
 

Relacionados problema

2  Aplicación Simple TCP Client Server con Side Side Side  ( Simple tcp client server application with receive side only ) 
Escribí la aplicación Simple TCP Client Server, me preguntaba, ¿podría revisar mi código? Estaría agradecido por cualquier sugerencia y consejos sobre la lógi...

5  C ++ Socket Part-2  ( C socket part 2 ) 
En mis intentos en curso de convertirse en un mejor escritor de blog, tengo algunos códigos más que necesitan revisar. fuente completa . primer artículo ...

31  Solicitudes de cliente HTTP realizado a la derecha  ( Http client requests done right ) 
según lo aconsejado por muchos, estoy usando un grupo de clientes, específicamente el Apache poolinghttpclientconnectionmanager . Por simplicidad, lo envuel...

6  Servicio de carrito de la compra de Python GRPC  ( Python grpc shopping cart service ) 
El archivo 99887776655443311 es lo siguiente: System.Drawing.Graphics2 y tengo un servicio 998877766555443313 en GRPC es tan simple como se muestra ...

8  TCP Chat (servidor / cliente)  ( Tcp chat server client ) 
Estoy buscando algunos consejos o consejos sobre la eficiencia, el rendimiento y algunas buenas prácticas de codificación. También tengo curiosidad por la sin...

2  Cliente API indocumentado / Envoltura en Python  ( Undocumented api client wrapper in python ) 
Obtuvo el siguiente para hacer una envoltura API para una API web indocumentada. Con la esperanza de obtener algunos comentarios sobre mi código y la elección...

1  Aplicación de gestión musical, puré de datos de varias API  ( Music management app mashing data from various apis ) 
Básicamente recibo datos de varias APIs y usando PHP para juntarlos, como un mashup web. Actualmente estoy usando 4 declaraciones para insertar los datos ...

3  Entregando datos en tiempo real desde el zócalo Backend  ( Delivering realtime data from backend socket ) 
Tengo un servidor que se ejecuta para hacer que los datos en serie estén disponibles en un puerto TCP / IP. Mi objetivo es recopilar datos provenientes de un ...

7  REST-cliente extensible  ( Extendable rest client ) 
He estado trabajando en un cliente de descanso. El propio cliente proporciona solo una funcionalidad muy básica y genérica. Todo lo demás se hace con extensio...

4  C Socket Parte-1  ( C socket part 1 ) 
En mis intentos en curso de convertirse en un mejor escritor de blog, tengo algunos códigos más que necesitan revisar. Fuente completa: https://github.com/...




© 2022 respuesta.top Reservados todos los derechos. Centro de preguntas y respuestas reservados todos los derechos