GithubHelp home page GithubHelp logo

jinq0123 / grpc-lua Goto Github PK

View Code? Open in Web Editor NEW
153.0 12.0 22.0 352 KB

The Lua gRPC binding. HTTP/2 based RPC http://grpc.io

License: BSD 3-Clause "New" or "Revised" License

Batchfile 1.22% Lua 52.14% C++ 38.01% Python 2.70% CMake 1.79% C 4.14%
grpc lua

grpc-lua's Introduction

gRPC-Lua

The Lua gRPC binding.

Dependencies

gRPC-Lua depends on

See doc/conan-graph.html

All these libraries can be installed by conan C/C++ package manager.

Build

Quick Build

  1. Install conan.
  2. Add conan repositories
    • conan remote add remote_bintray_conan-community https://api.bintray.com/conan/conan-community/conan
    • conan remote add remote_bintray_bincrafters https://api.bintray.com/conan/bincrafters/public-conan
    • conan remote add remote_bintray_inexorgame https://api.bintray.com/conan/inexorgame/inexor-conan
    • conan remote add remote_bintray_conan https://api.bintray.com/conan/conan/conan-transit
    • conan remote add remote_bintray_jinq0123 https://api.bintray.com/conan/jinq0123/test
  3. conan create . user/channel --build missing
    • The result grpc_lua.dll/grpc_lua.so is in ~/.conan/data/grpc-lua/0.1/user/channel/package/...

VS solution

See premake/README.md to use premake5 to generate VS solution.

Tutorial

Tutorial shows some codes in the route_guide example.

Define the service

See examples/route_guide/route_guide.proto.

// Interface exported by the server.
service RouteGuide {
  // A simple RPC.
  rpc GetFeature(Point) returns (Feature) {}

  // A server-to-client streaming RPC.
  rpc ListFeatures(Rectangle) returns (stream Feature) {}

  // A client-to-server streaming RPC.
  rpc RecordRoute(stream Point) returns (RouteSummary) {}

  // A Bidirectional streaming RPC.
  rpc RouteChat(stream RouteNote) returns (stream RouteNote) {}
}
...

Import proto file

For both client and server codes:

local grpc = require("grpc_lua.grpc_lua")
grpc.import_proto_file("route_guide.proto")

No need to generate codes.

Client

See examples/route_guide/route_guide_client.lua.

Create a stub

    local c_channel = grpc.channel("localhost:50051")
    local stub = grcp.service_stub(c_channel, "routeguide.RouteGuide")

Call service method

  • Sync call

    • Simple RPC: sync_get_feature()

       local feature = stub.sync_request("GetFeature", point(409146138, -746188906))
    • Server-side streaming RPC: sync_list_features()

       local sync_reader = stub:sync_request_read("ListFeatures", rect)
       while true do
       	local feature = sync_reader.read_one()
       	if not feature then break end
       	print("Found feature: "..inspect(feature))
       end  -- while
    • Client-side streaming RPC: sync_record_route()

       local sync_writer = stub.sync_request_write("RecordRoute")
       for i = 1, 10 do
       	local feature = db.get_rand_feature()
       	local loc = assert(feature.location)
       	if not sync_writer.write(loc) then
       		break
       	end  -- if
       end  -- for
       
       -- Recv status and reponse.
       local summary, error_str, status_code = sync_writer.close()
       if summary then
       	print_route_sumary(summary)
       end
    • Bidirectional streaming RPC: sync_route_chat()

       local sync_rdwr = stub.sync_request_rdwr("RouteChat")
       
       for _, note in ipairs(notes) do
       	sync_rdwr.write(note)
       end
       sync_rdwr.close_writing()
       
       -- read remaining
       while true do
       	local server_note = sync_rdwr.read_one()
       	if not server_note then break end
       	print("Got message: "..inspect(server_note))
       end  -- while
  • Async call

    • Simple RPC: get_feature_async()

       stub.async_request("GetFeature", point(409146138, -746188906),
       	function(resp)
       		print("Get feature: "..inspect(resp))
       		stub.shutdown()  -- to return
       	end)
       stub.run()  -- run async requests until stub.shutdown()
      • Ignore response

         stub.async_request("GetFeature", point())  -- ignore response
      • Set error callback

        stub.set_error_cb(function(error_str, status_code) ... end) before async_request()

    • Run the stub

      • Async calls need run()
         stub.run()  -- run async requests until stub.shutdown()
      • stub.shutdown() ends stub.run().
    • Server-side streaming RPC: list_features_async()

       stub.async_request_read("ListFeatures", rect,
       	function(f)
       		assert("table" == type(f))
       		print(string.format("Got feature %s at %f,%f", f.name,
       			f.location.latitude/kCoordFactor, f.location.longitude/kCoordFactor))
       	end,
       	function(error_str, status_code)
       		assert("number" == type(status_code))
       		stub.shutdown()  -- To break Run().
       	end)
       stub.run()  -- until stub.shutdown()
    • Client-side streaming RPC: record_route_async()

       local async_writer = stub.async_request_write("RecordRoute")
       for i = 1, 10 do
       	local f = db.get_rand_feature()
       	local loc = f.location
       	if not async_writer:write(loc) do break end  -- Broken stream.
       end  -- for
       
       -- Recv reponse and status.
       async_writer.close(
       	function(resp, error_str, status_code)
       		if resp then
       			print_route_summary(resp)
       		end  -- if
       		stub.shutdown()  -- to break run()
       	end)
       stub.run()  -- until stutdown()
    • Bidirectional streaming RPC: route_chat_async()

       local rdwr = stub.async_request_rdwr("RouteChat",
       	function(error_str, status_code)
       		stub.shutdown()  -- to break run()
       	end)
      
       for _, note in ipairs(notes) do
       	rdwr.write(note)
       end
       rdwr.close_writing()  -- Optional.
       rdwr.read_each(function(server_note)
       	assert("table" == type(server_note))
       	print("Got message: "..inspect(server_note))
       end)
      
       stub.run()  -- until shutdown()

Server

See examples/route_guide/route_guide_server.lua.

Start server

    local svr = grpc.server()
    svr:add_listening_port("0.0.0.0:50051")
    -- Service implementation is a table.
    local service = require("route_guide_service")
    svr:register_service("routeguide.RouteGuide", service)
    svr:run()

Implement service

Service is a table with the service functions defined in the proto file. The function name must be the same as in the proto file. The function parameters are different for different RPC method types.

  1. Simple RPC: GetFeature()

    --- Simple RPC method.
    -- @tab request
    -- @tparam Replier replier
    function M.GetFeature(request, replier)
    	assert("table" == type(request))
    	assert("table" == type(replier))
    	local name = get_feature_name(request)
    	local response = { name = name, location = request }
    	replier:reply(response);
    end  -- GetFeature()

    replier can be copied and reply() later.

  2. Server-side streaming RPC: ListFeatures()

    --- Server-to-client streaming method.
    -- @table rectangle
    -- @tparam Writer writer
    function M.ListFeatures(rectangle, writer)
    	assert("table" == type(rectangle))
    	assert("table" == type(writer))
    	...
    	for _, f in ipairs(db.features) do
    		local l = f.location
    		if l... then
    			if not writer.write(f) then
    				print("Failed to write.")
    				break
    			end  -- if not writer.write()
    		end  -- if l
    	end  -- for _, f
    	writer.close()
    end  -- ListFeatures()
  3. Client-side streaming RPC: RecordRoute()

    • Should return a reader table:

       --- Client-to-server streaming method.
       -- @tab replier `Replier` object
       -- @treturn table server reader object
       function M.RecordRoute(replier)
       	assert("table" == type(replier))
       	return require("server_reader.RecordRouteReader"):new(replier, db)
       end  -- RecordRoute()
    • the reader table should optionally have these methods

      • function Reader:on_msg(msg)
      • function Reader:on_error(error_str, status_code)
      • function Reader:on_end()
  4. Bidirectional streaming RPC: RouteChat()

    • Should return a reader table.

       --- Bi-directional streaming method.
       -- @table writer `Writer` object
       -- @treturn table server reader object
       function M.RouteChat(writer)
       	assert("table" == type(writer))
       	return require("server_reader.RouteChatReader"):new(writer, db)
       end  -- RouteChat()
    • The reader table should optionally have methods as client-side streaming reader.

Example codes

How to run examples

  1. Install dependencies into ~/.conan/data using conan install

    1. Rename examples/conan_install.bat.example to conan_install.bat
    2. Run it.
  2. Copy required exe and dll.

    1. Rename examples/copy_from_conan.bat.example to copy_from_conan.bat
    2. Change variables in copy_from_conan.bat
      • conandata, conan data dir, default ~/.conan/data
      • package names, conan package names for dependencies
        • lua_cpp_package
        • luapbintf_package
        • grpc_lua_package
    3. Run it, which will copy exe and dlls from ~/.conan/data
      • lua-cpp.exe
      • lua-cpp.dll
      • luapbintf.dll
      • grpc_lua.dll
  3. Start lua script

    • helloworld
      • lua-cpp.exe greeter_server.lua
      • lua-cpp.exe greeter_client.lua
    • route_guide
      • lua-cpp.exe route_guide_server.lua
      • lua-cpp.exe route_guide_client.lua

API doc

See doc/ldoc/html/index.html

TODO: Integrate into Unity

Note: If you are using grpc only as client, grpc-tolua is another option.

I think it is easy to integrate grpc-lua into Unity, but I have no time to do this. Work is:

  • Use C version of Lua
  • Support Lua5.1 and LuaJIT
  • Build for iOS and Android

Unity uses Lua library compiled as C. If use lua.exe and lua.lib compiled as C, C++ objects on stack must be destructed correctly on error. See LuaIntf error handling.

Building with Lua51 or LuaJIT library should succeed. LuaPbIntf, which is used to encode and decode protobuf messages, need to be recompiled with Lua51 or LuaJIT.

grpc-lua's People

Contributors

jinq0123 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

grpc-lua's Issues

Lua 5.1 / LuaJIT support

Attempting to run the examples with Lua52, Lua51 and LuaJIT result in the examples hanging or crashing.

Is there any possibility of supporting lua51 release which will also add support for the popular and the very fast http://luajit.org/ lua implementation?

I am relatively new to the lua ecosystem so I am not sure how difficult this will be (although I am assuming it is not trivial amount of work given the number of dependencies etc.).

Based on martanne/vis#291 it looks like it could be possible to get LuaJit compatible with 5.2 although most applications of luaJit would probably not be using this patch.

bintray is closed.

run "conan create . user/channel --build missing" on mac and be required to login with username:

Please log in to "remote_bintray_jinq0123" to perform this action. Execute "conan user" command.

How can i create it on my mac?

Lib stuck on require

Update:
Ok, so I was able to build everything (yay) but when importing the libgrpc_lua.so there's some weird stuff going on. I tried adding it to the same folder of the lua file I'm running with lua 5.2. If I use it as your README file says, it's just does not find the lib, so I had to do this:

print("requiring lib")
local grpc = require "grpc_lua_c"
print("loaded lib")

which does not raise an error, but does not import the file, I only see the first print.
Am I doing anything wrong?

Luarocks rock

How about making a rockspec for luarock package and upload it to the luarock website ?

can not build success

follow your build step
can not build success!

error log:
Unable to load conanfile in /Users//.conan/data/Protobuf/3.4.1/jinq0123/testing/export/conanfile.py
File "/Users/
/.conan/data/Protobuf/3.4.1/jinq0123/testing/export/conanfile.py", line 1, in
from conans import ConanFile, CMake, tools, ConfigureEnvironment
ImportError: cannot import name ConfigureEnvironment

centos 7.8 compile fail.

following content is compile error log. how can i fix ?

/usr/bin/ld: CMakeFiles/lua-cpp-console.dir/src/lua.cpp.o: undefined reference to symbol 'readline'
//usr/lib64/libreadline.so.6: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
gmake[2]: *** [lua-cpp] Error 1
gmake[1]: *** [CMakeFiles/lua-cpp-console.dir/all] Error 2
gmake[1]: *** Waiting for unfinished jobs....
[100%] Built target luac-cpp
gmake: *** [all] Error 2
lua-cpp/5.3.4@jinq0123/testing:
lua-cpp/5.3.4@jinq0123/testing: ERROR: Package '4f7d6d5032b1a188f98e0c149ef6bf91e76af63e' build failed
lua-cpp/5.3.4@jinq0123/testing: WARN: Build folder /root/.conan/data/lua-cpp/5.3.4/jinq0123/testing/build/4f7d6d5032b1a188f98e0c149ef6bf91e76af63e
ERROR: lua-cpp/5.3.4@jinq0123/testing: Error in build() method, line 32
	cmake.build()
	ConanException: Error 2 while executing cmake --build '/root/.conan/data/lua-cpp/5.3.4/jinq0123/testing/build/4f7d6d5032b1a188f98e0c149ef6bf91e76af63e' '--' '-j8'

Server/service shutdown on remote client command

I have no idea how to implement the Subj. Is there any way to call service own methods over RPC?

greeter_service.lua
--- Hello world greeter example server side service.
-- greeter_service.lua

local M = {}

local grpc = require("grpc_lua.grpc_lua")
grpc.import_proto_file("helloworld.proto")

--- Public functions.
-- @section public

function M.SayHello(request, replier)
assert("table" == type(request))
assert("table" == type(replier))
print("Got hello from "..request.name)
-- replier:reply() can be called later after return.
local response = { message = "Hello "..request.name }
replier:reply(response);
end -- SayHello()

function M.shutdown()
--self:shutdown() !!! Something like this
end

return M

options.static_rt doesn't exist

当跑windows示例时,提示
ERROR: protobuf/3.5.1@bincrafters/stable: 'options.static_rt' doesn't exist,这个是什么原因呢
image

Cannot build manually on MacOS

conan create . user/channel --build missing
Auto detecting your dev setup to initialize the default profile (/Users/vbandam/.conan/profiles/default)
Found apple-clang 12.0
Default settings
os=Macos
os_build=Macos
arch=x86_64
arch_build=x86_64
compiler=apple-clang
compiler.version=12.0
compiler.libcxx=libc++
build_type=Release
*** You can change them in /Users/vbandam/.conan/profiles/default ***
*** Or override with -s compiler='other' -s ...s***

Exporting package recipe
grpc-lua/0.1@user/channel: A new conanfile.py version was exported
grpc-lua/0.1@user/channel: Folder: /Users/vbandam/.conan/data/grpc-lua/0.1/user/channel/export
grpc-lua/0.1@user/channel: Exported revision: 413280be5bcd4269060cd21f870be801
Configuration:
[settings]
arch=x86_64
arch_build=x86_64
build_type=Release
compiler=apple-clang
compiler.libcxx=libc++
compiler.version=12.0
os=Macos
os_build=Macos
[options]
[build_requires]
[env]

grpc_cb_core/0.1@jinq0123/testing: Not found in local cache, looking in remotes...
grpc_cb_core/0.1@jinq0123/testing: Trying with 'conancenter'...
grpc_cb_core/0.1@jinq0123/testing: Trying with 'remote_bintray_conan-community'...
ERROR: Failed requirement 'grpc_cb_core/0.1@jinq0123/testing' from 'grpc-lua/0.1@user/channel'
ERROR: 410: Gone. [Remote: remote_bintray_conan-community]

It's wrong when execute conan_install.sh in example

This's wrong message.
/usr/bin/ld: cannot find -lreadline
collect2: error: ld returned 1 exit status
gmake[2]: *** [liblua-cpp.so] Error 1
gmake[1]: *** [CMakeFiles/lua-cpp.dir/all] Error 2
gmake: *** [all] Error 2
lua-cpp/5.3.4@jinq0123/testing:
lua-cpp/5.3.4@jinq0123/testing: ERROR: Package '4f7d6d5032b1a188f98e0c149ef6bf91e76af63e' build failed
lua-cpp/5.3.4@jinq0123/testing: WARN: Build folder /root/.conan/data/lua-cpp/5.3.4/jinq0123/testing/build/4f7d6d5032b1a188f98e0c149ef6bf91e76af63e
ERROR: lua-cpp/5.3.4@jinq0123/testing: Error in build() method, line 32
cmake.build()
ConanException: Error 512 while executing cmake --build '/root/.conan/data/lua-cpp/5.3.4/jinq0123/testing/build/4f7d6d5032b1a188f98e0c149ef6bf91e76af63e' '--' '-j8'

Integration with other lua environments

Is there a way to provide your own socket connecting/reading/writing functionality?
Or alternatively, a way to get the underlying file descriptor that needs to be waited on?

Thanks.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.