TCP sockets in ionic

Hello, In my application I need to use a custom protocol over raw TCP sockets (so socket.io is out of scope). I need to connect the mobile device to another with a certain IP address, and send and receive data over this connection. As far as I have seen, the closes plugin that could support this for ionic 2 would be cordova-plugin-chrome-apps-sockets-tcp, but I have not had any luck in using this in an ionic 2 project.

I have tried both
declare var chrome;
and
(<any>window).plugins.chrome.tcp.socket.create();
without any success.

I have seen an example using this plugin successfully, written for ionic (1), but I am afraid I lack the experience to convert it to ionic 2:
https://github.com/nutella/ionic-cordova-chrome-tcp-example

Would anybody have any knowledge on the matter, either on how to use the aforementioned plugin, or suggest another one I could use?

Thank you

For anyone interested: the reference to the plugin is made via window, but not through the plugins namespace, but directly. Thus, in order to call, for instance, the create method, one should use:
(<any>window).chrome.tcp.socket.create();

I hope this helps someone.

3 Likes

Still can’t understand how to use this plugin in an Ionic 2 provider. With other plugins I just import them and they are available for use. Anyone can help?

This is the complete provider I am using:

import { Injectable } from '@angular/core';
import { Http } from '@angular/http';
import 'rxjs/add/operator/map';

/*
  Generated class for the TCPServices provider.

  See https://angular.io/docs/ts/latest/guide/dependency-injection.html
  for more info on providers and Angular 2 DI.
*/

@Injectable()

export class TCPServices {

  constructor(public http: Http) {
    console.log('Hello TCPServices Provider');
  }

	arrayBuffer2str(buf) {
		var str= '';
		var ui8= new Uint8Array(buf);
		for (var i= 0 ; i < ui8.length ; i++) {
			str= str+String.fromCharCode(ui8[i]);
		}
		return str;
	}

	str2arrayBuffer(str) {
		var buf= new ArrayBuffer(str.length);
		var bufView= new Uint8Array(buf);
		for (var i= 0 ; i < str.length ; i++) {
			bufView[i]= str.charCodeAt(i);
  		}
		return buf;
	}

	sendPacket(ipAddr,ipPort,data) {
		var delay= 5000;	/// 5 seconds timeout
		(<any>window).chrome.sockets.tcp.create({}, createInfo => { //callback function with createInfo as the parameter
			var _socketTcpId= createInfo.socketId;
			(<any>window).chrome.sockets.tcp.connect(_socketTcpId, ipAddr, ipPort, result => { //callback function with result as the parameter
				if (result === 0) {
					var data2send= this.str2arrayBuffer(data);
					/// connection ok, send the packet
					(<any>window).chrome.sockets.tcp.send(_socketTcpId, data2send);
				}
			});
			(<any>window).chrome.sockets.tcp.onReceive.addListener( info => { //callback function with info as the parameter
				/// recived, then close connection
				(<any>window).chrome.sockets.tcp.close(_socketTcpId);
				var data= this.arrayBuffer2str(info.data);
			});
			/// set the timeout
			setTimeout(function() {
				(<any>window).chrome.sockets.tcp.close(_socketTcpId);
			}, delay);
		});
	}
}
4 Likes

hi from france,
i start ionic2 personnal project and i want to use ethernet thermal printer, but i have error :
chrome.sockets.tcp.send - data is not an Array Buffer! (Got: String)

can you help and explain me how to send esc-pos character to printer,

thanks you

Hi

you need to create an arraybuffer and send this, not a string.

See https://developers.google.com/web/updates/2012/06/How-to-convert-ArrayBuffer-to-and-from-String

Tom

Hello,

Indeed, you need to send an arraybuffer. So, please note that in the sendPacket function within the code attached to the thread, there is a str2arrayBuffer function that does exactly this conversion.

Nikos

thanks you,
last question, in php i use :
$print = chr(0x1B).chr(0x64).chr(0x00);
can you explain me how to correctly write/convert this sequence

thanks you

the solution is here :

command.js

thanks you for all

I tried using the same code in my ionic 2 typescript project and still no success. It says can not read property sockets of undefined.

Please assist me with some sample application. Struggling to get the reference in typescript for this plug in.

Do you still no success?? I got same problem…

Is the undefined problem resolved? Can’t seem to find other solutions on the net…

I used the same code in ionic 2 but it return Runtime error can’t read property ‘sockets’ of undefined.

you need to use the platform.ready() function to make sure cordova is ready, THEN the chrome sockets will be usable…

import {  Platform } from 'ionic-angular';

inject via constructor

constructor(public navCtrl: NavController, public navParams: NavParams,
  			public viewCtrl: ViewController, **platform:Platform**)

in constructor

     platform.ready().then(
	(readySource) => {
	     if(readySource=='cordova'){
	     	 // start handling network stuff now
	     }
      }); 	

Can you help me to sole this error. i am using the exact code that you have shared.

main.js:1507 ERROR TypeError: Cannot read property ‘sockets’ of undefined
at HomePage.addDevice (file:///android_asset/www/build/main.js:48894:22)
at Object.eval [as handleEvent] (ng:///AppModule/HomePage.ngfactory.js:5159:24)

i had a problem where I had to reinstall the cordova platfom

ionic cordova platform rm (ios or android)
ioinc cordova plafform add (ios or android)

and then I had a problem where the plugin wasn’t install properly with npm

so I had to do npm install chrome-sockets…

see the top of https://www.npmjs.com/package/cordova-plugin-chrome-apps-sockets-tcp
says use npm i

Hi guy,
I’m a new development guy, and I’ve found a solution and I give it.

export class HomePage  {

private socketTcpId: number;

constructor(platform:Platform , public navCtrl: NavController, private vibration: Vibration,   public alertCtrl: AlertController) {
        
        platform.ready().then((readySource) => {
	     if(readySource=='cordova'){
             
	     	 // start handling network stuff now
             //this.AlertAction();
             (<any>window).chrome.sockets.tcp.create({}, createInfo => {
             this.socketTcpId = createInfo.socketId;   
                // this.AlertAction();;
                (<any>window).chrome.sockets.tcp.connect(this.socketTcpId, "192.168.1.42", 12345, result => {
                console.log("Connected to server");
            });
            });
	     }
      }); 	
  }

And Send Method

arrayBuffer2str(buf): string {
		var str= '';
		var ui8= new Uint8Array(buf);
		for (var i= 0 ; i < ui8.length ; i++) {
			str= str+String.fromCharCode(ui8[i]);
		}
		return str;
   }

   str2arrayBuffer(str) : ArrayBuffer {
		var buf= new ArrayBuffer(str.length);
		var bufView= new Uint8Array(buf);
		for (var i= 0 ; i < str.length ; i++) {
			bufView[i]= str.charCodeAt(i);
  		}
		return buf;
	}

	sendPacket( ) : void {
		      
				var data2send= this.str2arrayBuffer( "Philip is the best\n\r");
				// connection ok, send the packet
				(<any>window).chrome.sockets.tcp.send(this.socketTcpId, data2send);
		
	}

Enjoy it :slight_smile:

1 Like

Hello TOTO69,

do you have any idea how to receive data from the server if the server sends data/answer back after you send the server data with the send method ?

you would use the receiveListener

(window).chrome.sockets.tcp.onReceive.addListener(recvListener) ;

var amountReceived = 0;
function recvListener(info)
{
amountReceived += info.data.byteLength;
var arr = new Uint8Array(info.data);
var textChunk = String.fromCharCode.apply(null,arr);
}

note that for large messages you might have multiple receives to get the whole message

hi sdetweil, thankyou for your fast answer but it seems like it is not working. here is my code maybe you can have a quick look:

login(){
var data = this.str2ab(“0x7c0x040x000x00”);
(window).chrome.sockets.tcp.create({}, createInfo => {
let socketTcpId = createInfo.socketId;
(window).chrome.sockets.tcp.connect(socketTcpId, this.IPADRESS, this.PORT, result => {
alert(result);
console.log(“Connected to server”);
alert(“connected to server”);
(window).chrome.sockets.tcp.send(socketTcpId, data, function(info) {
alert(info.resultCode);
alert(“send executed”);
(window).chrome.sockets.tcp.onReceive.addListener(recvListener) ;
var amountReceived = 0;
function recvListener(info)
{
amountReceived += info.data.byteLength;
var arr = new Uint8Array(info.data);
var textChunk = String.fromCharCode.apply(null,arr);
}
});
});
});

i think it connect and send work fine because result and info.resultCode are equal 0. But i am having problems receiving data from server