Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 25/08/2016, à 11:37

JPlaroche

websocket c++ complet et fonctionnel avec libwebsocket

bonjour
j'ai passez quelques heures .... bref je vous fait parvenir un test complet en ligne sur mon site. trop long à mettre en ligne . comporte un ensemble javascript une feuille html et un source c++ et comment le compiler avec code block
vous y trouverez des trucs et astuces intégrer comme par exemples faire du xml  et passez le tout comme une donnée , un validator a votre main ... mais ce n'est pas le but , le but est de vous présenter libwebsocket et comment s'en servir.
voilà le source :
il vous permettra de tester et de comprendre les mécanismes  un serveur websocket en c++ .(on devrait dire d'une "application" de type web-serveur sur un socket )
pourquoi en c++ :  la liberté , de ne pas dépendre d'un environnement et surtout pas d'une complexité débordante pour intégré votre métier au sain d'une entreprise . pas de mélange de langage ...
le % de CPU est null pratiquement d’où l’intérêt de la bande passante ce limitant aux données bidirectionnel .
le ssl n'est pas mis en place pour que vous puissiez facilement tester.

nombre limite de connection concurrente 1024 par port

compatibilté: fonctionne en html5 sur   "explorer 10" --  Firefox ect...

plein d'info sur libwebsocket    https://github.com/warmcat/libwebsockets

le ppa en ligne sur notre Ubuntu  avec la dernière release 1.7.1-1  libwebsocket dev


voilà juste le code d'un serveur socket
compile :
GCC c+14 warning enable   OK

#include <stdio.h>
#include <stdlib.h>
#include <libwebsockets.h>







#define MAX_BUFFER_SIZE 4096  // a voir si pas assez grand pour un reccord

#include <fstream>
#include<string>

using namespace std;

string WEB_MESSAGE ="";
string XMLBuffer;
string line;
bool ok = false ;

bool msg_SIGTERM = false ;
FILE *f_log ;


struct lws_context * context;



struct per_session_data__client {
    char client_name [256];
	char client_ip[45];
	char client_njob[27];
	int Num_Client;
	int number =0;
};

struct connect_web {;
    char client_name [256];
    char client_ip[45]; // prev The correct maximum IPv6 string length is 45 characters
} webcon;


int Client_web = 0;



static int callback_main( struct lws *wsi,
                            enum lws_callback_reasons reason,
                            void *user,
                            void *in,
                            size_t len )


{


    char *buf = (char*) malloc(LWS_PRE +MAX_BUFFER_SIZE);

    	struct per_session_data__client *pss = (struct per_session_data__client*) user;


    switch ((int)reason) {


    case  LWS_CALLBACK_ESTABLISHED: {
            printf("connection established\n  N° client : %d\n" , Client_web );
            WEB_MESSAGE="Vous êtes connecté au  SERVEUR";
            lwsl_notice("Client_web :%d\n",Client_web);

            sprintf(pss->client_name,"%s",webcon.client_name);
            sprintf(pss->client_ip,"%s",webcon.client_ip);
            pss->number =Client_web;
            pss->Num_Client = 79928; // pour le moment  récupéré avec bd

            sprintf(pss->client_njob,"%s","20150609195701433872653505"); // calcul avec date ect...
            lwsl_notice("N° connection  %d \n  IP : %s  Name: %s\n njob:%s\n" , Client_web, pss->client_ip, pss->client_name,pss->client_njob );

            lwsl_notice("pss->number :%d\n",pss->number);
            break;
    }
    case LWS_CALLBACK_SERVER_WRITEABLE: {
            memset(&buf[LWS_PRE], 0, MAX_BUFFER_SIZE);

            if(WEB_MESSAGE >"") {

                            /// preparation de la sortie bien respecter le tampon  attention ça peux vite devenir un casse tête
                            /// norme https:https://libwebsockets.org/lws-api-doc-master/html/index.html
                               strcpy(buf+ LWS_PRE,WEB_MESSAGE.c_str() );
                               lws_write(wsi, (unsigned char *) &buf[LWS_PRE], strlen(&buf[LWS_PRE]), LWS_WRITE_TEXT);
                               WEB_MESSAGE ="";

                            // on dégage en sortie envoie par exemple: fermeture page html client send("SIGTERM");
                            // pour test ecriture log reception XMLBuffer pour control conformiter voir tinyxml
                             //  if ( stop_SIGTERM == true) { fclose(f_log);   kill(getpid(), SIGKILL); }
            }

            break;
    }
    case LWS_CALLBACK_RECEIVE: {

            // log console
            lwsl_notice("received_data:>%s<\n", (char *) in);

            // traitement recuperation pour traitement XML
            line =  string( (char *) in);

            if(line != "%}" && ok== true   ) XMLBuffer+= line ;

            if(line == "{%") { XMLBuffer =""; ok = true; } ; // start group xml

            if(line == "%}") {  // end group XML
                            ok = false;
                            WEB_MESSAGE = XMLBuffer;

                             fputs(pss->client_name, f_log);fputs(XMLBuffer.c_str(),f_log);

                            };

            if (line == "SIGTERM") {
                            lwsl_notice("SIGTERM SERVEUR\n");
                            msg_SIGTERM = true;
                            };

                   /* get notified as soon as we can write again */
                    lws_callback_on_writable(wsi);
            break;

        }

    case LWS_CALLBACK_CLOSED: {
        lwsl_notice("LWS_CALLBACK_CLOSED\n");
        Client_web --;
        printf("N° connection  %d \n" , Client_web);

        break;
    }

    case LWS_CALLBACK_FILTER_NETWORK_CONNECTION: {
        lws_get_peer_addresses(wsi, (int)(long)in, webcon.client_name, sizeof(webcon.client_name) ,webcon.client_ip, sizeof(webcon.client_ip));
        /* controle */
        Client_web += 1;

        lwsl_notice("network connect from %s (%s)\n", webcon.client_name, webcon.client_ip);
             /* if we returned non-zero from here, we kill the connection */
        break;
        }

    };
    return 0;
}


// actuelement un seul protocol pour le test
static struct lws_protocols protocols[] = {
    {
        "echo", // service
        callback_main,
        sizeof(struct per_session_data__client), // user data struct  used  
        MAX_BUFFER_SIZE,
    },{ NULL, NULL, 0, 0 } // terminator
};
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$

int main(void) {
    // server url will be http://localhost:9000


    // pour test le fichier log
f_log = fopen("logweb.txt", "r+");


//-- new Version: context 2016
struct lws_context_creation_info info;
memset(&info, 0, sizeof info);

// renseigne la structure info

info.port = 9000;

info.iface = NULL;

info.protocols = protocols;


static const struct lws_extension exts[] = {
	{
		"permessage-deflate",
		lws_extension_callback_pm_deflate,
		"permessage-deflate; client_max_window_bits"
	},
	{
		"deflate-frame",
		lws_extension_callback_pm_deflate,
		"deflate_frame"
	},
	{ NULL, NULL, NULL /* terminator */ }
};

#ifndef LWS_NO_EXTENSIONS
    info.extensions =  exts;  // sans extension  je n'ai plus de closed intenspestive  et le susytem est  bouffé
                              // avec extension  le systeme n'est lus bouffé
                              // et le timeout dans le html est quand même obligatoire dans les 2 cas
#endif
//if (!use_ssl) {
    info.ssl_cert_filepath = NULL;
    info.ssl_private_key_filepath = NULL;
//} else {
//  info.ssl_cert_filepath = LOCAL_RESOURCE_PATH"/libwebsockets-test-server.pem";
//  info.ssl_private_key_filepath = LOCAL_RESOURCE_PATH"/libwebsockets-test-server.key.pem";
//}
info.gid = -1;
info.uid = -1;

info.options = 0;


// en laissant a zeros tout ce stabilise pour faire du temps reel et commit avec le metier
info.ka_time = 0; // 60 seconds until connection is suspicious
info.ka_probes = 0; // 10 probes after ^ time
info.ka_interval =0; // 10s interval for sending probes




context = lws_create_context(&info);


    if (context == NULL) {
        fprintf(stderr, "libwebsocket init failed\n");
        return -1;
    }

    printf("starting server...\n");

    // infinite loop
    while (1) {

    if ( msg_SIGTERM == true  && Client_web == 0   ) {  fclose(f_log);
                                                        printf("connection established\n  N° client : %d\n" , Client_web );
                                                        kill(getpid(), SIGKILL); };

    if ( msg_SIGTERM == true  ) {
            WEB_MESSAGE = "CLOSE-SERVEUR";
            lws_callback_on_writable_all_protocol(context,&protocols[0]);


    };



    lws_service(context,20);
// Libwebsocket_service traitera tous les événements d'attente avec leurs fonctions
// de rappel, puis attendre 50 ms. en moyenne    J'ai passé a 20 ms qui est beaucoup plus correct lors de nombreuse connections
// (Ce qui est un seul serveur web fileté et cela permet de garder notre serveur
// de génération de charge alors qu'il ya pas de demandes à traiter)
    }

    lws_context_destroy(context);

    return 0;
}

tout le projet sur : http://www.ombrebleu.com/wxsrc/linux/

sur github example websocket mais le site le plus à jour est le mien

smile @bientôt de vous lire.

Dernière modification par JPlaroche (Le 01/10/2016, à 14:12)


depuis 2004 avec Ubuntu
depuis 1976 informaticien   Mon site plein d'information pour les programmeurs   http://www.ombrebleu.com

Hors ligne

#2 Le 25/08/2016, à 13:31

telliam

Re : websocket c++ complet et fonctionnel avec libwebsocket

Salut, en multithread ça doit pas bien marcher:)


"- Un intellectuel assis va moins loin qu'un con qui marche."
Maurice Biraud - Un Taxi pour Tobrouk
Michel Audiard

Hors ligne

#3 Le 25/08/2016, à 14:15

JPlaroche

Re : websocket c++ complet et fonctionnel avec libwebsocket

telliam a écrit :

Salut, en multithread ça doit pas bien marcher:)

Bonjour,

si j'en ai vue fonctionner mais je trouve que cela n'en vaux pas la peine
chaque connexion  d'un nouvel utilisateur tu as un socket qui lui est attribué , d’où le trhead ??? je vois pas trop la nécessité il y a quand même un exemple dans le site de libwebsocket
alors il est vrais que l'on peut jouez avec du parallélisme  mais en regardant de plus près, mais on devient compliqué  lors des envoies de messages de la part du serveur vers les utilisateurs donc toutes thread  ...  .  et en plus je prends cela pour une simplification de communication donc l’interaction user et programme métier au travers de xml qui enfin de compte n'est que le transport d'un format out & in et donne au metier les demande et réponse
j'entends par métier le code ex gestion entête de commande .
dans l'exemple que je fourni, j'ouvre  la page avec apache normalement (si j'avais des requêtes importante je passerais par apache pour récupérez mon fichier xml et monter dans un grid ... )  mais là je montre juste un conversationnel  tout ça pour dire que l'es deux sont compatible .
@bientôt de te lire


depuis 2004 avec Ubuntu
depuis 1976 informaticien   Mon site plein d'information pour les programmeurs   http://www.ombrebleu.com

Hors ligne

#4 Le 30/09/2016, à 13:04

JPlaroche

Re : websocket c++ complet et fonctionnel avec libwebsocket

telliam a écrit :

Salut, en multithread ça doit pas bien marcher:)

le seul intérêt que je vois est de n'avoir qu'un branchement comme dans le programme proposé "echo" et d'ouvrir les différents branchement thread suite a des messages  dont chaque thread serais une branche de métier pour l'utilisateur .  d'ou j'ai pensé que ce type d'application websocket on devait le voir comme un applicatif qui comporte tous ses modules .  sur que tu dois avoir un distributeur qui répond au user comment il doit ce connecter  ça fait un programme a l’écoute pour l'ensemble des utilisateur  et N programme qui démarre et seront a l’écoute des demandes sachant que si un user travaille déjà avec un module inutile dans redémarrer une deuxieme instance   est ce que tu comprends ...
@bientôt


depuis 2004 avec Ubuntu
depuis 1976 informaticien   Mon site plein d'information pour les programmeurs   http://www.ombrebleu.com

Hors ligne