Click here to Skip to main content
15,895,256 members
Articles / Desktop Programming / Win32

How To Add Simple Web-enabled 2D/3D Dashboards to your Natively Built Application

Rate me:
Please Sign up or sign in to vote.
4.92/5 (26 votes)
29 Dec 2010CPOL6 min read 58.4K   2.7K   65  
The webonization of gnuplot
#include <stdio.h>
#include <stdlib.h>
#include <snorkel.h>
#define DEFAULT_NUM_THREADS 2

void
syntax (char *pszProg)
{
  fprintf (stderr, "syntax error:\n");
  fprintf (stderr,
           "%s -i <index_file_directory> [-p <http_port>] [-P <https_port>][-l <log>] "
           "[[-b <bandwidth_in_megabits> -d|r <delay_in_ms>]|[-w tcp_window_size]][-t number_of_threads]\n"
           "[-L linger_time_in_seconds][-T timeout_in_seconds][-k keep_alive_connections][-K keep_alive_timeout]\n",
           pszProg);
  exit (1);
}


void
main (int argc, char *argv[])
{
  int i = 1;
  int http_port = 0;
  int https_port = 0;
  char *pszIndex = 0;
  char *pszLog = 0;
  char szExit[10];
  snorkel_obj_t logobj = 0;
  snorkel_obj_t http = 0;
  char *pszBandwidthInMegabits = 0;
  double bandwidth = 0.0;
  double roundtrip = 0.0;
  char *pszRoundTripMilliseconds = 0;
  int sndbuffsize = 66560;
  int chthreads = DEFAULT_NUM_THREADS;
  int slinger = 10;
  int timeout = 0;
  int keep_alive = 0; /* no keep alive by default */
  int keep_alive_timeout = 15;

  for (; i < argc; i++)
    {
      if (argv[i][0] == '-' || argv[i][0] == '/')
        {
          char carg = argv[i][1];

          switch (carg)
            {
		    case 'K':
			  keep_alive_timeout = atoi (argv[i + 1]);
			  break;
		    case 'k':
			  keep_alive = atoi (argv[i + 1]);
			  i++;
			  break;
            case 'P':
              https_port = atoi (argv[i + 1]);
              i++;
              break;
            case 'p':
              http_port = atoi (argv[i + 1]);
              i++;
              break;
            case 'L':
              slinger = atoi (argv[i + 1]);
              i++;
              break;
            case 'i':
              pszIndex = argv[i + 1];
              i++;
              break;
            case 'l':
              pszLog = argv[i + 1];
              i++;
              break;
            case 'b':
              bandwidth = (atof (argv[i + 1]) * 1000000.0);
              i++;
              break;
            case 'r':
            case 'd':
              roundtrip = atof (argv[i + 1]) / 1000;
              i++;
              break;
            case 'w':
              sndbuffsize = atoi (argv[i + 1]);
              i++;
              break;
            case 't':
              chthreads = atoi (argv[i + 1]);
              i++;
              break;
            case 'T':
              timeout = atoi (argv[i + 1]);
              i++;
              break;
            case 'h':
              syntax (argv[0]);
              break;
            default:
              syntax (argv[0]);
              break;
            }
        }

    }
  if (!http_port && !https_port)
    http_port = 80;


  if (roundtrip > 0.0 && bandwidth > 0.0)
    {
      sndbuffsize = (int) ((bandwidth * roundtrip) / 8.0F);

    }

/* align to a page if greater */
  if (sndbuffsize > 0)
    {
      if (sndbuffsize > 1024)
        {
          sndbuffsize /= 1024;
          sndbuffsize = sndbuffsize * 1024;
        }

      printf ("send buffer size set to %d bytes\n",
              sndbuffsize);
    }

  if (pszLog)
    {
      logobj = snorkel_obj_create (snorkel_obj_log, pszLog);
      if (!logobj)
        {
          perror ("could not create log file\n");
          exit (1);
        }
#if defined(_DEBUG) || defined(DEBUG)
      snorkel_debug (1);
#endif
    }

  /*
   *
   * always call first to initialize
   * snorkel API
   *
   */
  if (snorkel_init () != SNORKEL_SUCCESS)
    {
      perror ("could not initialize snorkel\n");
      exit (1);
    }

  /*
   *
   * disable thread governor
   *
   */
  if (chthreads > DEFAULT_NUM_THREADS)
    {
		snorkel_obj_t sys = snorkel_get_sys ();
		snorkel_obj_set (sys, snorkel_attrib_thread_governor, chthreads);
    }
  /*
   *
   * create a server object
   *
   */
  http = snorkel_obj_create (snorkel_obj_server,
                             chthreads, pszIndex);
  if (!http)
    {
      perror ("could not create server object!\n");
      exit (1);
    }


  /*
   *
   * identify plug-in directory
   *
   *
   */
  /* note: path to bubble directory or NULL (current directory)/bubbles */
  if (snorkel_obj_set (http, snorkel_attrib_bubbles, NULL)
      != SNORKEL_SUCCESS)
    {
      fprintf (stderr,
               "error encountered setting bubbles!\n");
      exit (1);
    }

  snorkel_obj_set (http, snorkel_attrib_show_dir, 1);   /* turn on directory display */
  /*
   *
   * add listeners
   *
   */
  if (http_port)                /* http port */
    {
      if (snorkel_obj_set (http,
                           snorkel_attrib_listener,
                           http_port, 0) != SNORKEL_SUCCESS)
        {
          fprintf (stderr,
                   "error could not add listener for port %d\n",
                   http_port);
          exit (1);
        }
    }

  if (https_port)               /* https port */
    {
      /*
       *
       * tell server where SSL certificate is
       *
       */
      if (snorkel_obj_set (http,
                           snorkel_attrib_ssl,
                           "snorkel.pem") !=
          SNORKEL_SUCCESS)
        {
          fprintf (stderr,
                   "error could not add listener for port %d\n",
                   https_port);
          exit (1);
        }
      /*
       *
       * set up SSL listener
       *
       */
      if (snorkel_obj_set (http,
                           snorkel_attrib_listener,
                           https_port,
                           1) != SNORKEL_SUCCESS)
        {
          fprintf (stderr,
                   "error could not add listener for port %d\n",
                   https_port);
          exit (1);
        }
    }

  /*
   *
   * connection linger
   *
   */
  if (snorkel_obj_set
      (http, snorkel_attrib_linger, slinger)
      == SNORKEL_ERROR)
    {
      fprintf (stderr,
               "error could not set linger value\n");
      exit (1);
    }
  if (timeout
      && snorkel_obj_set (http, snorkel_attrib_timeout,
                          timeout) == SNORKEL_ERROR)
    {
      fprintf (stderr, "error could not set timeout\n");
      exit (1);
    }

  if (snorkel_obj_set
      (http, snorkel_attrib_ipvers, IPVERS_IPV4,
       SOCK_SET) == SNORKEL_ERROR)
    {
      fprintf (stderr, "error could not set ip version\n");
      exit (1);
    }

  /*
   *
   * set http keepalive attribute
   *
   */
  if (keep_alive >= 0)
    {
		if (snorkel_obj_set (http, snorkel_attrib_keepalive, keep_alive)
			!= SNORKEL_SUCCESS)
		  {
			  fprintf (stderr,
				       "error encountered setting keep alive!\n");
			  exit (1);
		   }
    }

   if (snorkel_obj_set (http, snorkel_attrib_keepalive_timeout, keep_alive_timeout)
	   != SNORKEL_SUCCESS)
     {
		 fprintf (stderr,
			      "error encountered setting keep alive timeout!\n");
		 exit (1);
     }

  /*
   *
   * set send/receive buffer size. 
   * must be called after listeners added,
   * only applies to existing listeners. 
   * can't be called after server started.
   *
   */
  if (sndbuffsize)
    {
      if (snorkel_obj_set
          (http, snorkel_attrib_tcpbuffsize,
           sndbuffsize) != SNORKEL_SUCCESS)
        perror ("could not set send buffer size!\n");
    }

  fprintf (stderr,
           "\n\n[HTTPS] starting embedded server...\n");

  /*
   *
   * start server, no more editing or creation
   * of objects allowed after this point
   *
   */
  if (snorkel_obj_start (http) != SNORKEL_SUCCESS)
    {
      perror ("could not start server\n");
      snorkel_obj_destroy (http);
      if (logobj)
        snorkel_obj_destroy (logobj);
      exit (1);
    }


  /*
   *
   * server is on a separate thread
   * we need to do something to prevent from exiting
   *
   */
#ifdef FOREGROUND
  fprintf (stderr,
           "\n[HTTP] started.\n\n--hit enter to terminate--\n");
  fgets (szExit, sizeof (szExit), stdin);

  fprintf (stderr, "[HTTP] bye\n");

  /*
   *
   * graceful termination of server
   *
   */
  if (http)
    snorkel_obj_destroy (http);
  if (logobj)
    snorkel_obj_destroy (logobj);
  exit (0);
#else
  while (1)
    {
      sleep (120);
    }
#endif

}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Architect
United States United States
Currently I am a Software Architect for Compuware specializing in software security
Languages: C/C++, FORTRAN, COBOL, Java
Libraries: OpenGL, MFC, X11 (X-Windows), WIN32

Platform Experience: AIX, HP-UX, SunOS, Open VMS, AS400, OSF, AIX, SGI, Linux, Windows CE, Windows

I have a strong background in 3D graphics programming, TCP/IP development, threading, cross platform development, encryption and secured communications, and system level programming.

In the early years before OpenGL made its way to the PC world, I authored one of the first high performance double buffered 3D graphics engines that supported both DOS and Windows providing real time 3D graphics for Engineering Technology Associate’s Finite Element Model Builder, FEMB. You can see their products at www.eta.com.

I also hold a US patent http://www.patentstorm.us/patents/6894690.html

Comments and Discussions