diff --git a/luarocks/LuaWebSocket.h b/luarocks/LuaWebSocket.h index 258a4d1d..26c687f3 100644 --- a/luarocks/LuaWebSocket.h +++ b/luarocks/LuaWebSocket.h @@ -1,3 +1,9 @@ +/* + * LuaWebSocket.h + * Author: Benjamin Sergeant + * Copyright (c) 2020 Machine Zone, Inc. All rights reserved. + */ + #pragma once #include @@ -5,87 +11,153 @@ extern "C" { -#include "lua.h" -#include "lauxlib.h" + #include "lua.h" + #include "lauxlib.h" } #include "luawrapper.hpp" #include #include #include +#include +#include -using namespace ix; - -WebSocket* WebSocket_new(lua_State* L) +namespace ix { - WebSocket* webSocket = new WebSocket(); - webSocket->setOnMessageCallback([](const WebSocketMessagePtr& msg) { - if (msg->type == ix::WebSocketMessageType::Message) - { - std::cout << msg->str << std::endl; - } - }); - return webSocket; -} - -int WebSocket_getUrl(lua_State* L) -{ - WebSocket* webSocket = luaW_check(L, 1); - lua_pushstring(L, webSocket->getUrl().c_str()); - return 1; -} - -int WebSocket_setUrl(lua_State* L) -{ - WebSocket* webSocket = luaW_check(L, 1); - const char* url = luaL_checkstring(L, 2); - webSocket->setUrl(url); - return 0; -} - -int WebSocket_start(lua_State* L) -{ - WebSocket* webSocket = luaW_check(L, 1); - webSocket->start(); - return 0; -} - -int WebSocket_send(lua_State* L) -{ - WebSocket* webSocket = luaW_check(L, 1); - const char* msg = luaL_checkstring(L, 2); - webSocket->send(msg); - return 0; -} - -int WebSocket_sleep(lua_State* L) -{ - WebSocket* webSocket = luaW_check(L, 1); - int duration = luaL_checkinteger(L, 2); - std::this_thread::sleep_for(std::chrono::milliseconds(duration)); - return 0; -} - -static luaL_Reg WebSocket_table[] = { - { NULL, NULL } -}; - -static luaL_Reg WebSocket_metatable[] = { - { "getUrl", WebSocket_getUrl }, - { "setUrl", WebSocket_setUrl }, - { "start", WebSocket_start }, - { "send", WebSocket_send }, - { "sleep", WebSocket_sleep }, - { NULL, NULL } -}; - -int luaopen_WebSocket(lua_State* L) -{ - luaW_register(L, - "WebSocket", - WebSocket_table, - WebSocket_metatable, - WebSocket_new - ); - return 1; + class LuaWebSocket + { + public: + LuaWebSocket() + { + _webSocket.setOnMessageCallback([this](const WebSocketMessagePtr& msg) { + if (msg->type == ix::WebSocketMessageType::Message) + { + std::lock_guard lock(_queueMutex); + _queue.push(msg->str); + } + }); + } + + void setUrl(const std::string& url) { _webSocket.setUrl(url); } + const std::string& getUrl() { return _webSocket.getUrl(); } + void start() { _webSocket.start(); } + void send(const std::string& msg) { _webSocket.send(msg); } + + const std::string& getMessage() + { + std::lock_guard lock(_queueMutex); + return _queue.front(); + } + + bool hasMessage() + { + std::lock_guard lock(_queueMutex); + return !_queue.empty(); + } + + void popMessage() + { + std::lock_guard lock(_queueMutex); + _queue.pop(); + } + + private: + WebSocket _webSocket; + + std::queue _queue; + std::mutex _queueMutex; + }; + + LuaWebSocket* WebSocket_new(lua_State* L) + { + LuaWebSocket* webSocket = new LuaWebSocket(); + return webSocket; + } + + int WebSocket_getUrl(lua_State* L) + { + LuaWebSocket* luaWebSocket = luaW_check(L, 1); + lua_pushstring(L, luaWebSocket->getUrl().c_str()); + return 1; + } + + int WebSocket_setUrl(lua_State* L) + { + LuaWebSocket* luaWebSocket = luaW_check(L, 1); + const char* url = luaL_checkstring(L, 2); + luaWebSocket->setUrl(url); + return 0; + } + + int WebSocket_start(lua_State* L) + { + LuaWebSocket* luaWebSocket = luaW_check(L, 1); + luaWebSocket->start(); + return 0; + } + + int WebSocket_send(lua_State* L) + { + LuaWebSocket* luaWebSocket = luaW_check(L, 1); + const char* msg = luaL_checkstring(L, 2); + luaWebSocket->send(msg); + return 0; + } + + int WebSocket_getMessage(lua_State* L) + { + LuaWebSocket* luaWebSocket = luaW_check(L, 1); + lua_pushstring(L, luaWebSocket->getMessage().c_str()); + return 1; + } + + int WebSocket_hasMessage(lua_State* L) + { + LuaWebSocket* luaWebSocket = luaW_check(L, 1); + lua_pushboolean(L, luaWebSocket->hasMessage()); + return 1; + } + + int WebSocket_popMessage(lua_State* L) + { + LuaWebSocket* luaWebSocket = luaW_check(L, 1); + luaWebSocket->popMessage(); + return 1; + } + + // This should be a static method + int WebSocket_sleep(lua_State* L) + { + LuaWebSocket* luaWebSocket = luaW_check(L, 1); + int duration = luaL_checkinteger(L, 2); + std::this_thread::sleep_for(std::chrono::milliseconds(duration)); + return 0; + } + + static luaL_Reg WebSocket_table[] = { + { NULL, NULL } + }; + + static luaL_Reg WebSocket_metatable[] = { + { "getUrl", WebSocket_getUrl }, + { "setUrl", WebSocket_setUrl }, + { "start", WebSocket_start }, + { "send", WebSocket_send }, + { "getMessage", WebSocket_getMessage }, + { "hasMessage", WebSocket_hasMessage }, + { "popMessage", WebSocket_popMessage }, + { "sleep", WebSocket_sleep }, + { NULL, NULL } + }; + + int luaopen_WebSocket(lua_State* L) + { + luaW_register(L, + "WebSocket", + WebSocket_table, + WebSocket_metatable, + WebSocket_new + ); + return 1; + } } diff --git a/luarocks/ia.lua b/luarocks/ia.lua index 1d667047..29d190b9 100644 --- a/luarocks/ia.lua +++ b/luarocks/ia.lua @@ -1,13 +1,28 @@ -webSocket = WebSocket.new() +-- +-- make luarocks && (cd luarocks ; ../build/luarocks/luarocks) +-- +local webSocket = WebSocket.new() webSocket:setUrl("ws://localhost:8008") print("Url: " .. webSocket:getUrl()) +-- Start the background thread webSocket:start() +local i = 0 + while true do - print("Waiting ...") - webSocket:send("coucou"); + print("Sending message...") + webSocket:send("msg_" .. tostring(i)); + i = i + 1 + + print("Waiting 1s...") webSocket:sleep(1000) + + if webSocket:hasMessage() then + local msg = webSocket:getMessage() + print("Received: " .. msg) + webSocket:popMessage() + end end diff --git a/luarocks/main.cpp b/luarocks/main.cpp index e4a800dc..25420f34 100644 --- a/luarocks/main.cpp +++ b/luarocks/main.cpp @@ -1,10 +1,16 @@ +/* + * main.cpp + * Author: Benjamin Sergeant + * Copyright (c) 2020 Machine Zone, Inc. All rights reserved. + */ + #include extern "C" { -#include "lua.h" -#include "lualib.h" -#include "lauxlib.h" + #include "lua.h" + #include "lualib.h" + #include "lauxlib.h" } #include "functions.hpp" @@ -20,29 +26,39 @@ int main() lua_register(L, "info", lua_info); // Objets - luaopen_WebSocket(L); + ix::luaopen_WebSocket(L); -#if 0 - luaL_dofile(L, "ia.lua"); -#else - int loadStatus = luaL_loadfile(L, "ia.lua"); + // + // Simple version does little error handling + // luaL_dofile(L, "ia.lua"); + // + std::string luaFile("ia.lua"); + int loadStatus = luaL_loadfile(L, luaFile.c_str()); if (loadStatus) { - std::cerr << "Error loading gof_server.lua" << std::endl; + std::cerr << "Error loading " << luaFile << std::endl; std::cerr << lua_tostring(L, -1) << std::endl; return 1; } else { - std::cout << "loaded ia.lua" << std::endl; + std::cout << "loaded " << luaFile << std::endl; } - try { + // + // Capture lua errors + // + try + { lua_call(L, 0, 0); + lua_close(L); } - catch (const std::runtime_error& ex) { + catch (const std::runtime_error& ex) + { + lua_close(L); std::cerr << ex.what() << std::endl; + return 1; } -#endif - lua_close(L); + + return 0; }