├── .gitignore ├── .gitmodules ├── node.js ├── README ├── erlang.erl └── index.html /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | ebin 3 | socket.io-erlang/deps 4 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "socket.io-erlang"] 2 | path = socket.io-erlang 3 | url = git://github.com/yrashk/socket.io-erlang.git 4 | -------------------------------------------------------------------------------- /node.js: -------------------------------------------------------------------------------- 1 | var http = require('http'), 2 | io = require('socket.io'), 3 | index = require('fs').readFileSync('./index.html'); 4 | 5 | var server = http.createServer(function(req, res){ 6 | // your normal server code 7 | res.writeHead(200, {'Content-Type': 'text/html'}); 8 | res.end(index); 9 | }); 10 | server.listen(3000); 11 | 12 | // socket.io 13 | var socket = io.listen(server); 14 | socket.on('connection', function(client){ 15 | client.on('message', function(){ 16 | client.send("PONG"); 17 | }); 18 | }); -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | This is a pretty naïve comparison of socket.io implementations in nodejs and erlang. 2 | 3 | Here we have two servers that respond "PONG" to any message they receive. 4 | In order to be able to run the nodejs version, you need to have node and its socket.io module installed. You can do that with: 5 | 6 | npm install socket.io 7 | 8 | In order to be able to run the erlang version, you first need to run: 9 | 10 | git submodule init 11 | git submodule update 12 | cd socket.io-erlang 13 | make 14 | 15 | Then just run 'node node.js' or ./erlang. A http server will be started on port 3000. 16 | Note that you can't run both servers at the same time. 17 | 18 | In the webpage that will be displayed when you go to http://localhost:3000, you can set a number of messages to be sent to the server via socket.io. 19 | In my computer nodejs processes 10k messages in 1250ms, and erlang version does the same in 1050ms. 20 | With 100k messages, erlang handles them in 70secs, and node drops the connection thus failing the test. 21 | 22 | We know that benchmarks aren't really that useful, since they differ from real production code. But this one served me to decide to go with erlang instead of node for a game I will be developing. Not being able to handle 100k messages is a no-no, given that erlang is able to handle them without problem. -------------------------------------------------------------------------------- /erlang.erl: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env escript 2 | %%! -pa socket.io-erlang/ebin socket.io-erlang/deps/misultin/ebin socket.io-erlang/deps/ossp_uuid/ebin socket.io-erlang/deps/jsx/ebin socket.io-erlang/include -I ./socket.io-erlang 3 | -mode(compile). 4 | -include_lib("include/socketio.hrl"). 5 | -compile(export_all). 6 | -behaviour(gen_event). 7 | 8 | main(_) -> 9 | % appmon:start(), 10 | application:start(sasl), 11 | application:start(misultin), 12 | application:start(socketio), 13 | {ok, Pid} = socketio_listener:start([{http_port, 3000}, 14 | {default_http_handler,?MODULE}]), 15 | EventMgr = socketio_listener:event_manager(Pid), 16 | ok = gen_event:add_handler(EventMgr, ?MODULE,[]), 17 | receive _ -> ok end. 18 | 19 | %% gen_event 20 | init([]) -> 21 | {ok, undefined}. 22 | 23 | handle_event({client, Pid}, State) -> 24 | io:format("Connected: ~p~n",[Pid]), 25 | EventMgr = socketio_client:event_manager(Pid), 26 | ok = gen_event:add_handler(EventMgr, ?MODULE,[]), 27 | {ok, State}; 28 | handle_event({disconnect, Pid}, State) -> 29 | io:format("Disconnected: ~p~n",[Pid]), 30 | {ok, State}; 31 | handle_event({message, Client, #msg{ content = Content } = Msg}, State) -> 32 | % io:format("Received message: ~p~n",[Content]), 33 | socketio_client:send(Client, #msg{ content = ["PONG"]}), 34 | {ok, State}; 35 | 36 | handle_event(E, State) -> 37 | {ok, State}. 38 | 39 | handle_call(_, State) -> 40 | {reply, ok, State}. 41 | 42 | handle_info(_, State) -> 43 | {ok, State}. 44 | 45 | terminate(_Reason, State) -> 46 | ok. 47 | 48 | code_change(_OldVsn, State, _Extra) -> 49 | {ok, State}. 50 | %% 51 | 52 | handle_request('GET', [], Req) -> 53 | Req:file(filename:join([filename:dirname(code:which(?MODULE)), "index.html"])); 54 | handle_request(_Method, _Path, Req) -> 55 | Req:respond(200). 56 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Shadow world test 6 | 7 | 53 | 54 | 55 | # of messages to send: 56 | 57 |
58 |
59 |
60 | 61 | --------------------------------------------------------------------------------