lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


It was thus said that the Great Mark Hamburg once stated:
> On Feb 15, 2010, at 1:40 PM, Sean Conner wrote:
> 
> > It was thus said that the Great Doug Rogers once stated:
> > 
> >> Have you posted the C source behind your TCP
> >> server - the code that starts the coroutines and handles the sockets
> >> (presumably using epoll())?
> > 
> >  No, I haven't---it's a bit rough and there isn't much documentation, but
> > plenty of example code (and yes, it does use epoll()).  I can put up what I
> > have if anyone is interested.  One limitiation---it only uses a single
> > process.  I could use multiple processes (or threads) but that would
> > complicate the code quite a bit.
> 
> Please do.

  Okay, I'm doing so.  Anyone interested in writing simple TCP services in
Lua can grab:

	http://www.conman.org/software/misc/luadaemon.tar.gz

  You will also need to grab and install the following first though:

	http://www.conman.org/software/cgilib/cgilib-6.0.0.tar.gz

(while that library does have something to do with CGI scripting (in C),
there are also a bunch of useful routines I use in other projects and it's
easier for me to release that as well, instead of trying to pull it apart
and package it up under the luadaemon package).  

  It should compile cleanly under Linux and bomb under anything else (as I
think only Linux has the epoll() system calls, which is what I use).  I've
written up some very minimal documentation, but anyone conversant enough
with C and Lua should be able to follow the code.

  As an indication of how easy it is to write a service, here is the echo
service:
	
	-- each connection will be its own Lua "thread", with execution
	-- starting with main()
	
	function main(socket)
	  while true do
	    socket:write(socket.read("*a"))
	  end
	end

  And a simple chat server:

	if members == nil then
	  members = {}
	end

	if handles == nil then
	  handles = {}
	end

	local function login(socket)
	  local handle
	  
	  repeat
	    if handle ~= nil then
	      socket:write(string.format("%s already taken, try again\n",handle))
	    end
	    socket:write("Handle you go by: ")
	    handle = socket:read()
	  until handles[handle] == nil
	  
	  handles[handle] = socket
	  return handle  
	end
	
	local function wallaction(socket,who,everybody,me)
	  for connection in pairs(members) do
	    if connection ~= socket then
	      connection:write(string.format("%s %s\n",who,everybody))
	    else
	      if me ~= nil then connection:write(string.format("%s\n",me)) end
	    end
	  end
	end
	
	local function wall(socket,who,everybody,me)
	  return wallaction(socket,who .. ":",everybody,me)
	end

	function main(socket)
	  local name      = login(socket)
	  members[socket] = name
	  
	  wallaction(socket,name,"is in da room!","You are in the room.")
	  io.stdout:write(string.format("%s has joined the party!\n",name))
	  
	  while true do
	    wall(socket,name,socket:read())
	  end
	end
	
	function fini(socket)
	  io.stdout:write(string.format("%s has left the party!\n",members[socket]))
	  wallaction(socket,members[socket],"has left the building!")
	  handles[members[socket]] = nil
	  members[socket] = nil
	end

  -spc (Eat and enjoy)