Skip to content

moteus/lua-lluv

Repository files navigation

lua-lluv

Licence Build Status

Lua low level binding to libuv

Compatible with libuv>=1.0.0

Install

Stable version

luarocks install lluv

Current master

luarocks install --server=http://luarocks.org/dev lluv

Related projects

Example

Basic tcp/pipe echo server

local uv = require "lluv"

local function on_write(cli, err)
  if err then return cli:close() end
end

local function on_read(cli, err, data)
  if err then return cli:close() end
  cli:write(data, on_write)
end

local function on_connection(server, err)
  if err then return server:close() end
  server
    :accept()
    :start_read(on_read)
end

local function on_bind(server, err, host, port)
  if err then
    print("Bind fail:" .. tostring(err))
    return server:close()
  end

  if port then host = host .. ":" .. port end
  print("Bind on: " .. host)

  server:listen(on_connection)
end

uv.tcp():bind("127.0.0.1", 5555, on_bind)

uv.pipe():bind([[\\.\pipe\sock.echo]], on_bind)

uv.run()

Coroutine based echo server

local uv     = require "lluv"
local ut     = require "lluv.utils"
local socket = require "lluv.luasocket"

local function echo(cli)
  while true do
    local msg, err = cli:receive("*r")
    if not msg then break end
    cli:send(msg)
  end
  cli:close()
end

local function server(host, port, fn)
  local srv = socket.tcp()

  srv:bind(host, port)

  while true do
    local cli = srv:accept()

    ut.corun(function()
      -- attach socket to current coroutine
      fn(cli:attach())
    end)
  end
end

ut.corun(server, "127.0.0.1", 5555, echo)

uv.run()

Using lluv.luasocket with origin LuaSocket modules.

The main problem that LuaSocket uses protect function to wrap its functions (e.g. http.request) So there may be problem with yield from such functions. The problem solved since commit 5edf093 and only for Lua >= 5.2. So if you use Lua 5.1/LuaJIT or you can not update LuaSocket you have trouble with using lluv.luasocket module.

To solve this problem you can use try or try-lua modules. This modules implement same functionality as LuaSocket's protect function. To replace LuaSocket implementation with this module you can use this code.

local socket = require "socket"
local try    = require "try"

socket.newtry  = try.new
socket.protect = try.protect
socket.try     = try.new()

This allows you use old version of LuaSocket with Lua >=5.2. Also if you use try-lua and bacause of it uses pcall function to implement protect this allows use lluv.luasocket on LuaJIT and on Lua 5.1 with Coco patch.

But this is not help solve problem with stock Lua 5.1. I do not know full solution for this but with using try.co module you can use socket.http, socket.smtp moudules.

At first you should replace socket.protect with try.co implementation

local socket = require "socket"
local try    = require "try.co"

socket.newtry  = try.new
socket.protect = try.protect
socket.try     = try.new()

And when you have to use socket object from lluv.luasocket module you should manually attach it to work coroutine.

local function http_request(url)
  -- this is work coroutine
  local co = coroutine.running()
  http.request{
    ...
    create = function()
      -- attach to work coroutine
      return socket.tcp():attach(co)
    end;
  }
end

You can also check out full example cohttp