qooxdoo / qooxdoo

qooxdoo - Universal JavaScript Framework
http://qooxdoo.org
Other
764 stars 259 forks source link

qx.io.transport Websocket.js bug? #10652

Closed uli99 closed 3 months ago

uli99 commented 3 months ago

Hi, when using websockets via qx.io.transport, I can only once use the websocket to transmit data, after that nothing happens (arrives at the server)

After some investigation, I looked at the Websocket.js file and found this in line 52 which is odd:

if (!ws.readyState !== WebSocket.OPEN) {

after removing the "!" at the beginning everything worked as expected.

I'm using qoxdoo 7.5.1

My application file looks like this:

/* ************************************************************************

   Copyright: 2024 undefined

   License: MIT license

   Authors: undefined

************************************************************************ */

/**
 * This is the main application class of "EAG_GUI"
 *
 * @asset(EAG_GUI/*)
 */
qx.Class.define("EAG_GUI.Application",
{
  extend : qx.application.Standalone,

  /*
  *****************************************************************************
     MEMBERS
  *****************************************************************************
  */

  members :
  {
    /**
     * This method contains the initial application code and gets called
     * during startup of the application
     *
     * @lint ignoreDeprecated(alert)
     */

    main()
    {
      // Call super class
      super.main();

      // Enable logging in debug variant
      if (qx.core.Environment.get("qx.debug"))
      {
        // support native logging capabilities, e.g. Firebug for Firefox
        qx.log.appender.Native;
        // support additional cross-browser console. Press F7 to toggle visibility
        qx.log.appender.Console;
      }

      /*
      -------------------------------------------------------------------------
        Below is your actual application code...
      -------------------------------------------------------------------------
      */

      // var myWebSocketClient = new EAG_GUI.WebSocketEAG2024("ws://${window.location.hostname}:8765/");
      var myWebSocketClient = new EAG_GUI.WebSocketEAG2024("ws://localhost:8765");

      // Create a button
      const button1 = new qx.ui.form.Button("Click me", "EAG_GUI/test.png");
      const button2 = new qx.ui.form.Button("Send websocket message", "EAG_GUI/test.png");

      // Document is the application root
      const doc = this.getRoot();

      // Add button to document at fixed coordinates
      doc.add(button1, {left: 100, top: 50});
      doc.add(button2, {left: 100, top: 100});

      // Add an event listener
      button1.addListener("execute", function() {
        /* eslint no-alert: "off" */
        alert("Hello World!");
      });

      button2.addListener("execute", function() {
        /* eslint no-alert: "off" */
        console.log('You have clicked, sending stuff via websocket...');
        myWebSocketClient.sendMessage("hi from qooxdoo2!")
      });
    }
  }
});

The WebSocketEAG2024 class looks like this

qx.Class.define("EAG_GUI.WebSocketEAG2024", {
    extend: qx.core.Object,

    construct: function(url) {
        this.base(arguments);

        qx.log.appender.Console.show();    // show qooxdoo debug-console
        this.info("websocket class initiated");

        this._socket = new qx.io.transport.Websocket(url);

        // this._socket.addListener("open", this._onOpen, this);
        // this._socket.addListener("close", this._onClose, this);
        // this._socket.addListener("error", this._onError, this);
        this._socket.addListener("message", this._onMessage, this);
    },

    members: {
        _socket: null,

        _onMessage: function(e) {
            var msg = e.getData();
            console.log("Message received:", msg);
        },

        sendMessage: function(message) {
                this._socket.send(message);
                console.log("sendMessage() called with '" + message + "'");
        }
    }
});

I used a python websocket server like this to check messages:

#!/usr/bin/env python3

import asyncio
from websockets.server import serve

async def echo(websocket):
    async for message in websocket:
        print("server received: '"+message+"'")
        await websocket.send("server received: '"+message+"'")

async def main():
    async with serve(echo, "localhost", 8765):
        await asyncio.Future()  # run forever

asyncio.run(main())

The browser used is Firefox 121.0.1 (64-bit) on linux

Uli

cboulanger commented 3 months ago

Hi, thanks for spotting this.

goldim commented 3 months ago

I didn't even know qooxdoo has wrapper for web sockets :) Unfortunately nobody uses it otherwise the error would be easily spotted.

cboulanger commented 3 months ago

Yes, I assume everyone uses different libraries for that. In the qx.io.transport.* namespace this is only a placeholder/proof of concept implementing the local API - it has never been used in one of the qooxdoo apps. But great to see that it finds its use.

cboulanger commented 3 months ago

https://github.com/qooxdoo/qooxdoo/tree/master/source/class/qx/io/transport contains a number of transports which all implement a very simple interface, on the basis of which higher-level API such as the one implementing JSON-RPC can be built transport-agnostically.