Open mapicard opened 4 years ago
I have removed the plugin npm remove blocshop-sockets-for-cordova-plugin
Then I added it with
ionic cordova plugin add blocshop-sockets-for-cordova-plugin
Then no more errors when running my constructor.
Still have an issue with the plugin package.json file, vscode complains that
Incorrect type. "Expected array". [32,25]
which is "bundleDependencies": false,
I changed it to "bundleDependencies": [],
No more errors in vscode.
I still have to use (<any>window).Socket()
in my constructor for the build to succeed.
When I try to import { Socket } from 'blockshop-sockets-for-cordova-plugin';
vscode complains about not finding the module and the build fails with
Cannot find module 'blockshop-sockets-for-cordova-plugin'
.
Some more googling lead me try replace the import with declare var Socket:any;
and now
this.socket = new Socket();
in my constructorBut... vsCode autocompletion not working...
Just in case somebody else needs this, I'll keep a recap here to summarize the steps to make it work under Ionic3.
Intall the plugin with
ionic cordova plugin add blocshop-sockets-for-cordova-plugin
In the module where you need it, use declare instead of import and use the api as documented.
I'm updating this recap to provide more details on my progress as requested. So far I can connect to my legacy server, send some data, receive a response and close the connection.
Keep in mind: I am new to Ionic & this library, if there's a better way, please advise.
In my case, tcp-service.ts looks like this so far
import { Injectable } from '@angular/core';
var declare Socket:any //import { Socket } from 'blocshop-sockets-for-cordova-plugin
@Injectable()
export class TCPServices {
private socket;
constructor() {
this.socket = new Socket();
this.socket.onData = ((data) => {
// invoked after new batch of data is received (typed array of bytes Uint8Array)
console.log('socket.onData'+this.arrayBuffer2str(data));
});
this.socket.onError = function(errorMessage) {
// invoked after error occurs during connection
console.log('socket.onError'+errorMessage);
};
this.socket.onClose = function(hasError) {
// invoked after connection close
console.log('socket.onClose'+hasError);
};
}
sendTest() {
this.socket.open("192.168.1.71", 23,
() => {
// invoked after successful opening of socket
console.log('socket.open.success');
this.socket.write(String.fromCharCode(13));
setTimeout(()=> { this.socket.shutdownWrite(); }, 2000);
},
(errorMessage) => {
// invoked after unsuccessful opening of socket
console.log('socket.open.failed'+errorMessage);
}
);
}
and my server-details.ts
import { TCPServices } from '../../providers/providers';
@Component({
export class ServerDetailsPage {
...
constructor(..., public tcp:TCPServices) {
...
}
buttonClicked(thisServer:Server) {
this.tcp.sendTest();
}
}
@mapicard I'm trying to send data to the other side, but it is not working, I can only make the connection, could you send me a complete example?
@daleffe I have updated my recap with more details. Hope this helps.
@daleffe I have updated my recap with more details. Hope this helps.
Thanks for your update.
I did some tests using netcat tcp servers and i was unable to receive the string, what i'm doing wrong?
I tried like this:
this.socket.open("192.168.25.6", 37005,
() => {
// invoked after successful opening of socket
var dataString = "Hello world";
var data = new Uint8Array(dataString.length);
for (var i = 0; i < data.length; i++) {
data[i] = dataString.charCodeAt(i);
}
this.socket.write(data + String.fromCharCode(10) + String.fromCharCode(13));
setTimeout(()=> { this.socket.shutdownWrite(); }, 2000);
},
(errorMessage) => {
// invoked after unsuccessful opening of socket
console.log('socket.open.failed'+errorMessage);
}
);
And i tried like this:
this.socket.write ("Hello world" + String.fromCharCode (10) + String.fromCharCode (13));
Can you help me?
I don't know your server app since port 37005 is unassigned, but I doubt its tcp handshake is expecting the string "Hello world". But then anything is possible. Try to send something that the server expects.
I did some tests using netcat tcp servers and i was unable to receive the string, what i'm doing wrong?
I'm not familiar with netcat but I would start by making sure the client device (mobile) can communicate with the server app. Any configurable Telnet client (iOS & Android) woud do. You won't go through the whole handshake but you'll be able to tell if you can connect and therefore determine if your problem is or is not related to the network or firewall.
@mapicard i did new test again and it works. Thanks!
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
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.
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);
});
}
}
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;
}
}
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:
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.
Thank you @daleffe,
I will check it out… And let you know when and where I get stuck in the process… I would appreciate the sample project as well…
Thank you @daleffe,
I was able to get it to work with the above mentioned code... Much appreciated...
Good day, how would I be able to timeout the call with an error if not responding within a specific timeout?
I have tried a settimeout in 2 places with no success...
events() {
return new Observable(observer => {
setTimeout({
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);
},2000);
});
}
and also put the onOpen content in a setTimeout...
The issue we are having is that some of the places, our app is being used, may struggle with connection to the server, and sometimes overall connectivity... thus open connection times out and fails... so I would like to shorten the time of that timeout
Alternatively, you can try this plugin (fork with connection fixes) cordova-plugin-socket-tcp
Alternatively, you can try this plugin (fork with connection fixes) cordova-plugin-socket-tcp
Do you have plans for Capacitor version?
Alternatively, you can try this plugin (fork with connection fixes) cordova-plugin-socket-tcp
Do you have plans for Capacitor version?
It's possible, I'll add the Capacitor version in a few months
Hi, I've installed the plugin with
npm i blocshop-sockets-for-cordova-plugin
and added it under cordova.js in index.html as instructed.If I use
this.socket = new Socket();
in my constructor, the build fails withCannot find name 'Socket'.
Error: Failed to transpile program
If I use
this.socket = new (<any>window).Socket();
When building the app with
ionic cordova emulate ios --target "iPhone-XS-Max, 12.4"
orionic cordova emulate android
the builds succeed but do not contain the file socket.js and Chrome console says
window.Socket is not a constructor
.I'm using
ionic-angular 3.9.2
Cordova android:7.0.0, ios: 5.1.1