proposals icon indicating copy to clipboard operation
proposals copied to clipboard

Websockets Support - WebSocketClient

Open tiuscodes opened this issue 4 years ago • 7 comments

Plugin Request

Web Socket Client

Name: Web Socket Client Package: @capacitor-community/web-socket-client

Platform(s)

Android, Web

Existing Solutions

This plugin claims to support android, ios and web https://github.com/HomeControlAS/cordova-plugin-advanced-websocket

This plugin appears to have a simpler android implementation and ios support https://github.com/kannercao/cordova-websocket-client-cert

Description

An API similar to that of https://www.npmjs.com/package/react-use-websocket but with support for running on Android as well as web.

tiuscodes avatar May 18 '21 09:05 tiuscodes

I actually generated this request because of difficulty getting websockets working on an ionic / react / capacitorjs project. Turns out the problem was with my android emulator networking. I only realised after testing on a physical device 😏. Not sure what to do with this now.

tiuscodes avatar May 18 '21 13:05 tiuscodes

will be very good :D

vitalijalbu avatar May 20 '21 17:05 vitalijalbu

To the others reading this afterwards. Native JS websocket clients work fine with Capacitor, I have apps working with websockets. Be sure to follow the rules for websockets though (other clients will only connect over a secure channel!).

ultimate-tester avatar May 25 '21 16:05 ultimate-tester

To the others reading this afterwards. Native JS websocket clients work fine with Capacitor, I have apps working with websockets. Be sure to follow the rules for websockets though (other clients will only connect over a secure channel!).

Does this mean that my client can only connect to servers via wss?

VirusBLITZ avatar Aug 15 '22 18:08 VirusBLITZ

We are currently using the following for our Ionic Vue App: https://github.com/mia-z/capacitor-websocket

MartinLoeper avatar May 29 '23 19:05 MartinLoeper

I also had a hard time finding resources here. I've got websockets to work partially after a while and I'm also using 'react-use-websockets'.

My issue is that I authenticate websocket connections though a session token passed in the cookie header. Capacitor http + cookies correctly patches the headers for fetch but not for the websocket it seems:

Websocket connection headers in browser:

GET ws://localhost:8000/api/core/ws HTTP/1.1
Host: localhost:8000
Connection: Upgrade
Pragma: no-cache
Cache-Control: no-cache
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36
Upgrade: websocket
Origin: http://localhost:8000
Sec-WebSocket-Version: 13
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Cookie: csrftoken=q3Etil1qDyyLTYDG276zPNfn1noWeT4e; sessionid=someSessionId:D
Sec-WebSocket-Key: d/DRhWaZv7aqPwptHbh/fQ==
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits

Websocket connection headers though capacitor android:

Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
Cache-Control: no-cache
Connection: Upgrade
Host: 10.0.2.2:8000
Origin: http://localhost
Pragma: no-cache
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
Sec-WebSocket-Key: UXOaWlWQ+ehX+FxzDLbCdQ==
Sec-WebSocket-Version: 13
Upgrade: websocket
User-Agent: Mozilla/5.0 (Linux; Android 13; sdk_gphone64_x86_64 Build/TE1A.220922.021; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/103.0.5060.71 Mobile Safari/537.36

Not that in the second case the Cookie header is missing. If I use CapacitorCookie and log document.cookie I can verify that both sessionid and csrftoken are present on the client.

So in general I'd say make sure that connection is really not getting though to the server ( it was for me ). And If it's getting though check if the connection can actually be authorized and established ( that was the issue for me ).

I still haven't found a good solution for this I suppose there are 2 outcomes here:

  1. I miss-configured capacitor and there is a way to get the Cookie header also to be transmitted when the web-socket connection is established. & Though a miracle I find this hidden information. OR
  2. I have to write a custom authentication scheme that allows authenticating with data passed on an initial web-socket message ( after establishing an unauthenticated connection ).

tbscode avatar Jun 26 '23 18:06 tbscode

Actually, my bad. It was the configuration.

The solution is also visible in my output above. I misconfigured the Android hostname, since I was using ws://10.0.2.2:8000 as a WebSocket route but had my Capacitor config still at the default hostname localhost. The cookies would not be sent when establishing the connection.

I simply set:

...
  server: {
    hostname: "10.0.2.2:8000",
    ...
  plugins: {
    CapacitorHttp: {
      enabled: true,
    },
    CapacitorCookies: {
      enabled: true
    }
    ...
  },

In my capacitor.config.ts, now everything is working as expected.

I'm using:

    "@capacitor/android": "^5.0.2",
    "@capacitor/core": "^5.0.2",
    "@capacitor/ios": "^5.0.2",
    "@capacitor/preferences": "^5.0.2",

And I have WebSockets fully working now!

So you can find a project using react-use-websocket in a React + Next.js frontend with a Django backend over here: tims-stack

tbscode avatar Jun 26 '23 20:06 tbscode