Any way to help with a ionic 4/5 integration using this... I am struggling to get the
var declare Socket:any
setup to work in Ionic 4/5
Hi @Burnie777, i will reproduce some parts of code of production app that works to help you.
- The socket service
Here we created a service with following content, transforming the Cordova events in Observables:
import { Injectable } from '@angular/core';
import { Platform } from '@ionic/angular';
import { Observable } from 'rxjs';
import { ConverterProvider } from './../providers/converter.provider';
@Injectable({
providedIn: 'root'
})
export class SocketService {
tcp: any;
constructor(private platform: Platform, private converter: ConverterProvider) {
this.platform.ready().then(() => {
this.tcp = new (<any>window).Socket();
});
}
init() {
this.tcp = new (<any>window).Socket();
}
events() {
return new Observable(observer => {
this.tcp.onData = asData => observer.next('socket.onData|' + this.converter.arrayBuffer2str(asData));
this.tcp.onError = asError => observer.next('socket.onError|' + JSON.stringify(asError));
this.tcp.onClose = asClose => observer.error('socket.onClose|' + asClose);
});
}
}
- Converter helper
We created a provider with converter functions:
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class ConverterProvider {
constructor() { }
arrayBuffer2str(buf: Uint8Array) {
return String.fromCharCode.apply(null, new Uint16Array(buf));
}
Str2ArrayBuffer(dataString: string) {
let data = new Uint8Array(dataString.length);
for (let i = 0; i < data.length; i++) {
data[i] = dataString.charCodeAt(i);
}
return data;
}
}
- Putting it to work
Finally we are able to use sockets! Below is an example of how to implement it on your foo.page.ts (some parts of code ommited):
import { Component, OnInit, ViewChild, NgZone } from '@angular/core';
import { ConverterProvider } from './../../providers/converter.provider';
import { SocketService } from './../../services/socket.service';
constructor(private ngZone: NgZone, private converter: ConverterProvider, private socket: SocketService) {}
private open(device: DeviceModel) {
this.socket.init();
this.socket.tcp.open(device.address, device.netPortConfig,
() => {
this.ngZone.run(() => {
this.setDeviceState(true);
console.log(`[Socket] New connection: ${device.address} (${device.name})`);
this.message.popUp(`${device.name} connected`);
});
this.socket.events().subscribe(
data => {
let split = data.toString().split('|');
if (split[0].toLowerCase().trim().includes('socket.onerror')) {
this.ngZone.run(() => console.warn(`[Socket] Connection error:`, JSON.parse(split[1].trim())));
} else {
let received = split[1].trim();
console.log('Received data: ', received);
}
},
error => {
this.ngZone.run(() => {
this.message.popUp(`Device was disconnected`);
this.setDeviceState(false);
console.error('[Socket] Connection closed:', error);
});
}
);
this.socket.tcp.write(
this.converter.Str2ArrayBuffer('Hello World!'),
() => {
this.ngZone.run(() => {
console.log(`[Socket] Data successfully sent to ${device.address} (${device.name})`);
});
}, error => {
this.ngZone.run(() => {
console.error(`[Socket] Unable to sent data to ${device.address} (${device.name})`, error);
});
}
)
}, (error: string) => {
this.ngZone.run(() => {
this.setDeviceState(false);
console.error(`[Socket] Unable to connect: ${device.address} (${device.name}) `, error);
this.message.popUp(`Unable to connect: ${device.name}`);
});
}
);
}
You can now create a button by calling the open method and passing the settings of the server (which I called the device) you want to connect.
Some notes:
- The Device parameter in open method has the connection configs (host address, network port, etc);
- We created the method init() in socket service because when you reuse the object a lot of times it crashes plugin, then we "init" every new connection;
- NgZone is used to properly update interface/visual elements (i just left the console.log for example).
Hope it helps, if you have any problems, just point out that we help (I screwed up a lot until it worked correctly).
I'll create an example project this week to help then update here.