【问题标题】:Pushing data to websocket browser client in Lua将数据推送到 Lua 中的 websocket 浏览器客户端
【发布时间】:2020-01-14 07:13:17
【问题描述】:

我想使用 NodeMCU 设备(基于 Lua 的顶级设备)充当 1 个或多个浏览器客户端的 websocket 服务器。

幸运的是,这里有执行此操作的代码:NodeMCU Websocket Server (由@creationix 和/或@moononournation 提供)

这如描述的那样工作,我能够从客户端向 NodeMCU 服务器发送一条消息,然后它会根据收到的消息做出响应。太好了。

我的问题是:

  1. 如何向客户端发送消息,而不必将其作为对客户端请求的响应(独立发送数据)?当我尝试调用 socket.send() 时,未找到作为变量的套接字,我明白,但不知道该怎么做! :(
  2. 为什么 decode() 函数会输出 extra 变量?这是干什么用的?我假设它会导致数据包溢出,但无论我的消息长度如何,我似乎永远无法让它返回任何内容。
  3. 在listen方法中,作者为什么要添加排队系统?这是必不可少的还是对于可能同时接收多个消息的应用程序?理想情况下,我想删除它。

我将代码简化如下:

(不包括 decode()encode() 函数 - 请参阅上面的链接以获取完整脚本)

net.createServer(net.TCP):listen(80, function(conn)

  local buffer = false
  local socket = {}
  local queue = {}
  local waiting = false

  local function onSend()
    if queue[1] then
      local data = table.remove(queue, 1)
      return conn:send(data, onSend)
    end
    waiting = false
  end

  function socket.send(...)
    local data = encode(...)
    if not waiting then
      waiting = true
      conn:send(data, onSend)
    else
      queue[#queue + 1] = data
    end
  end

  conn:on("receive", function(_, chunk)

    if buffer then
      buffer = buffer .. chunk
      while true do
        local extra, payload, opcode = decode(buffer)

        if opcode==8 then
          print("Websocket client disconnected")
        end

        --print(type(extra), payload, opcode)
        if not extra then return end
        buffer = extra
        socket.onmessage(payload, opcode)
      end
    end

    local _, e, method = string.find(chunk, "([A-Z]+) /[^\r]* HTTP/%d%.%d\r\n")
    local key, name, value

    for name, value in string.gmatch(chunk, "([^ ]+): *([^\r]+)\r\n") do
      if string.lower(name) == "sec-websocket-key" then
        key = value
        break
      end
    end

    if method == "GET" and key then

      acceptkey=crypto.toBase64(crypto.hash("sha1", key.."258EAFA5-E914-47DA-95CA-C5AB0DC85B11"))

      conn:send(
        "HTTP/1.1 101 Switching Protocols\r\n"..
        "Upgrade: websocket\r\nConnection: Upgrade\r\n"..
        "Sec-WebSocket-Accept: "..acceptkey.."\r\n\r\n",
        function () 

          print("New websocket client connected")

          function socket.onmessage(payload,opcode)
            socket.send("GOT YOUR DATA", 1)
            print("PAYLOAD = "..payload)
            --print("OPCODE = "..opcode)
          end

        end)
      buffer = ""
    else
      conn:send(
        "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nContent-Length: 12\r\n\r\nHello World!",
        conn.close)
    end

  end)
end)

【问题讨论】:

    标签: websocket server lua client nodemcu


    【解决方案1】:

    我只能回答 1 个问题,其他问题可能更适合图书馆作者。此外,SO 是一种您通常会问 1 个问题的格式。

    如何向客户端发送消息,而不必将其作为对客户端请求的响应(独立发送数据)?

    你不能。如果没有客户端首先联系服务器并建立套接字连接,服务器将不知道将消息发送到哪里。即使使用 SSE (server-sent events),它也是客户端首先发起与服务器的连接。

    【讨论】:

    • 我并不是建议我在 建立 websocket 连接之前发送服务器-客户端消息。我需要一个关于如何使用上面的代码发送服务器-客户端消息的答案,一个 websocket 连接已经建立。例如,每 30 秒调用一次socket.send(),并使用发送给客户端的文本字符串。也许是因为socket={}listen 方法的本地?
    猜你喜欢
    • 2014-05-05
    • 2014-05-16
    • 1970-01-01
    • 1970-01-01
    • 2017-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多