TCP Socket for React App

Hello! :slight_smile:

I am currently building a React based APP which will have a functionality to connect to Thermal Printers in the network via IP, sending ArrayInt8 data through a TCP Socket.

In the past we had the chrome.sockets.tcp extension that allowed us to do this, but unfortunately it was deprecated.

A solution like Socket.io always applies an intermediate layer which formats the data and doesn’t let it get to the destination IP on its raw state.

All I can find are Cordova options like: GitHub - KoenLav/cordova-plugin-chrome-apps-sockets-tcp

Do you have any solution for Capacitor as I am building a React project? Or is there any way I can use cordova plugins on my project?

Thanks for your kind attention!

I haven’t used that specific plugin before but a ton of Cordova plugins will work with Capacitor. So you could try doing that; or you could try using a Javascript WebSocket which is supported on every device that Capacitor 2 or 3 supports

Hey again! Sorry for taking so long to answer.

So, the Javascript WebSocket is not a solution. I need to connect to an HTTP:// protocol and not a WS://.

I managed to pass the raw data properly with the Ionic Native HTTP Plugin . The problem is that the since it establishes a connection on each request, the printer prints the Request Header like:

POST / HTTP/1.1
Content-Length: 68137
Content-Type: application/octet-stream;

I believe we really need a socket connection, like the deprecated google plugin cordova-plugin-chrome-apps-sockets-tcp which I believe was continued by the sockets-for-cordova TCP/IP plugin. The only problem is that I am not able to use it on an React based Ionic app.

Is there any way to easily use this sockets-for-cordova plugin with capacitor? Or maybe this one cordova-plugin-epson-epos2 which is a little bit more oriented to Epson Thermal Printers?

I have also tried cordova-plugin-printer but I get a gradle error when trying to run for Android.

This is the error:

> capacitor run android --no-sync --target Pixel_C_API_30
[capacitor] âś– Running Gradle build - failed!
[capacitor] [error] 
[capacitor]         > Configure project :app
[capacitor]         google-services.json not found, google-services plugin not applied. Push Notifications won't work
[capacitor]         WARNING:: Using flatDirs should be avoided because it doesn't support any meta-data formats.
[capacitor]         Currently detected usages:
[capacitor]         - repository flatDir used in: project ':app', project ':capacitor-cordova-android-plugins'
[capacitor]         WARNING:: Please remove usages of `jcenter()` Maven repository from your build scripts and migrate your build to other Maven repositories.
[capacitor]         This repository is deprecated and it will be shut down in the future.
[capacitor]         See http://developer.android.com/r/tools/jcenter-end-of-service for more information.
[capacitor]         Currently detected usages in: root project 'android', project ':app', project ':capacitor-android', ...

And these are my packages:

    "@capacitor/android": "3.2.3",
    "@capacitor/app": "1.0.0",
    "@capacitor/core": "3.0.0",
    "@capacitor/haptics": "1.0.0",
    "@capacitor/ios": "3.0.1",
    "@capacitor/keyboard": "1.0.0",
    "@ionic-native/bluetooth-serial": "^5.33.0",
    "@ionic-native/core": "^5.33.1",
    "@ionic-native/file": "^5.36.0",
    "@ionic-native/http": "^5.36.0",
    "@ionic-native/printer": "^5.36.0",
    "@ionic/react": "^5.5.0",
    "@ionic/react-router": "^5.5.0",
    "@ionic/storage": "^3.0.4",
    "@testing-library/jest-dom": "^5.11.9",
    "@testing-library/react": "^11.2.5",
    "@testing-library/user-event": "^12.6.3",
    "@types/jest": "^26.0.20",
    "@types/node": "^12.19.15",
    "@types/react": "^16.14.3",
    "@types/react-dom": "^16.9.10",
    "@types/react-router": "^5.1.11",
    "@types/react-router-dom": "^5.1.7",
    "@types/socket.io-client": "^1.4.34",
    "axios": "^0.21.1",
    "cordova-plugin-advanced-http": "^3.2.1",
    "cordova-plugin-epson-epos2": "^1.0.3",
    "cordova-plugin-file": "^6.0.2",
    "cordova-plugin-printer": "^0.8.0",
    "cz.blocshop.socketsforcordova": "^1.1.0",
    "date-fns": "^2.16.1",
    "ionicons": "^5.4.0",
    "node-sass": "^6.0.0",
    "react": "^17.0.1",
    "react-dom": "^17.0.1",
    "react-indiana-drag-scroll": "^2.0.1",
    "react-router": "^5.2.0",
    "react-router-dom": "^5.2.0",
    "react-scripts": "4.0.2",
    "rxjs": "^7.1.0",
    "socket.io": "^2.3.0",
    "socket.io-client": "^2.3.1",
    "typescript": "^4.1.3",
    "web-vitals": "^0.2.4",
    "workbox-background-sync": "^5.1.4",
    "workbox-broadcast-update": "^5.1.4",
    "workbox-cacheable-response": "^5.1.4",
    "workbox-core": "^5.1.4",
    "workbox-expiration": "^5.1.4",
    "workbox-google-analytics": "^5.1.4",
    "workbox-navigation-preload": "^5.1.4",
    "workbox-precaching": "^5.1.4",
    "workbox-range-requests": "^5.1.4",
    "workbox-routing": "^5.1.4",
    "workbox-strategies": "^5.1.4",
    "workbox-streams": "^5.1.4"

Thank you so very much again!

Hey there, again!

So I managed to solve my issue. I am now able to establish a TCP Socket with any address on a local network on a React based Ionic App.

For that I adapted blocshop’s sockets-for-cordova plugin (mentioned on my previous answer), as I was suspecting

Made a really small change that enabled TypeScript usage and Capacitor 3 is now able to do its’ job of reading the Cordova package.

I’ll just leave here the package in case it helps anyone!
https://www.npmjs.com/package/@vendus/sockets-for-cordova

Thank you for help! :slight_smile:

1 Like

Hi Joao!
Is this fully working for you? I can’t connect at socket.
I have tried your solution, but got many errors like this:

Uncaught TypeError: Cannot read properties of undefined (reading 'dispatchEvent')
    at <anonymous>:1:15

Please, can you tell me how to solve that?

Also:
window.Socket.dispatchEvent({"type":"Close","hasError":true,"socketKey":"ab0756be-ddbd-e0ee-31ae-6b70a1a9c02d"});

Hello @TomCosta , sorry for using another account.
I’m going to share a small code example of how it was working for me at the time.

This is using Ionic React

import { IonButton, IonCol, IonContent, IonGrid, IonPage, IonRow, useIonViewDidEnter } from '@ionic/react';
import { useContext, useState } from 'react';
import Socket from '@vendus/sockets-for-cordova';
const Tests: React.FC<props> = () => {
  const [socketTest] = useState(new Socket());
  useIonViewDidEnter(() => {
        // Change the IP and PORT to the desired one
        socketTest.open('192.168.1.83', 9100, (res:any) => { 
            console.log(res);
            console.log('success!')
        }, (res:any) => {
            console.log(res);
            console.log('error!')
        })
   });
   return (
        <IonPage>
            <Header />
            <IonContent fullscreen>
                <IonGrid>
                    <IonRow class="ion-justify-content-center">
                        <IonCol size="16" sizeLg="8">
                            <IonButton onClick={async () => {
                                // I was passing UInt8Array data because the thermal printer needed it, but you can send pretty much whatever you want.
                                let data = stringToUint8Array(atob('G0AKG2ExGyEgTmV4ChshABshAFJ1YSBDYXJsb3MgQWxiZXJ0byBNb3JhaXMsIG5vMTIyLCBMb3RlIEEsIDNvRXNxLiBQb2VudGUKNDQ1MC0zNDkgTGVjYSBkYSBQYWxtZWlyYQpOSUY6IDIzMzI5Njg2NwobYTAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KG2EwRmF0dXJhIFRlc3RlICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRFU1RFIDAxCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpPcmlnaW5hbCAgICAgICAgICAgICAgICAgICAgICAgIDIwMjEtMDktMjMgMTI6MTkKCk5JRjogLS0tLS0tLS0tCk5vbWU6IENvbnN1bWlkb3IgRmluYWwKCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KUmVmZXJlbmNpYSBQcm9kdXRvICAgICAgICAgICAgICAgICAgICAgICAgVG90YWwKICBRdGQuIHggUHJlY28gKElWQSkKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tClRyaWRlbnQgTWludCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMSwwOQogIDEgeCAxLDA5ICgyMyUpCkhhcHB5ZGVudCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCw5NQogIDEgeCAwLDk1ICgyMyUpCkdvcmlsYSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwwNQogIDEgeCAwLDA1ICgyMyUpClZCVUIxMS0xNzA5MjU4OCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMSwwMApCdWJhbG9vCiAgMSB4IDEsMDAgKDIzJSkKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgobISBUb3RhbCAgICAgICAgICAgRXVyIDMsMDkKGyEARGluaGVpcm8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEV1ciA1LDAwCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KJUlWQSAgICAgICAgICBCYXNlICAgICAgICAgSVZBICAgICAgICAgICAgIFRvdGFsCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoyMyUgICAgICAgICAgIDIsNTEgICAgICAgIDAsNTggICAgICAgICAgICAgIDMsMDkKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpFc3RlIGRvY3VtZW50byBuYW8gc2VydmUgZGUgZmF0dXJhCgobYTFBNWFMLVByb2Nlc3NhZG8gcG9yIHByb2dyYW1hIApjZXJ0aWZpY2FkbyBuLiAyMjMwL0FUChthMAobYTFPcGVyYWRvcjogSm9hbwoKT2JyaWdhZG8gcGVsYSBwcmVmZXJlbmNpYSEKG2EwG3AAYP8bSv4bbQ=='));
                                socketTest.write(data, (res:any) => {
                                    console.log('write success:', res)
                                }, (res:any) => {
                                    console.log('write error:', res)
                                });
                            }}>
                                Test
                            </IonButton>
                        </IonCol>
                    </IonRow>
                </IonGrid>
            </IonContent>
        </IonPage>
    );
};

Hope it helps.

I’m also using the following packages:

    "@capacitor/android": "3.2.3",
    "@capacitor/app": "1.0.0",
    "@capacitor/core": "^3.2.4",
    "@capacitor/haptics": "1.0.0",
    "@capacitor/ios": "3.2.4",
    "@capacitor/keyboard": "1.0.0",
    "@capacitor/network": "^1.0.3",
    "@capacitor/splash-screen": "^1.1.5",
    "@ionic-native/core": "^5.33.1",
    "@ionic/react": "^5.6.0",
    "@ionic/react-router": "^5.6.0",
    "@vendus/sockets-for-cordova": "^1.7.2",
    "react": "^17.0.1",
    "react-dom": "^17.0.1",
    "typescript": "^4.1.3",
1 Like

Thanks for your reply!
I still have problems using it with Angular.

I’m sorry to hear. This npm package I created was adapted to work in React. The original repository was this one, maybe it can help you:
https://github.com/blocshop/sockets-for-cordova

Everton Costa via Ionic Forum <notifications@ionicframework.discoursemail.com> escreveu no dia quarta, 18/05/2022 Ă (s) 21:32:

Thanks for sharing.
I will have a look on it.

1 Like

The same issue for me. Have you solved this issue???

Actually I give up using Capacitor and ended up using Cordova with this plugin:

Hi @joao-oliveira

I’m also trying to use the npm package you made from the modified blocshop package. But I get an error on the console:
Uncaught ReferenceError: cordova is not defined at Socket.open at line 84

Here is see in your code that it calls: cordova.exec…

So somehow that module is not included in my configuration/app. Maybe a version problem in my new’er project?

I can’t figure out what is wrong. Have you any idea what could be missing?

Thanks

NB:
“dependencies”: {
“@capacitor/app”: “5.0.6”,
“@capacitor/core”: “5.4.1”,
“@capacitor/haptics”: “5.0.6”,
“@capacitor/ios”: “5.4.1”,
“@capacitor/keyboard”: “5.0.6”,
“@capacitor/status-bar”: “5.0.6”,
“@ionic/react”: “^7.0.0”,
“@ionic/react-router”: “^7.0.0”,
“@types/react-router”: “^5.1.20”,
“@types/react-router-dom”: “^5.3.3”,
“@vendus/sockets-for-cordova”: “^1.7.2”,
“cordova-plugin-chrome-apps-sockets-udp”: “^1.3.0”,
“ionicons”: “^7.0.0”,
“react”: “^18.2.0”,
“react-dom”: “^18.2.0”,
“react-router”: “^5.3.4”,
“react-router-dom”: “^5.3.4”
},