123456789_123456789_123456789_123456789_123456789_

Using EventMachine in C/C++ Programs

You can use EventMachine as a standalone library to implement high-speed I/O in C/C++ programs. An example of a simple EventMachine echo server.

  #include "project.h"
  #include <iostream>

  using namespace std;

  class MyConnection: public EM::Connection {
    public:
      void ReceiveData (const char *data, int length) {
        cout << data;
        this->SendData(data, length);
      }

      void PostInit() {
        cout << "Post Init\n";
      }

      void Unbind() {
        cout << "Unbind\n";
      }
  };

  class MyAcceptor: public EM::Acceptor {
    public:
      MyConnection *MakeConnection() { 
        cout << "Received new connection!\n";
        return new MyConnection();
      }  
  };

  void start () {
    EM::Acceptor *echo = new MyAcceptor();
    echo->Start("127.0.0.1", 2202);
  }

  int main() {
    cout << "Starting the Reactor..\n";
    EM::Run(start);
    cout << "Finished Successfully!\n";
    return 0
  }

In order to get this to compile you’ll need to create a static library for your application to link against.

The steps are as follows

--- ./ext/em.cpp	2008-06-17 14:40:07 -0700
+++ ./ext/em.cpp	2008-06-28 20:18:11.000000000 -0700
@@ -635,12 +635,14 @@
 _SelectDataSelect
 *****************/

+#ifdef BUILD_FOR_RUBY
 static VALUE _SelectDataSelect (void *v)
 {
 	SelectData_t *sd = (SelectData_t*)v;
 	sd->nSockets = select (sd->maxsocket+1, &(sd->fdreads), &(sd->fdwrites), NULL, &(sd->tv));
 	return Qnil;
 }
+#endif

 /*********************
 SelectData_t::_Select
@@ -648,6 +650,7 @@

 int SelectData_t::_Select()
 {
+	#ifdef BUILD_FOR_RUBY
 	#ifdef HAVE_TBR
 	rb_thread_blocking_region (_SelectDataSelect, (void*)this, RB_UBF_DFL, 0);
 	return nSockets;
@@ -656,6 +659,7 @@
 	#ifndef HAVE_TBR
 	return rb_thread_select (maxsocket+1, &fdreads, &fdwrites, NULL, &tv);
 	#endif
+	#endif
 }

This will give you a static library that you can link against.

There is an example rake file available to build CPP programs with.

One important thing to remember is that if your EventMachine files were compiled with any libraries (-lcrypto -lssl etc.) then your target application will need to pass those flags to the linker as well.

A sample project might look like the following

A typical compiler command (on OSX) for the previous directory setup may look like:

g++ -I. -I./include \
  -DHAVE_SYS_EVENT_H -DHAVE_SYS_QUEUE_H \
  -DHAVE_OPENSSL_SSL_H -DHAVE_OPENSSL_ERR_H  \
  -D_XOPEN_SOURCE -D_DARWIN_C_SOURCE -DOS_UNIX \
  -DHAVE_KQUEUE -DWITH_SSL \
  -fno-common -D_XOPEN_SOURCE=1  -fno-common -pipe -fno-common -c source/*.cpp

A typical linker command (on OSX) for the previous directory setup may look like:

g++ -o myserver main.o -L. -L./lib -L/usr/local/lib -leventmachine -lC -lcrypto -lssl  -lpthread -ldl -lobjc