This repository was archived by the owner on Jun 26, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2
Socket Communication
kmussel edited this page Dec 17, 2010
·
1 revision
Socket communication is broken up into 3 classes.
- Socket
- serverSocket
- clientSocket
Both the client and server socket classes are derived from Socket.
Overview
For the client and server socket to communicate we attach listeners to them. These listeners trigger a callback when there is data on the socket. Inside these callbacks is where we call our javascript callbacks if they were set.
For example:
Inside client New function
/**
* Creates new event to listen on socket
* When socket is ready for reading will trigger the ClientSocket::onRead function
**/
struct event * readEvent = event_new(myCEvents->base, so->m_sock, EV_READ|EV_PERSIST, ClientSocket::onRead, (void *)(so));
event_add(readEvent, NULL);
so->whichEvents["readEvent"] = readEvent;Inside the onRead function
/**
* Checks if we set the "onData" callback and executes it if it is.
**/
if(so->FuncIsSet.count("onData")){
if((so->FuncIsSet["onData"])->IsFunction()){
Handle<Value> val = {String::New(data.c_str())};
Handle<Value> res = (so->FuncIsSet["onData"])->Call(v8::Context::GetCurrent()->Global(), 1, &val);
}
}
Creating and Setting Callbacks:
Simply duplicate the following example. You'll need to change the "onData" text to whatever you want and change "Socket" to whatever class you're adding this to. This example shows how the socket onData listener is declared.
// JS_METHOD is just a macro to declare the v8 javascript methods
JS_METHOD(Socket::onData)
{
HandleScope scope;
Socket *so = UnwrapObject(args.This());
if(args[0]->IsFunction()){
so->FuncIsSet["onData"] = Persistent<Function>::New(Handle<Function>::Cast(args[0]));
}
return scope.Close(Undefined());
}Server Overview
- Create New Instance of Server Socket *
ServerSocket *so = new ServerSocket();
so->create() // Creates the actual socket* Bind Socket to the Port and Begin Listening For Connections on Port
*
// These are combined into one step with libevent's evconnlistener_new_bind function.
so->listener = evconnlistener_new_bind(myEvents->base, ServerSocket::accept_conn_cb, (void *)so,
LEV_OPT_CLOSE_ON_FREE|LEV_OPT_REUSEABLE|LEV_OPT_CLOSE_ON_EXEC, -1, (struct sockaddr*)&so->m_addr, sizeof(so->m_addr));
- Accept New Connection
- Add new event to listen on the new connection
Client Overview
- Create New Instance of Client Socket *
ClientSocket *client = new ClientSocket();
client->create() // Creates the actual socket
client->connect(HOST, PORT); // Connect to the server* Add events to listen on the socket
Class Variables:
- Socket Base Class
- The main socket contains 2 std::maps
// Used to see if you set a callback in your javascript.
std::map<std::string, v8::Persistent<v8::Function> > FuncIsSet;
// Used to keep track of all the events that have been registered on the event_base.
std::map<std::string, event * > whichEvents;- Server Socket:
- Contains 2 std::maps
// This allows our server to keep track of all the sockets connected to the server.
std::map<int, Socket * > sockMap;
// Keeps track of the events on the accepted client socket
std::map<int, event * > socketEvents;* Contains libevent's evconnlistener to listen for incoming connections.