Websockets Support - WebSocketClient
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.
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.
will be very good :D
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!).
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?
We are currently using the following for our Ionic Vue App: https://github.com/mia-z/capacitor-websocket
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:
- I miss-configured capacitor and there is a way to get the
Cookieheader also to be transmitted when the web-socket connection is established. & Though a miracle I find this hidden information. OR - 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 ).
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