fengari-lua / fengari-web

Provides everything you need to run Fengari in the browser.
MIT License
250 stars 19 forks source link

TypeError: Constructor WebSocket requires 'new' #42

Closed RussellHaley closed 5 years ago

RussellHaley commented 5 years ago

Hi, I'm converting a javascript file that opens a websocket client over to fengari. I don't know how to instantiate a new WebSocket: original: webSocket = new WebSocket(webSocketURL);

Fengari: webSocket = WebSocket(webSocketURL) Which creates the error: "TypeError: Constructor WebSocket requires 'new'"

I've also tried WebSocket:new(...) and WebSocket.new(...)

Hints? Thanks, Russ

giann commented 5 years ago

Try js.new(WebSocket)

RussellHaley commented 5 years ago

Thank you!

In the onmessage handler, the expected messageEvent.data field is nil. I seem to be getting my WebSocket object instead of a MessageEvent object. Any thoughts?

webSocket.onmessage = function (messageEvent)
        if messageEvent then
            console:log(messageEvent) --This displays my websocket object instead of a MessageEvent
            local wsMsg = messageEvent.data  --messageEvent.data is nil
            console:log("WebSocket MESSAGE: " .. wsMsg) --This causes a concat with nil error
            local output = document:getElementById("incomingMsgOutput")
            if (wsMsg.indexOf("error") > 0) then            
                output.value = output.value .. "error: " .. wsMsg.error .. "\r\n"
            else
                output.value = output.value .. "message: " .. wsMsg .. "\r\n"
            end
        else
            console:log("messageEvent was nil")
        end
    end

My complete script is here:

local js = require "js"
local window = js.global
local console = js.global.console
local document = window.document
local WebSocket = js.global.WebSocket
local JSON = js.global.JSON
local webSocket   = null
local ws_protocol = null
local ws_hostname = null
local ws_port     = null
local ws_endpoint = null

--~ /**
--~ * Event handler for clicking on button "Connect"
--~ */
function onConnectClick() 

    console:log("Totally got here!")
    local ws_protocol = document:getElementById("protocol").value
    local ws_hostname = document:getElementById("hostname").value
    local ws_port     = document:getElementById("port").value
    local ws_endpoint = document:getElementById("endpoint").value
    openWSConnection(ws_protocol, ws_hostname, ws_port, ws_endpoint)
end
--~ /**
--~ * Event handler for clicking on button "Disconnect"
--~ */
function onDisconnectClick() 
    webSocket:close()
end
--~ /**
--~ * Open a new WebSocket connection using the given parameters
--~ */
function openWSConnection(protocol, hostname, port, endpoint)
    local webSocketURL = null
    --~ webSocketURL = protocol .. "://" .. hostname .. ":" .. port .. endpoint
    webSocketURL = "wss://echo.websocket.org"
    console:log("openWSConnection - Connecting to: " .. JSON:stringify(webSocketURL))
    --~ try {
    --~ webSocket = new WebSocket(webSocketURL);
    webSocket = js.new(WebSocket, webSocketURL)
    --~ webSocket.url = webSocketURL
    webSocket.onopen = function(openEvent) 
        console:log("WebSocket OPEN: " .. JSON:stringify(openEvent, null, 4))
        document:getElementById("btnSend").disabled       = false
        document:getElementById("btnConnect").disabled    = true
        document:getElementById("btnDisconnect").disabled = false
    end
    webSocket.onclose = function (closeEvent) 
        console:log("WebSocket CLOSE: " + JSON:stringify(closeEvent, null, 4))
        document:getElementById("btnSend").disabled       = true
        document:getElementById("btnConnect").disabled    = false
        document:getElementById("btnDisconnect").disabled = true
    end
    webSocket.onerror = function (errorEvent) 
        console:log("WebSocket ERROR: " + JSON:stringify(errorEvent, null, 4))
    end
    webSocket.onmessage = function (messageEvent)
        if messageEvent then
            console:log(messageEvent)
            local wsMsg = messageEvent.data
            console:log("WebSocket MESSAGE: " .. wsMsg)
            local output = document:getElementById("incomingMsgOutput")
            if (wsMsg.indexOf("error") > 0) then            
                output.value = output.value .. "error: " .. wsMsg.error .. "\r\n"
            else
                output.value = output.value .. "message: " .. wsMsg .. "\r\n"
            end
        else
            console:log("messageEvent was nil")
        end
    end
    --~ } catch (exception) {
    --~ console.error(exception)
    --~ }
end
--~ /**
--~ * Send a message to the WebSocket server
--~ */
function onSendClick() 
    if (webSocket.readyState ~= WebSocket.OPEN) then
        console.error("webSocket is not open: " + webSocket.readyState)
    return
    end
    local msg = document:getElementById("message").value
    local out = "{'cmd':"..msg.."}"
    webSocket:send(JSON:stringify(out))
end

local btnConnect = document:getElementById('btnConnect')
   btnConnect.onclick=onConnectClick
local btnSend = document:getElementById('btnSend')
    btnSend.onclick=onSendClick
<!DOCTYPE html>
<html>
    <head>
    <meta charset="UTF-8">
      <meta http-equiv="Content-Security-Policy"  content="connect-src * 'unsafe-inline';">

    <script src="javascript/fengari-web.js"></script>
<!--
    <script src="wsclient.js"></script>
-->
    <script type="application/lua">
    print("hello world!")
    </script>

    <script src="lua/my-script.lua" type="application/lua" async></script>
    <script src="lua/wsclient.lua" type="application/lua" async></script>

    <style>
        table    { border: 2px solid black; }
        input    { width: 300px; }
        select   { width: 300px; }
        textarea { width: 513px; border: 2px solid black; }
        #btnConnect    { width: 100px; }
        #btnDisconnect { width: 100px; }
        #btnSend       { width: 100px; }
    </style>
    </head>
    <body>
    <h1>WebSocket Client</h1>
    <!-- WebSocket Connection Parameters Table -->
    <table>
        <tr>
        <td width="200px">WS Protocol</td>
        <td>
            <select id="protocol">
            <option value="ws" selected="selected">ws</option>
            <option value="wss">wss</option>
            </select>
        </td>
        </tr>
        <tr>
        <td>WS Hostname</td>
        <td><input type="text" id="hostname" value="localhost"/></td>
        </tr>
        <tr>
        <td>WS Port</td>
        <td><input type="text" id="port" value="8086"/></td>
        </tr>
        <tr>
        <td>WS Endpoint</td>
        <td><input type="text" id="endpoint"/></td> 
        <td><input type="text" id="ep_message"/></td>
        </tr>
        <tr>
        <td></td>
        <td>
<!--
            <input id="btnConnect"    type="button" value="Connect"    onclick="onConnectClick()">&nbsp;&nbsp;
-->
            <input id="btnConnect"    type="button" value="Connect" >&nbsp;&nbsp;
            <input id="btnDisconnect" type="button" value="Disconnect" onclick="onDisconnectClick()" disabled="disabled">
        </td>
        </tr>
    </table><br/>
    <!-- Send Message Table -->
    <table>
        <tr>
        <td width="200px">Message</td>
        <td><input type="text" id="message"/></td>
        </tr>
        <tr>
        <td></td>
        <td>
            <input id="btnSend" type="button" value="Send Message" disabled="disabled">
        </td>
        </tr>
    </table><br/>
    <textarea id="incomingMsgOutput" rows="10" cols="20" ></textarea>
    </body>
</html>

Console output

Totally got here! 
openWSConnection - Connecting to: "wss://echo.websocket.org" 
WebSocket OPEN: {} 
WebSocket { url: "wss://echo.websocket.org/", readyState: 1, bufferedAmount: 0, onopen: n(), onerror: n(), onclose: n(), extensions: "", protocol: "", onmessage: n()
, binaryType: "blob" }

uncaught exception: http://192.168.1.174:8099/lua/wsclient.lua:66: attempt to concatenate a nil value (local 'wsMsg')
daurnimator commented 5 years ago
webSocket.onmessage = function (messageEvent)

You probably meant:

webSocket.onmessage = function (this, messageEvent)

or

function webSocket:onmessage(messageEvent)
RussellHaley commented 5 years ago

Brilliant. Thanks so much.