I am trying to share datas between a cordova app (android) and a node server, but the client doesn't stop disconnect and reconnect...
Also, I can't get any information from the server (probably because the client disconnects too fast).
Here's my simple server :
io.sockets.on('connection', function (socket) {
console.log('new connected : ' + socket.id);
socket.emit('connected', {"data": "YEAAAAH"});
socket.on('slt', ( data ) => {
console.log(data);
});
socket.on("disconnect", () => {
console.log("disconnection");
});
});
And the code i use for the client app :
<script type="text/javascript" src="http://cdn.socket.io/socket.io-1.0.3.js"></script>
let socket = io.connect('http://MY-DOMAIN-NAME.com');
socket.on('connected', function (data) {
alert('connected');
socket.emit('slt', { data: 'slt' });
});
And a picture of the logs after 5 sec... :
logs
Do you have an idea how to fix that ? :)
Ok problem fixed : I messed up for linking my scripts :/
Related
Im using react-native-tcp-socket and my code is identical to what is in their docs. I am able to make a connection and send/receive one message, but when I try to connect again, I get this error. I am working on an android simulator and connecting to a node js server.
var client = TcpSocket.createConnection(options);
client.on('data', function(data) {
console.log('message was received', data);
});
client.on('error', function(error) {
console.log(error);
});
client.on('close', function(){
console.log('Connection closed!');
});
// Write on the socket
client.write('COORDINATE_MOVE ELEV:' + this.state.elevation + 'AZIM:' + this.state.azimuth + 'ID:todd');
// Close socket
client.destroy();
I am developing a game on React-Native that works completely offline without needing internet connection,
The game will be multiplayer 1vs1 game, and players will join via Wifi Hotspot (also known as wifi Direct)
The game will also allow users to chat with eachother
and this all should be done without internet by just using the wifi..
I have tried "React-Native-Wifi-Hotspot" but there is no documentation about how to send and receive data
I want to send and receive objects/arrays over wifi hotspot between 2 connected devices. P2P
I have also readed about react-native-wifi-p2p library but it's documentation says that we need a local server or something i am really not sure about how to do that.
So, I would keep this answer as comprehensive as possible. I will share a small react-native application I build to help understand what exactly we need to do.
This answer is a working extension to #ßãlãjî 's answer.
Libraries we need:
react-native-tcp
react-native-network-info
// In App.js
import {createAppContainer} from 'react-navigation';
import {createStackNavigator} from 'react-navigation-stack';
import ClientScreen from './src/screens/ClientScreen';
import ServerScreen from './src/screens/ServerScreen';
const navigator = createStackNavigator({
Server: ServerScreen,
Client: ClientScreen
});
export default createAppContainer(navigator);
// In ClientScreen.js
import React, {useState, useEffect} from 'react';
import {View, Text, Button, FlatList, TextInput} from 'react-native';
import { NetworkInfo } from 'react-native-network-info';
var net = require('react-native-tcp');
const createClient = (ip, chats, setChats) => {
const client = net.createConnection(6666,ip, () => {
console.log('opened client on ' + JSON.stringify(client.address()));
// client.write('Hello, server! Love, Client.');
});
client.on('data', (data) => {
setChats([...chats, {id:chats.length+1, msg:data}]);
// console.log('Client Received: ' + data);
// client.destroy(); // kill client after server's response
// this.server.close();
});
client.on('error', (error) => {
console.log('client error ' + error);
});
client.on('close', () => {
console.log('client close');
});
return client;
};
const ClientScreen = ({navigation}) => {
const [client, setClient] = useState(null);
const [chats, setChats] = useState([]);
useEffect(async () => {
let ip = await NetworkInfo.getIPV4Address(); //await NetworkInfo.getGatewayIPAddress();
setClient(createClient(ip));
return () => {};
}, []);
return <View>
<Text>Client Screen</Text>
<Button title="Stop Client" onPress={() => {
if(client){
client.destroy();
setClient(null);
}
}}/>
{client ? <Text>Client is on</Text>: null}
<FlatList
data={chats}
renderItem={({item}) =>{
return <Text style={{margin:10, fontSize:20}}>{item.msg}</Text>;
}}
keyExtractor={item => item.id}
/>
<TextInput placeholder="Type a message" placeholderTextColor="black" style={{margin:10, borderWidth:2, color:'black'}} onSubmitEditing={({nativeEvent: {text}}) => {
if(client){
client.write(JSON.stringify({msg:text, id:1}));
}
}}/>
</View>;
};
export default ClientScreen;
// In ServerScreen.js
import React, {useState} from 'react';
import {View, Text, Button, StyleSheet, FlatList} from 'react-native';
import { NetworkInfo } from 'react-native-network-info';
var net = require('react-native-tcp');
const createServer = (chats, setChats) => {
const server = net.createServer((socket) => {
console.log('server connected on ' + socket.address().address);
socket.on('data', (data) => {
let response = JSON.parse(data);
setChats([...chats, {id:chats.length+1, msg:response.msg}]);
// console.log('Server Received: ' + data);
// socket.write('Echo server\r\n');
});
socket.on('error', (error) => {
console.log('error ' + error);
});
socket.on('close', (error) => {
console.log('server client closed ' + (error ? error : ''));
});
}).listen(6666, () => {
console.log('opened server on ' + JSON.stringify(server.address()));
});
server.on('error', (error) => {
console.log('error ' + error);
});
server.on('close', () => {
console.log('server close');
});
return server;
};
const ServerScreen = ({navigation}) => {
const [server, setServer] = useState(null);
const [chats, setChats] = useState([]);
const [ip, setIp] = useState('');
return <View>
{ip.length > 0? <Text>Server Screen: {ip}</Text>: <Text>Server Screen</Text>}
<Button title="Start Server" onPress={async () => {
if(!server)
setServer(createServer(chats, setChats));
try{
let temp_ip = await NetworkInfo.getIPV4Address();
setIp(temp_ip);
}catch(e){
console.log(e.message);
}
}}/>
<Button title="Stop Server" onPress={() => {
if(server){
server.close();
setServer(null);
}
}}/>
<Button title="Go to Client Screen" onPress={() => navigation.navigate('Client')}/>
{server ? <Text>Server is on</Text>: null}
<FlatList
data={chats}
renderItem={({item}) =>{
return <Text style={{margin:10, fontSize:20}}>{item.msg}</Text>;
}}
keyExtractor={item => item.id}
/>
</View>;
};
const styles = StyleSheet.create({});
export default ServerScreen;
Firstly, how to run this application.
Build and Install this into a physical device or Emulator.
First, go to ServerScreen.
In the ServerScreen press on Start Server button. You will be able to see an IP address pop in the screen.
Now navigate to ClientScreen. The Client socket gets automatically invoked once you navigate to this Screen. Here you can see a button and a text input field. Type in some message in the field and submit from the keyboard. Press the Stop Client button to avoid any errors.
Go back to the ServerScreen you will be able to see the message that you typed in the ClientScreen.
Now, this is a minimal example of how to communicate between 2 devices through local network. But as you might be wondering, this app only lets us communicate between 2 screens right?
To be honest, thats true, we are only able to communicate between 2 screens so far using this application, but, the underlying mechanism we used to make it work is exactly same as what we would do in case of communication between 2 devices.
So, how to do it for different devices.
Lets say we have 2 device, namely A and B. We want to establish a connection between both of these device. Firstly, we will turn on the wifi hotspot of A, and will connect B to that wifi.
Now, on device A, we will go to the ServerScreen and start the server. On device B, go to ClientScreen and you will see "client is on" info appear, but if you type in some message in the textfield and submit, you wont be seeing any message appear on Device A, this is because to make it work, we need to change a little bit on the ClientScreen.js component file.
Change from =>
useEffect(async () => {
let ip = await NetworkInfo.getIPV4Address(); //await NetworkInfo.getGatewayIPAddress();
setClient(createClient(ip));
return () => {};
}, []);
to =>
useEffect(async () => {
let ip = await NetworkInfo.getGatewayIPAddress();
setClient(createClient(ip));
return () => {};
}, []);
What this does is, the IP that we want, to connect our device B to device A, is the IP of the Gateway of device B (Remember, we connected B to the hotspot of A).
That's it.
Now simply build again and follow the steps previously mentioned. Once you type in a message and submit it over the ClientScreen on B, you will be able to see it on ServerScreen of A.
Hope this helps anyone who is struggling with establishing a local socket connection between devices.
Note that, you can sure have multiple clients with a single server with some little behaviourial change on ServerScreen and this same codebase.
PS. I will make sure that I keep a check on this answer frequently so that any issue you face, you can comment and I can get back to you ASAP.
Edit: If you want to sent messages to the client system from the main system (hotspot), then you can follow this answer https://stackoverflow.com/a/73166697/9748372.
Yes You can share data between two devices but you mentioned
React-Native-Wifi-Hotspot
this library is helps to establish connection between two devices but not share anything (this lib just made for establish connection thats it)
then how i share the data?
1.you can share data with help of TCP and UDP
The major applications using TCP/UDP for file sharing and data communicaiton like shareit
Now You imagine exactly share it app
it has sender and reciever same way
sender is a client in tcp/udp
reciever is a server in tcp/udp
Now we see detail approach(server and client)
device one is server(just Imagine)
eg:
ip address 192.1.1.1
port: 6666
device two is a client
eg
ip address 192.2.2.2
port: 6666
sending data to server by ip address with port
Note:device 2 should know server ip and port thats it
Now we configure device one as server
npm i react-native-tcp
to know ip
npm i react-native-network-info
import { NetworkInfo } from "react-native-network-info";
// Get Local IP
NetworkInfo.getIPAddress().then(ipAddress => {
console.log(ipAddress);
});
// Get IPv4 IP (priority: WiFi first, cellular second)
NetworkInfo.getIPV4Address().then(ipv4Address => {
console.log(ipv4Address);
});
server setup only i added port(eg 6666)
let server = net.createServer((socket) => {
this.updateChatter('server connected on ' + JSON.stringify(socket.address()));
socket.on('data', (data) => {
this.updateChatter('Server Received: ' + data);
socket.write('Echo server\r\n');
});
socket.on('error', (error) => {
this.updateChatter('error ' + error);
});
socket.on('close', (error) => {
this.updateChatter('server client closed ' + (error ? error : ''));
});
}).listen("6666", () => {
this.updateChatter('opened server on ' + JSON.stringify(server.address()));
});
server.on('error', (error) => {
this.updateChatter('error ' + error);
});
server.on('close', () => {
this.updateChatter('server close');
});
client setup(i added manualy server ip address(192.1.1.1) and port(6666) ):
let client = net.createConnection(6666,192.1.1.1, () => {
this.updateChatter('opened client on ' + JSON.stringify(client.address()));
client.write('Hello, server! Love, Client.');
});
client.on('data', (data) => {
this.updateChatter('Client Received: ' + data);
this.client.destroy(); // kill client after server's response
this.server.close();
});
client.on('error', (error) => {
this.updateChatter('client error ' + error);
});
client.on('close', () => {
this.updateChatter('client close');
});
this.server = server;
this.client = client;
}
componentWillUnmount() {
this.server = null;
this.client = null;
}
thats it
then i come to your point
React-Native-Wifi-Hotspot
this library just helps to share ip address between devices then you establish tcp connection to communicate or share files between devices
Note:
file sharing possible with tcp ,udp , ftp , websocket,peer network and also over http
you can choose any one of above protocol to make file sharing application,extra tips ,you must learn about chunks and stream.(this helps you large file sharing)
i hope it may help you
You can use this library called React Native TCP which is able to send and receive data over wifi.
It is the node's net API in React Native.
It is almost identical to the node's net API and you can use net's documentation. And just a suggestion on how to do it would be that, You can set up a connection page consistent of two buttons for example. And then define a hotspot creating functionality for one and define a hotspot connecting functionality for another one.
I am working on HTML5 mobile app using jQuery mobile.
This is my code:
$(document).on("click","#send_mobile_number",function(){
var mobile = $('#mobile_number').val();
var user_id = sessionStorage.getItem("user_id");
$('.ui-loader').show();
$.ajax({
url: BASE_URL+'users/send_sms_code.php',
type: 'POST',
datatype: 'json',
data: "user_id="+user_id+"&mobile="+mobile+"&type=1",
async:false,
success: function (response) {
var data = jQuery.parseJSON(response);
$('.ui-loader').hide();
if(data.status == 'Fail') {
$('.very_mob_no_message').html('Sorry some error occurred,try again.');
}else{
$('#close_mob_popup').trigger('click');
setTimeout(function()
{
$('.click_mobile_verify').trigger('click');
}, 500);
$('#send_mobile_verify_span').hide();
$('#after_mobile_send_span').show();
$('#moble_number_div').hide();
$('#user_code_div').show();
$('#user_code').val(data.sms_code);
//alert(window.localStorage.getItem('mobile'));
//sessionStorage.setItem("mobile",mobile);
window.localStorage.setItem("mobile",mobile); // IT IS NOT WORKING
$('.very_mobile_message').html('Enter code which is <br/> sent to your mobile number.');
}
},
error: function (jqXHR, textStatus, errorThrown) {
//alert(jqXHR.status);
}
});
});
I want to store mobile number in session using window.localStorage.setItem("mobile",mobile);. It is working when I run on my browser but when I runt on mobile phone as APP it stop working. Why this happening. I am checking android phone.
Just use localStorage.mobile = "mobile". It's as simple as that. localStorage is a global object and can be accessed and manipulated as any other object. The only difference with regular objects is that it can store only strings.
You can then retrieve your value using alert( localStorage.mobile ); // will alert "mobile"
So finally found the solution, I need to set webSettings.setDomStorageEnabled(true); on android code and after this localstorage is working perfectlly.
Is it possible to communicate an android Application with cakePhp website and share data? If it is possible, I want to create an application that can login into the website; my doubt is:
How to pass user name and password from our application to cakephp websites login page? Can anybody show me an example program?
How cakephp controller handle this request and respond to this request? Please show me an example program?
(I am a beginner in android and cakephp.)
Quick answer -- YES!
We just finished pushing an Android app to the market place that does this exact thing. Here's how we did it:
1) Download and learn to use Cordova PhoneGap (2.2.0 is the latest version) within Eclipse. This makes the whole thing so much easier with just some HTML and a lot of Javascript.
2) In your JS, create methods that push the login information using AJAX parameters. Example:
document.addEventListener('deviceready', onDeviceReady, false);
function onDeviceReady() {
$("#login").click(function() {
$email = $("#UserEmail").val();
$pass = $("#UserPassword").val();
$.ajax({
url : yourURL + 'api/users/login',
async : false,
data : {
'email' : $email,
'password' : $pass
},
dataType : 'json',
type : 'post',
success : function(result) {
/**
* do your login redirects or
* use localStorage to store your data
* on the phone. Keep in mind the limitations of
* per domain localStorage of 5MB
*/
// you are officially "logged in"
window.location.href = "yourUrl.html";
return;
},
error : function(xhr, status, err) {
// do your stuff when the login fails
}
});
}
}
3) In Cake / PHP, your Users controller here will take the username and password data in the AJAX call and use that for its authentication.
<?php
class UsersController extends AppController {
public $name = 'Users';
public function beforeFilter() {
parent::beforeFilter();
$this->Auth->allow('api_login');
}
public function api_login() {
$this->autoRender = false;
if ($this->request->data && isset($this->request->data['email']) && isset($this->request->data['password'])) {
$arrUser = $this->User->find('all',array(
'conditions'=>array(
'email'=> $this->request->data['email'],
'password' => $this->Auth->password($this->request->data['password']),
)
)
);
if (count($arrUser) > 0) {
$this->Session->write('Auth.User',$arrUser[0]['User']);
// Do your login functions
$arrReturn['status'] = 'SUCCESS';
$arrReturn['data'] = array( 'loginSuccess' => 1,'user_id' => $arrUser[0]['User']['id'] );
} else {
$arrReturn['status'] = 'NOTLOGGEDIN';
$arrReturn['data'] = array( 'loginSuccess' => 0 );
}
} else {
$arrReturn['status'] = 'NOTLOGGEDIN';
$arrReturn['data'] = array( 'loginSuccess' => 0 );
}
echo json_encode($arrReturn);
}
}
?>
That's pretty much it. You are now authenticated to CakePHP.
You do not need to use "api_", you can use any function name you want, but this helped us keep a handle on what we allowed mobile users to do versus web users.
Now, these are just the building blocks. You basically have to create a whole version of your site on the phone using HTML and Javascript, so depending on your application it may be easier just to create a responsive design to your site and allow mobile browsing.
HTH!
Use Admad JWT Auth Plugin
If you use cakephp3 change your login function with this one :
public function token() {
$user = $this->Auth->identify();
if (!$user) {
throw new UnauthorizedException('Invalid username (email) or password');
}
$this->set([
'success' => true,
'data' => [
'token' => JWT::encode([
'sub' => $user['id'],
'exp' => time() + 604800
],
Security::salt())
],
'_serialize' => ['success', 'data']
]);
}
You can read this tutorial about REST Api and JWT Auth Implementation
http://www.bravo-kernel.com/2015/04/how-to-add-jwt-authentication-to-a-cakephp-3-rest-api/
if rebuild most of the view pages in cakephp into ajax will seem defeat the purposes of using cakephp as it is.
I'm trying to find the best way to send my users a real-time status update of a process that's running on my server - this process is broken up into five parts. Right now I'm just 'pulling' the status using an Ajax call every few seconds to a PHP file that connects to MySQL and reads the status, but as you can imagine, this is extremely hard on my database and doesn't work so well with users that don't have a strong internet connection.
So I'm looking for a solution that will 'push' data to my client. I have APE push-engine running on my server now, but I'm guessing Socket.IO is better for this? What if they're on 3G and they miss a status update?
Thanks in advance :)
I guess my answer may match what you need.
1st: You Have to Get Node.js to run the socket.io
BELOW IS SAMPLE CODE FOR SERVER:
var app = require('http').createServer(handler)
, io = require('socket.io').listen(app)
, fs = require('fs')
app.listen(8800); //<---------Port Number
//If No Connection / Page Error
function handler (req, res) {
fs.readFile(__dirname + '/index.html',
function (err, data) {
if (err) {
res.writeHead(500);
return res.end('Error loading index.html');
}
res.writeHead(200);
res.end(data);
});
}
//If there is connection
io.sockets.on('connection', function (socket) {
//Set Varible
var UserID;
var Old_FieldContent = "";
socket.on('userid', function (data) {
if(data.id){
UserID = data.id;
StartGetting_FileName(UserID)
}
});
//Checking New Status
function StartGetting_FileName(UserID){
//Create Interval for continues checking from MYSQL database
var myInterval = setInterval(function() {
//clearInterval(myInterval);
//MySQL Connection
var mysql = require('mysql');
var connection = mysql.createConnection({
host : 'localhost',
port : '3306',
user : 'root',
password : 'ABCD1234',
database : 'test',
});
//Setup SQL Query
var SQL_Query = "SELECT FileName FROM status WHERE UserID = '"+UserID+"'";
connection.connect();
connection.query(SQL_Query, function(err, rows, fields) {
//Do if old result is, different with new result.
if(Old_FieldContent !== rows[0].FileName){
if (err) throw err;
//Display at Server Console
console.log('------------------------------------------');
console.log('');
console.log('Fields: ', fields[0].name);
console.log('Result: ', rows[0].FileName);
console.log('');
console.log('------------------------------------------');
//Send Data To Client
socket.emit('news', { FieldName: fields[0].name });
socket.emit('news', { FieldContent: rows[0].FileName });
//Reset Old Data Variable
Old_FieldContent = rows[0].FileName;
}
});
connection.end();
}, 500 );
}
});
BELOW IS CLIENT HTML & JS:
<!doctype html>
<html>
<head>
<title>web sockets</title>
<meta charset="utf-8">
<!-- URL PATH TO LOAD socket.io script -->
<script src="http://15.17.100.165:8800/socket.io/socket.io.js"></script>
<script>
//Set Variable
var UserID = "U00001";
var socket = io.connect('http://15.17.100.165:8800');
var Field_Name = "No Data";
var Field_Content = "No Data";
// Add a disconnect listener
socket.on('connecting',function() {
msgArea.innerHTML ='Connecting to client...';
console.log('Connecting to client...');
//Once Connected Send UserID to server
//for checking data inside MYSQL
socket.emit('userid', { id: UserID });
});
// Get data that push from server
socket.on('news', function (data) {
console.log(data);
writeMessage(data);
});
// Add a disconnect listener
socket.on('disconnect',function() {
msgArea.innerHTML ='The client has disconnected!';
console.log('The client has disconnected!');
});
//Function to display message on webpage
function writeMessage(msg) {
var msgArea = document.getElementById("msgArea");
if (typeof msg == "object") {
// msgArea.innerHTML = msg.hello;
if(msg.FieldName !== undefined){
Field_Name = msg.FieldName;
}
if(msg.FieldContent !== undefined){
Field_Content = msg.FieldContent;
}
}else {
msgArea.innerHTML = msg;
}
msgArea.innerHTML = Field_Name +" = "+ Field_Content;
}
</script>
</head>
<body>
<div id="msgArea">
</div>
</body>
</html>
You should consider using push notifications, with the service provided for Android by Google as C2DM: https://developers.google.com/android/c2dm/
You will need to implement a PhoneGap plugin to handle the native notifications, and communicate them to your PhoneGap project that will then (and only then) query your server .
As K-ballo above points out, using a push notification plugin would be best.
Luckily, some good citizen on GitHub has done this already!
https://github.com/awysocki/C2DM-PhoneGap
Please note: the above C2DM plugin was built for PhoneGap v1.2, so if you are running a more up-to-date version you will have to tweak the native code a bit to get it working better.