This forum uses cookies
This forum makes use of cookies to store your login information if you are registered, and your last visit if you are not. Cookies are small text documents stored on your computer; the cookies set by this forum can only be used on this website and pose no security risk. Cookies on this forum also track the specific topics you have read and when you last read them. Please confirm that you accept these cookies being set.

Socket.io server on .lp file
#1
Hi,

is there a possibility to use socket.io in .lp file to create realtime and simple connection with client without a http requests?
Done is better than perfect
Reply
#2
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-m...xsockettcp
Reply
#3
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?
Done is better than perfect
Reply
#4
.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.
Reply
#5
Thanks admin, it is helpful. What is the websocket server path in this example (I must type it on client script)?
Done is better than perfect
Reply
#6
As for any other .lp, just replace http:// with ws://
Reply
#7
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?
Done is better than perfect
Reply
#8
Why two websockets? There's one localbus socket which is local UDP broadcast, another one is server-client TCP connection.
Reply
#9
(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()
Done is better than perfect
Reply
#10
You don't need a separate port, websockets is just an extension over standard http requests.
Reply
#11
Thank you very much for your admin for help, I will test it.
Done is better than perfect
Reply


Forum Jump: