1
0
mirror of https://github.com/lammertb/libhttp.git synced 2025-08-16 11:21:57 +03:00

Rewrite websocket for Lua (Step 9 of ?)

This commit is contained in:
bel
2014-05-24 00:14:37 +02:00
parent 6e8415d4e5
commit ab3bc563cd
2 changed files with 45 additions and 27 deletions

View File

@@ -1013,6 +1013,7 @@ static void websock_cry(struct mg_connection *conn, int err, lua_State * L, cons
static void * lua_websocket_new(const char * script, struct mg_connection *conn) static void * lua_websocket_new(const char * script, struct mg_connection *conn)
{ {
struct mg_shared_lua_websocket_list **shared_websock_list = &(conn->ctx->shared_lua_websockets); struct mg_shared_lua_websocket_list **shared_websock_list = &(conn->ctx->shared_lua_websockets);
struct lua_websock_data *ws;
int err, ok = 0; int err, ok = 0;
assert(conn->lua_websocket_state == NULL); assert(conn->lua_websocket_state == NULL);
@@ -1035,46 +1036,54 @@ static void * lua_websocket_new(const char * script, struct mg_connection *conn)
return NULL; return NULL;
} }
/* init ws list element */ /* init ws list element */
(*shared_websock_list)->ws.script = mg_strdup(script); /* TODO: handle OOM */ ws = &(*shared_websock_list)->ws;
pthread_mutex_init(&((*shared_websock_list)->ws.ws_mutex), NULL); ws->script = mg_strdup(script); /* TODO: handle OOM */
(*shared_websock_list)->ws.state = lua_newstate(lua_allocator, NULL); pthread_mutex_init(&(ws->ws_mutex), NULL);
(*shared_websock_list)->ws.conn[0] = conn; ws->state = lua_newstate(lua_allocator, NULL);
(*shared_websock_list)->ws.references = 1; ws->conn[0] = conn;
(void)pthread_mutex_lock(&((*shared_websock_list)->ws.ws_mutex)); ws->references = 1;
prepare_lua_environment(conn->ctx, NULL, &((*shared_websock_list)->ws), (*shared_websock_list)->ws.state, script, LUA_ENV_TYPE_LUA_WEBSOCKET); (void)pthread_mutex_lock(&(ws->ws_mutex));
err = luaL_loadfile((*shared_websock_list)->ws.state, script); prepare_lua_environment(conn->ctx, NULL, ws, ws->state, script, LUA_ENV_TYPE_LUA_WEBSOCKET);
err = luaL_loadfile(ws->state, script);
if (err != 0) { if (err != 0) {
websock_cry(conn, err, (*shared_websock_list)->ws.state, script, "load"); websock_cry(conn, err, ws->state, script, "load");
} }
err = lua_pcall((*shared_websock_list)->ws.state, 0, 0, 0); err = lua_pcall(ws->state, 0, 0, 0);
if (err != 0) { if (err != 0) {
websock_cry(conn, err, (*shared_websock_list)->ws.state, script, "init"); websock_cry(conn, err, ws->state, script, "init");
} }
} else { } else {
/* inc ref count */ /* inc ref count */
(void)pthread_mutex_lock(&((*shared_websock_list)->ws.ws_mutex)); ws = &(*shared_websock_list)->ws;
(*shared_websock_list)->ws.conn[((*shared_websock_list)->ws.references)++] = conn; (void)pthread_mutex_lock(&(ws->ws_mutex));
(*shared_websock_list)->ws.conn[(ws->references)++] = conn;
} }
(void)pthread_mutex_unlock(&conn->ctx->nonce_mutex); (void)pthread_mutex_unlock(&conn->ctx->nonce_mutex);
/* call add */ /* call add */
lua_getglobal((*shared_websock_list)->ws.state, "open"); lua_getglobal(ws->state, "open");
err = lua_pcall((*shared_websock_list)->ws.state, 0, 1, 0); lua_newtable(ws->state);
prepare_lua_request_info(conn, ws->state);
lua_pushstring(ws->state, "client");
lua_pushlightuserdata(ws->state, (void *)conn);
lua_rawset(ws->state, -3);
err = lua_pcall(ws->state, 1, 1, 0);
if (err != 0) { if (err != 0) {
websock_cry(conn, err, (*shared_websock_list)->ws.state, script, "open handler"); websock_cry(conn, err, ws->state, script, "open handler");
} else { } else {
if (lua_isboolean((*shared_websock_list)->ws.state, -1)) { if (lua_isboolean(ws->state, -1)) {
ok = lua_toboolean((*shared_websock_list)->ws.state, -1); ok = lua_toboolean(ws->state, -1);
} }
lua_pop((*shared_websock_list)->ws.state, 1); lua_pop(ws->state, 1);
} }
if (!ok) { if (!ok) {
/* TODO */ /* TODO */
} }
(void)pthread_mutex_unlock(&((*shared_websock_list)->ws.ws_mutex)); (void)pthread_mutex_unlock(&(ws->ws_mutex));
return (void*)&((*shared_websock_list)->ws); return (void*)ws;
} }
static int lua_websocket_data(struct mg_connection * conn, void *ws_arg, int bits, char *data, size_t data_len) static int lua_websocket_data(struct mg_connection * conn, void *ws_arg, int bits, char *data, size_t data_len)
@@ -1125,7 +1134,6 @@ static int lua_websocket_ready(struct mg_connection * conn, void * ws_arg)
lua_getglobal(ws->state, "ready"); lua_getglobal(ws->state, "ready");
lua_newtable(ws->state); lua_newtable(ws->state);
prepare_lua_request_info(conn, ws->state);
lua_pushstring(ws->state, "client"); lua_pushstring(ws->state, "client");
lua_pushlightuserdata(ws->state, (void *)conn); lua_pushlightuserdata(ws->state, (void *)conn);
lua_rawset(ws->state, -3); lua_rawset(ws->state, -3);

View File

@@ -41,16 +41,25 @@ function ser(val)
return t return t
end end
-- table of all active connection
allConnections = {}
-- function to get a client identification string
function who(tab)
local ri = allConnections[tab.client]
return ri.remote_addr .. ":" .. ri.remote_port
end
-- Callback to reject a connection -- Callback to reject a connection
function open() function open(tab)
trace("open") allConnections[tab.client] = tab.request_info
trace("open[" .. who(tab) .. "]: " .. ser(tab))
return true return true
end end
-- Callback for "Websocket ready" -- Callback for "Websocket ready"
function ready(tab) function ready(tab)
trace("ready: " .. ser(tab)) trace("ready[" .. who(tab) .. "]: " .. ser(tab))
mg.write("text", "Websocket ready") mg.write("text", "Websocket ready")
senddata() senddata()
return true return true
@@ -58,15 +67,16 @@ end
-- Callback for "Websocket received data" -- Callback for "Websocket received data"
function data(tab) function data(tab)
trace("data: " .. ser(tab)) trace("data[" .. who(tab) .. "]: " .. ser(tab))
senddata() senddata()
return true return true
end end
-- Callback for "Websocket is closing" -- Callback for "Websocket is closing"
function close(tab) function close(tab)
trace("close: " .. ser(tab)) trace("close[" .. who(tab) .. "]: " .. ser(tab))
mg.write("text", "end") mg.write("text", "end")
allConnections[tab.client] = nil
end end
function senddata() function senddata()