Logic Machine Forum
Socket.io server on .lp file - Printable Version

+- Logic Machine Forum (https://forum.logicmachine.net)
+-- Forum: LogicMachine eco-system (https://forum.logicmachine.net/forumdisplay.php?fid=1)
+--- Forum: Scripting (https://forum.logicmachine.net/forumdisplay.php?fid=8)
+--- Thread: Socket.io server on .lp file (/showthread.php?tid=1796)



Socket.io server on .lp file - buuuudzik - 18.12.2018

Hi,

is there a possibility to use socket.io in .lp file to create realtime and simple connection with client without a http requests?


RE: Socket.io server on .lp file - admin - 18.12.2018

Please explain your taks a bit more. Anyway, LuaSocket should never be used in .lp because it will block the whole webserver during i/o operations. You should use these functions instead: https://github.com/openresty/lua-nginx-module#ngxsockettcp


RE: Socket.io server on .lp file - buuuudzik - 18.12.2018

Recently I've created a nodejs app for realtime controlling inverter in one project. It had a client and a server and all data was exchanged via websockets in two directions. Thanks to websocket it was possible because like in LM with localbus. But in this project I've noticed that this technology could simplify and improve also other communication between client and server what's normally is done by http requests and exchanging data in JSON file.

I think websockets would be useful in .lp files for:
- every client show up-to-date app state (server sends every change in config to all clients without need to refresh page by client). This also removes the need for polling some data.
- server could send something to connected clients.
- generally I think that such possiblity could help to create better and more advanced apps to LM



Another question I have:
- could you replace jQuery need from localbus?


RE: Socket.io server on .lp file - admin - 18.12.2018

.lp can already work as WebSocket server. Here's a short example:
Code:
<?

local json = require('json')
local ws, err = require('ngx.ws'):new({ timeout = 10 * 1000 })

-- websocket init error
if not ws then
  write('websocket init failed: ', tostring(err))
  return
end

request.raw = true
local lb = require('localbus')

local function lbthread(ws)
  local client = lb.new()
  local run = true

  -- telegram event
  local function groupcallback(event)
    event.tsec, event.tusec = os.microtime()
    local data = json.encode(event)
    if not ws:send_text(data) then
      run = false
    end
  end

  -- set callbacks
  client:sethandler('groupwrite', groupcallback)
  client:sethandler('groupresponse', groupcallback)

  while run do
    client:step()
  end
end

local function datacallback(data)
  -- ignore ping messages
  if data == 'ping' then
    return
  end

  data = json.pdecode(data)
end

local co = ngx.thread.spawn(lbthread, ws)

repeat
  local data, typ, err = ws:recv_frame()

  if typ == 'text' then
    datacallback(data)
  end
until ws.fatal or typ == 'close' or ngx.worker.exiting()

ngx.thread.kill(co)
if not ws.fatal then
  ws:send_close()
end

jQuery is required for localbus, but only $.ajax, $.param and $.each functions are used. I suppose you can provide your own compatibility layer if using any other JS library.


RE: Socket.io server on .lp file - buuuudzik - 18.12.2018

Thanks admin, it is helpful. What is the websocket server path in this example (I must type it on client script)?


RE: Socket.io server on .lp file - admin - 18.12.2018

As for any other .lp, just replace http:// with ws://


RE: Socket.io server on .lp file - buuuudzik - 18.12.2018

I try understand this and not only do this. So if in .lp file there would be 2 websockets defined then they would using same address?


RE: Socket.io server on .lp file - admin - 18.12.2018

Why two websockets? There's one localbus socket which is local UDP broadcast, another one is server-client TCP connection.


RE: Socket.io server on .lp file - buuuudzik - 18.12.2018

(18.12.2018, 16:57)admin Wrote: Why two websockets? There's one localbus socket which is local UDP broadcast, another one is server-client TCP connection.

This was only theoretically question. I don't understand where in attached code there is the websocket assignment to some port. Because in a few examples which I read always there was some address + port 8080 (probably default for websocket);

Like below:

Code:
local ev = require'ev'

-- create a copas webserver and start listening
local server = require'websocket'.server.ev.listen
{
 -- listen on port 8080
 port = 8080,
 -- the protocols field holds
 --   key: protocol name
 --   value: callback on new connection
 protocols = {
   -- this callback is called, whenever a new client connects.
   -- ws is a new websocket instance
   echo = function(ws)
     ws:on_message(function(ws,message)
         ws:send(message)
       end)

     -- this is optional
     ws:on_close(function()
         ws:close()
       end)
   end
 }
}

-- use the lua-ev loop
ev.Loop.default:loop()



RE: Socket.io server on .lp file - admin - 18.12.2018

You don't need a separate port, websockets is just an extension over standard http requests.


RE: Socket.io server on .lp file - buuuudzik - 18.12.2018

Thank you very much for your admin for help, I will test it.