airsdk / Adobe-Runtime-Support

Report, track and discuss issues in Adobe AIR. Monitored by Adobe - and HARMAN - and maintained by the AIR community.
206 stars 11 forks source link

No solution for client websocket desktop air app, please help! #3274

Open JoseEstevesPt opened 6 months ago

JoseEstevesPt commented 6 months ago

I'm using Adobe Animate 24.0.3 and Air SDK 50.2.4.4, creating a desktop app that connects do websockets (websockt or websocket IO) server, I've tried all the old libraries, help of chat GPT, help of Copilot, nothing works. Then I saw this post...How can I get AIR SDK 51? will I be able to solve my problem. Please help!

Discussed in https://github.com/airsdk/Adobe-Runtime-Support/discussions/3081

Originally posted by **ajwfrost** February 23, 2024 Hi all. Finally, we are releasing a new major version of the AIR SDK - the major version update is because of a number of new ActionScript APIs and features that are being added, which means the SWF version code will also be going up to 51 (fourth byte of the SWF = 0x33). This discussion thread is to provide information about the new features/APIs. Our intention is to create a new main comment for each of the features, and then we (or anyone) can reply on those comment threads, so that we keep each thread specifically about a particular feature. We can then use it to give examples, provide updates on the status (51.0 is released initially as a beta/pre-release, some features are not actually completed), and hopefully it still stay roughly organised. For full ActionScript API details, check out the "What's New" page of https://airsdk.dev/reference/actionscript/3.0/
ajwfrost commented 6 months ago

You can download AIR SDK 51 by selecting the version from https://airsdk.harman.com/release_notes (I just noticed we hadn't updated the 'default' SDK version from the downloads page..)

But if you wait 12 hours, we should have 51.0.1.2 available which fixes a number of issues and would be better to use..

thanks

JoseEstevesPt commented 6 months ago

thanks Andrew, meanwhile I discovered the air sdk manager and downloaded air sdk 51.0.1.1 but I'me still struggling and can't make the connection work. Where can I find a simple code example?

ajwfrost commented 6 months ago

Well it should be a fairly straightforward thing, but having just tried it here, we seem to have some issues with the client-side connection. It's one of those that worked when we tried it locally, but trying it again now and I've just noticed a couple of problems.

Sample code, if you're connecting from AIR to a websocket server elsewhere:

        private function testWebSocket() : void
        {
            // create a connection to the websocket echo server
            _ws = new WebSocket();
            _ws.addEventListener(Event.CONNECT, onConnected);
            _ws.addEventListener(WebSocketEvent.DATA, onData);
            _ws.addEventListener(IOErrorEvent.IO_ERROR, onError);
            trace("Connecting to web socket test echo server");
            _ws.connect("wss://echo.websocket.org/echo");
        }

        private function onConnected(e : Event) : void
        {
            // send a test message
            trace("Connected: sending a message");
            if (_ws) _ws.sendMessage(WebSocket.fmtTEXT, "This is a test message");
        }

        private function onData(e : WebSocketEvent) : void
        {
            trace("Received data from the message");
            var msg : String = e.stringData;
            trace(msg);
        }

        private function onError(e :IOErrorEvent) : void
        {
            trace("Error connecting to server: " + e.text);
        }

We've just been finding that sometimes, the secure socket connection doesn't work - which appears to be a garbage collection issue (we use an internal instance of a socket within the websocket implementation and the mechanism used to prevent this from being GCed seems to not be working?).

And also we've just noticed that the test server used above is sending responses with different capitalisations to the requests, which our earlier test server didn't do, and this has then exposed an issue in the code.

So .. it may well not connect properly... are you trying to connect to anything public that we can check against? or if you are able to find out what network packages (at least the http messages) are being sent/received, we can take a look at those to see where it's going wrong.

We'll get fixes out in the next release (well, 51.0.1.3, a few weeks away I'm afraid) to try to resolve these..

thanks

ajwfrost commented 6 months ago

Hi @JoseEstevesPt - can I check what operating system you're using to build/test this? We could share an update to try out perhaps?

JoseEstevesPt commented 6 months ago

Thanks once more, here is the code I’m using (yours of course), I’m using as a test server "wss://gr8events.tech/teste”, can’t connect getting one warning and one error.

Warning: Scene 1, Layer 'Layer_1', Frame 1, Line 28, Column 10 Warning: 1090: Migration issue: The onData event handler is not triggered automatically by Flash Player at run time in ActionScript 3.0. You must first register this handler for the event using addEventListener ( 'data', callback_handler).

Error: Connecting to web socket test echo server Error connecting to server: Error #2031: Socket Error. URL: gr8events.tech http://gr8events.tech/

I’m running Animate on macOS Sonoma version 14.5

import flash.events.Event; import flash.events.IOErrorEvent; import flash.events.SecurityErrorEvent; import flash.events.WebSocketEvent; import air.net.WebSocket;

var _ws:WebSocket _ws = new WebSocket(); _ws.addEventListener(Event.CONNECT, onConnected); _ws.addEventListener(WebSocketEvent.DATA, onData); _ws.addEventListener(IOErrorEvent.IO_ERROR, onError); trace("Connecting to web socket test echo server");

//_ws.connect("wss://echo.websocket.org/echo");

ws.connect("wss://gr8events.tech/teste");

function onConnected(e : Event) : void { // send a test message trace("Connected: sending a message"); if (_ws) _ws.sendMessage(WebSocket.fmtTEXT, "This is a test message"); }

function onData(e : WebSocketEvent) : void { trace("Received data from the message"); var msg : String = e.stringData; trace(msg); }

function onError(e :IOErrorEvent) : void { trace("Error connecting to server: " + e.text); }

On 31 May 2024, at 00:23, Andrew Frost @.***> wrote:

Well it should be a fairly straightforward thing, but having just tried it here, we seem to have some issues with the client-side connection. It's one of those that worked when we tried it locally, but trying it again now and I've just noticed a couple of problems.

Sample code, if you're connecting from AIR to a websocket server elsewhere:

  private function testWebSocket() : void
  {
      // create a connection to the websocket echo server
      _ws = new WebSocket();
      _ws.addEventListener(Event.CONNECT, onConnected);
      _ws.addEventListener(WebSocketEvent.DATA, onData);
      _ws.addEventListener(IOErrorEvent.IO_ERROR, onError);
      trace("Connecting to web socket test echo server");
      _ws.connect("wss://echo.websocket.org/echo");
  }

  private function onConnected(e : Event) : void
  {
      // send a test message
      trace("Connected: sending a message");
      if (_ws) _ws.sendMessage(WebSocket.fmtTEXT, "This is a test message");
  }

  private function onData(e : WebSocketEvent) : void
  {
      trace("Received data from the message");
      var msg : String = e.stringData;
      trace(msg);
  }

  private function onError(e :IOErrorEvent) : void
  {
      trace("Error connecting to server: " + e.text);
  }

We've just been finding that sometimes, the secure socket connection doesn't work - which appears to be a garbage collection issue (we use an internal instance of a socket within the websocket implementation and the mechanism used to prevent this from being GCed seems to not be working?).

And also we've just noticed that the test server used above is sending responses with different capitalisations to the requests, which our earlier test server didn't do, and this has then exposed an issue in the code.

So .. it may well not connect properly... are you trying to connect to anything public that we can check against? or if you are able to find out what network packages (at least the http messages) are being sent/received, we can take a look at those to see where it's going wrong.

We'll get fixes out in the next release (well, 51.0.1.3, a few weeks away I'm afraid) to try to resolve these..

thanks

— Reply to this email directly, view it on GitHub https://github.com/airsdk/Adobe-Runtime-Support/issues/3274#issuecomment-2140995050, or unsubscribe https://github.com/notifications/unsubscribe-auth/AE52QAECS5VQ6CJJYCUJO73ZE6YFVAVCNFSM6AAAAABIRTABJWVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDCNBQHE4TKMBVGA. You are receiving this because you authored the thread.

ajwfrost commented 6 months ago

Thanks

So .. with the changes we've just made here, we can connect to the echo service and send/receive messages now. But with your server, when we connect via a WebSocket, we get:

[OPENSSL] 0xe13a968 SSL_connect: Handshake failed(1)!

But, when we connect directly using a SecureSocket, the handshaking works.

We'll have to investigate that a little more! Your server looks fine from what we can tell from an SSL check, we're trying to use TLS v1.3 for the connection.. and it shouldn't really be the case that a SecureSocket works from client code but not when it's run from within the builtin code!

Will check on this and if we can get past these issues, will send you an update build to test!

thanks

JoseEstevesPt commented 6 months ago

Thanks Andrew an update build sounds great! To test if my server is ok, i'm using Postman and all works well with the connections. Hope to ear from you soon :)

ajwfrost commented 6 months ago

Okay, the handshaking works when it's actually a connection on port 443. There's an omission in our detection code for the default port number so this had been trying to connect on port 80!

There is then the same issue that we had in the echo service with our code being too strict (i.e. not properly reading the specification..). The earlier issue I thought was related to garbage collection was actually just because we were debugging and there was a timeout happening behind the scenes!

So - will get a test build prepared for you for macOS..

thanks

JoseEstevesPt commented 6 months ago

Thanks once more, good news.

ajwfrost commented 6 months ago

Hi - please use the below link and then unzip that over the top of AIR 51 (it's built on top of 51.0.1.2 but shouldn't matter which 51.0.x.x version is under it...). This should

https://transfer.harman.com/link/SYIfSjYLk7HDJbu6VuJ4u9

thanks

JoseEstevesPt commented 6 months ago

Andrew, thanks, you were really helpful. It seams to work now, later I will make more complex tests.

raresn commented 6 months ago

@JoseEstevesPt what are you using for the server? Thinking of implementing this in our app as well.

JoseEstevesPt commented 6 months ago

It's a linux web server, with node.js, express, ws, hope this was helpful.

JoseEstevesPt commented 6 months ago

Screenshot 2024-06-03 at 14 12 13 Screenshot 2024-06-03 at 14 25 29 Hello, some more issues...once more help needed. Everything runs fine in testing / development, but when I publish it to air, just won't install on a windows machine (yes I'm developing in mac but the production machine will be in windows). Tried to update AIR runtime to version version 50.2.4.1, with no success. I think the runtimes (51.0.1.1) you sent will only work on mac, correct? The project involves 2 apps (one air desktop windows and a second one running on android). My second problem is that due to missing files I can't compile to Android. Can you once more help? thank you in advance.

ajwfrost commented 6 months ago

For the first one -> we don't have an AIR shared runtime version 51.x yet. But will hopefully update that shortly!

For the second .. what's the SDK that you've got Animate pointed to? It seems strange for one of our SDKs to be missing that file, but strange for a non-Harman SDK to even be looking for it. So there may have been some issue with installation/deployment of the AIR SDK....?

If you have AIR SDK Manager open to the "Troubleshooting" tab, try building from Animate again, and see what the logs say..

JoseEstevesPt commented 6 months ago

Thanks for the fast reply. For the first issue, please define shortly, 1,2 days...or more?

For the second issue, I was able so solve the issue, and compile the APK, but it will not connect to the websocket, on the android tablet in production.

ajwfrost commented 6 months ago

Yes, one or two days should be about right - we had a slight issue with the macOS version that needs to be re-packaged..

If you've got issues with the Android connection: is that from the tablet, or to it? If the Android tablet is the client side then it may be challenging to sniff what's happening on the network (unless you are running the server?) but that would be my suggestion, so we can see the HTTP traffic and work out where the disconnection is coming. It may be best to try things in stages e.g. does it work on HTTP, before moving to HTTPS, and could you try the Android emulator before trying it on device, etc?

But I can also ask someone to try your test server from an Android handset here and see what happens...

JoseEstevesPt commented 6 months ago

I tried with two android tablets and could not connect, both can go online, and connect to webservices and download data, but can't connect to websocket server. I will wait for the next macOS version, and test it again.

ajwfrost commented 6 months ago

Ah - but yes I guess the updates that you need aren't in the Android runtimes yet... so I'd sent the macOS package but that only changed the macOS runtime, it didn't contain other updates.

What you'd need is the next 'full' release of AIR SDK with all the platforms updated.

The way things are going, that will be sooner rather than later - as soon as we've got a fix for the current arm64 JIT problems...

thanks

JoseEstevesPt commented 6 months ago

I think that will solve my problems... but now I have a time problem, next week i must have everything ready and working... will it happen?

ajwfrost commented 6 months ago

So the ideal scenario would probably be if we can find and fix the JIT thing in the next two days, then I'll trigger an update release to 51.0.1.3 with this stuff plus whatever other changes are in...

But to validate this websocket stuff, it would probably also be useful if I can send you an interim Android package that you can use to test it with! Otherwise we risk you finding a problem too last-minute to be able to change... I can kick that off fairly easily..

thanks

JoseEstevesPt commented 6 months ago

The interim Android package sounds just great, and I will be able to share any problems I encounter.

JoseEstevesPt commented 6 months ago

Thanks, later today I will test it.

JoseEstevesPt commented 6 months ago

hello, thanks for the files, just tried it...with no success, still can't connect to websocket on android. Works perfect on Mac, on Android on the debug I get Error #2031: Socket Error. URL: gr8events.tech

ajwfrost commented 5 months ago

FYI we seem to have a more fundamental issue with secure sockets on the latest Android versions. With some hacks, I can get the echo server to work, but I'm having to manually pass in a bunch of root certificates, ignoring an error code, and ignoring a CRL read failure. Will see if we can make this work a little better, we may need to have some other client-side workaround to avoid opening up some security holes in the short term...

thanks

JoseEstevesPt commented 5 months ago

I'm running out of time, can I expect a solution in short term? (2,3 days), will it work in non secure websocket? how can I help?

ajwfrost commented 5 months ago

It should work fine if it's not over a secure protocol ... something is up with SSL here, it won't be a particularly quick fix I'm afraid...

JoseEstevesPt commented 5 months ago

I've just tried using "ws://gr8events.tech:4117/" with no success, can connect with postman, with no problem. All works on mac, not on android...please help. We tested on a web server and on a local server.

ajwfrost commented 5 months ago

Can you double-check that port, I'm not getting any response when trying to connect a socket to 176.61.146.17:4117.. it retransmits after 1/2/4/8s and then gives up...

Transmission Control Protocol, Src Port: 54141, Dst Port: 4117, Seq: 0, Len: 0
    Source Port: 54141
    Destination Port: 4117
    [Stream index: 4]
    [Conversation completeness: Incomplete, SYN_SENT (1)]
    [TCP Segment Len: 0]
    Sequence Number: 0    (relative sequence number)
    Sequence Number (raw): 1763988296
    [Next Sequence Number: 1    (relative sequence number)]
    Acknowledgment Number: 0
    Acknowledgment number (raw): 0
    1000 .... = Header Length: 32 bytes (8)
    Flags: 0x002 (SYN)
    Window: 64240
    [Calculated window size: 64240]
    Checksum: 0x0422 [unverified]
    [Checksum Status: Unverified]
    Urgent Pointer: 0
    Options: (12 bytes), Maximum segment size, No-Operation (NOP), Window scale, No-Operation (NOP), No-Operation (NOP), SACK permitted
    [Timestamps]
JoseEstevesPt commented 5 months ago

I just tested again with postman and works "ws://gr8events.tech:4117", but testing with your code on my mac it only works if I use"ws://gr8events.tech:4117/", it need the extra slash. When I publish to android it will not work, will not conencto to the server.

JoseEstevesPt commented 5 months ago

GET / HTTP/1.1 Sec-WebSocket-Version: 13 Sec-WebSocket-Key: Eu7hFWF/6WXbxeA/mCzzQg== Connection: Upgrade Upgrade: websocket Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits Host: gr8events.tech:4117

HTTP/1.1 101 Switching Protocols Upgrade: websocket Connection: Upgrade Sec-WebSocket-Accept: KRMUfQsZ8KbKInqQfpOCQLTTrzE=

ajwfrost commented 5 months ago

Okay so something may be happening within our network to block that location/port.. The "extra slash" thing is a limitation here which we can resolve.

But are you saying that even with the updated Android runtime files, you can't connect to the non-secure version on port 4117?

Is that HTTP log from Postman? I assume so, we don't send the extensions method... plus on the "Host" line, we wouldn't be sending the port number. Maybe we should add that..

I think the quickest thing here may be to do a separate mechanism for Android via ANE in the short term, whilst we work on what's going wrong with the SSL connection... let me check how quickly we may be able to get that done.

thanks

JoseEstevesPt commented 5 months ago

There was a firewall issue from outside of Portugal, but all good now. And yes with the updated Android Ruttimes I can't coonect. It was the postman log. My time is running very short, need some kind of solution for this. Thanks for your help.

ajwfrost commented 5 months ago

Can I check your requirements here:

We can get you something for Monday or latest Tuesday, assuming you don't need the extra protocol handling. The questions just narrow down the scope for a "version 1" -> putting the Android capability into an ANE. Functionality-wise, it would be the same API (and derive from air.net.WebSocket) so it would just mean you need to change where your code creates the object initially, to use a different class name...

JoseEstevesPt commented 5 months ago

server side: https://www.npmjs.com/package/ws

server code: const WebSocket = require("ws"); const http = require("http"); const { v4: uuidv4 } = require("uuid");

// Create an HTTP server const server = http.createServer((req, res) => { res.writeHead(200, { "Content-Type": "text/plain" }); res.end("TESTE\n"); });

// Attach WebSocket server to the HTTP server const wss = new WebSocket.Server({ server });

// Armazenar clientes conectados e seus IDs const clients = new Map();

wss.on("connection", (ws) => { console.log("Client connected");

.....

// Start the server on port 4116 server.listen(4117,'0.0.0.0', () => { console.log("Server is listening on port 4117"); });

ajwfrost commented 5 months ago

Hi Can you please use the attached ANE file (zipped up here) - if you do:

 var ws : WebSocket = new AndroidWebSocket();

it should work the same way as the normal WebSocket class, but using an ANE.

AndroidWebSocketANE.zip

Note: this uses a third party library: https://github.com/TakahikoKawasaki/nv-websocket-client/ The ANE doesn't actually include this, but it will mean that your application includes it, so please check the license terms (if you have any 'notices' file or third-party software notices in your app, you will need to add this one to it).

This works with WSS connections, and with your test server there. You'll need the extension added to your app descriptor file:

        <extensionID>com.harman.AndroidWebSocket</extensionID>
JoseEstevesPt commented 5 months ago

thanks for all your effort, I will give it a try.

ajwfrost commented 5 months ago

@JoseEstevesPt just wondering how that went..?!

JoseEstevesPt commented 5 months ago

@ajwfrost It din't worked, could not make it work and connect to server, had problems with the ANE testing in android "/private/var/folders/gx/d19f6_y10n92n10dg1lb6gf40000gn/T/TemporaryItems/TesteControla Websocket ane_ANE_Cache/AndroidWebSocket.ane is not a valid native extension file.". But due to the deadline, had to change te project to work with sockets on a local network, with local server, not websockets. Thanks for your effort, and hope that the websockets will be working on future releases, all across different platforms, it will be very useful. Once again thanks for you fast support.

ajwfrost commented 5 months ago

Shame - sounds like something went wrong with the ANE packaging/extraction from that log.. A better plan for us would be to have an implementation of "SecureSocket" on Android that actually works, after which the normal/native WebSocket class should be sufficient.

thanks

bobaoapae commented 5 months ago

@ajwfrost i'm having a problem on windows with websockets.

_webSocket = new WebSocket();
_webSocket.connect("wss://ws-emulador.redesurftank.com.br");
[trace] ERROR: UncaughtError: Error #2031: Socket Error. URL: ws-emulador.redesurftank.com.br
[trace] Error
[trace]     at Loading/uncaughtErrorHandler()[D:\IdeaProjects\ddtank-client\loadingAir\src\Loading.as:178]
[trace]     at flash.events::EventDispatcher/dispatchEventFunction()
[trace]     at flash.events::EventDispatcher/dispatchEvent()
[trace]     at air.net::WebSocket/forwardEvent()

using ws instead od wss

[trace] ERROR: UncaughtError: Error #2031: Socket Error. URL: ws://ws-emulador.redesurftank.com.br
[trace] Error
[trace]     at Loading/uncaughtErrorHandler()[D:\IdeaProjects\ddtank-client\loadingAir\src\Loading.as:178]
[trace]     at air.net::WebSocket/onClientData()
bobaoapae commented 5 months ago
_webSocket = new WebSocket();
_webSocket.connect("wss://websocket.redesurftank.com.br:443/test");
_webSocket.addEventListener(SecurityErrorEvent.SECURITY_ERROR, function (param1:SecurityErrorEvent):void
        {
            dispatchEvent(new ErrorEvent("error", false, false, param1.text));
        });
 _webSocket.addEventListener(ErrorEvent.ERROR, function (param1:ErrorEvent):void
        {
            dispatchEvent(new ErrorEvent("error", false, false, param1.text));
        });
 _webSocket.addEventListener("ioError", function (param1:ErrorEvent):void
        {
            dispatchEvent(new ErrorEvent("error", false, false, param1.text));
        });

In this example I get ioError. This websocket works normally testing from any other software, this websocket it's being proxied by cloudflare workers, maybe some headers are diff from expected by harman but this should be valid, as this works normally from any browser or others websocket programs.

ajwfrost commented 5 months ago

I'm getting a 'connected' event when I try this code..?! What version of AIR SDK are you using?

bobaoapae commented 5 months ago

I'm getting a 'connected' event when I try this code..?! What version of AIR SDK are you using?

Latest release version, 51 build 3 🤔

ajwfrost commented 5 months ago

Okay .. odd. On Windows? wss://websocket.redesurftank.com.br:443/test definitely works for me.

wss://ws-emulador.redesurftank.com.br gives me an ioError. Although it seems like I can access it in a browser..

Hmm... looking at the details, we're getting a response from your server HTTP/1.1 400 Bad Request The request was:

GET / HTTP/1.1
Host: ws-emulador.redesurftank.com.br
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: oPUwvunee9s0aNmnu3hNdQ==
Sec-WebSocket-Version: 13

Are you able to check the server logs? I can't get it to connect via https://websocketman.com/ although that may be CORS related.

Actually, I see in the HTTP response, a "Missing token" body.. so I suspect there's a need for some kind of authentication token from the cloudflare server? Are you able to make any successful connection to it and check the HTTP headers/responses and see if something like that exists?

If so .. we may need to change things so that the connection request is provided a URLRequest object, so that you can add headers etc..

bobaoapae commented 5 months ago

ws-emulador old example, sorry. Testing just with websocket.redesurftank...

I fully unistalled airsdk, deleted cache from sdkmanager downloaded again and now it's work. I suspect that airsdk manager don't fully updated, due to the old tests coping files over e-mail to the sdk path.

image

Sdk manager show the right version, but i think some file don't get updated the right way. Fully uninstall,deleting cache from .airsdk folder, and installing again fixed the issue with websocket here.

bobaoapae commented 5 months ago

@ajwfrost hey, me again.

On windows i can use websocket without problems here now, but testing on android i get this error

[IOErrorEvent type="ioError" bubbles=false cancelable=false eventPhase=2 text="Error #2031: Socket Error. URL: websocket.redesurftank.com.br" errorID=2031]

code:

_webSocket.connect("wss://websocket.redesurftank.com.br/harman/1016");
bobaoapae commented 5 months ago

I'm trying to use the ANE, but I get this error on package: Failed to package AIR application loadingAirAndroidDebug.apk: D:\IdeaProjects\ddtank-client\loadingAirAndroid\src\ane\AndroidWebSocket.ane is not a valid native extension file.

ajwfrost commented 5 months ago

Hi

On Android, we seem to be facing an underlying problem with the secure sockets, so if you're using WSS then you may face that problem. The ANE gets around this by using a separate Java library (imported via gradle: com.neovisionaries:nv-websocket-client:2.14) which handles all the WebSocket stuff within the Java/Android layer.

I've just rebuilt the ANE and checked it, below is a zip of the ANE (i.e. please extract the file from within here). If you still get that 'is not a valid native extension file' please confirm what AIR SDK version you're using, and open up the ANE in a zip manager to check you see a top level set of files including catalog.xml, library.swf and mimetype. AndroidWebSocket_ane.zip

thanks

bobaoapae commented 5 months ago

same error D:\IdeaProjects\ddtank-client\loadingAirAndroid\src\ane\AndroidWebSocket.ane is not a valid native extension file. Air version: 51.0.1.3

image

Image show air version and ane files open in winrar.