Unable to establish connection between Node.JS and React-Native (Socket.IO) - ios

I'm new to React and Node and i'm trying to make a simple WebSocket using Socket.IO which gonna simply send greetings to all connected users and the user will respond to the server.
The Node.JS server is running on a Windows PC while the React-Native app is running on both iOS and Android devices.
Node.JS server code is the following
var app = require('express')();
var http = require('http').createServer(app);
var io = require('socket.io')(http);
const bodyParser = require('body-parser');
const mysql = require('mysql');
const connection = mysql.createPool({
host : 'localhost',
user : 'root',
password : 'block',
database : 'visualpos'
});
// Creating a GET route that returns data from the 'users' table.
app.get('/prenotazioni', function (req, res) {
// Connecting to the database.
connection.getConnection(function (err, connection) {
// Executing the MySQL query (select all data from the 'users' table).
connection.query("SELECT Data, Importo_Doc FROM tabella_pagamenti", function (error, results, fields) {
// If some error occurs, we throw an error.
if (error) throw error;
// Getting the 'response' from the database and sending it to our route. This is were the data is.
res.send(results)
});
connection.release();
});
});
app.get('/', function(req, res){
res.send('<h1>Hello World</h1>');
});
// Starting our server.
http.listen(3000, () => {
console.log('In ascolto sulla porta *:3000');
});
io.emit('saluta', 'Ciao dal server :)');
io.on('connected', (data) => {
console.log(data);
});
Actually GET part of the code works perfectly but the Socket.IO seems death.
The client doesn't get any response and server the same i think the Socket.IO server simply doesn't start..
In XCode Debug i get the following errors when the app is running on the iPhone
And i even get on both devices warning "Unrecognized WebSocket connection option(s) 'agent', 'perMessageDeflate',..."
And here is the code i'm using in React-Native
import io from 'socket.io-client'
var socket = io('http://192.168.100.50:3000', {
jsonp: false,
transports: ['websocket'],
autoConnect: true,
reconnection: true,
reconnectionDelay: 500,
reconnectionAttempts: Infinity
});
componentDidMount(){
socket.emit('connected','we');
socket.on('saluta',(data) => { alert(data); });
}

On socket.io getStarted section, they use a "connection" event instead of "connected" (https://socket.io/get-started/chat/).
io.on('connection', function(socket){
console.log('a user connected');
socket.on('disconnect', function(){
console.log('user disconnected');
});
});

Related

Ionic 5 - API request working on browser, not on emulated IOS

I have this Ionic 5/Capacitor app, which I'm making an API call to a local server from, that server running on docker at localhost:3000. When I test from the browser, the request is made fine. From Postman it requests fine, too. In my XCode logs the emulator, I see this
[error] - ERROR {"headers":{"normalizedNames":{},"lazyUpdate":null,"headers":{}},"status":0,"statusText":"Unknown Error","url":"http://localhost:3000/pins","ok":false,"name":"HttpErrorResponse","message":"Http failure response for http://localhost:3000/pins: 0 Unknown Error","error":{"isTrusted":true}}
The really interesting part, is that I'm running Fiddler to monitor the request as it's made. Fiddler gets a 200 as well, I can even see the response data. So, Fiddler sees the proper network call, but then my Ionic app gets that error. That makes me feel like it's an Ionic/Emulator/IOS problem, but I don't have enough familiarity with Ionic to know right off the bat what it is.
Here's the code responsible for making the request:
ngOnInit() {
const request = this.http.get('http://localhost:3000/pins');
this.refresh$.subscribe(
(lastPos: { latitude?: any; longitude?: number }) => {
request.subscribe(data => {
if (data) {
this.addMarkersToMap(data, lastPos);
}
});
}
);
}
And the HTTPClient imported in the constructor is from Angular:
import { HttpClient } from '#angular/common/http';
I ended up having to use this package, doing a check on if I'm on mobile or not.
https://ionicframework.com/docs/native/http/
Try with this :
const request = this.http.get('http://localhost:3000/pins', { observe: 'response', withCredentials: true });
Solution 2 : capacitor.config.json
"server": {
"hostname": "localhost", (maybe try precising the port number too)
}
Solution 3 : On your Express server (from https://ionicframework.com/docs/troubleshooting/cors)
const express = require('express');
const cors = require('cors');
const app = express();
const allowedOrigins = [
'capacitor://localhost',
'ionic://localhost',
'http://localhost',
'http://localhost:8080',
'http://localhost:8100'
];
// Reflect the origin if it's in the allowed list or not defined (cURL, Postman, etc.)
const corsOptions = {
origin: (origin, callback) => {
if (allowedOrigins.includes(origin) || !origin) {
callback(null, true);
} else {
callback(new Error('Origin not allowed by CORS'));
}
}
}
// Enable preflight requests for all routes
app.options('*', cors(corsOptions));
app.get('/', cors(corsOptions), (req, res, next) => {
res.json({ message: 'This route is CORS-enabled for an allowed origin.' });
})
app.listen(3000, () => {
console.log('CORS-enabled web server listening on port 3000');
});

'Signal R' client side .js not receiving any response from server

I wrote a script which is working as expected.But sometimes it doesn't get any response from server side which is very confusing ,because I've debugged the application several times but no exceptions and errors occurred while the connection id remain constraint.Can anyone please help me out what is actually happening?
$(function() {
$.connection.hub.url = '#Url.Content("~/signalr")';
var Hub = $.connection.chatHub;
$.connection.hub.start({ transport: ["webSockets", "longPolling", "serverSentEvents","foreverFrame"] })
.done( function() { Hub.server.register(); })
.fail(function(){ console.log('Could not connect'); });
$.connection.hub.logging = true;
$.connection.hub.error(function (err) { console.log("Error Signal R:" + JSON.stringify(err)); });
Hub.client.onBrodcast = function (id, msg) { $('body #chat_show_').prepend($.trim(msg)); };
});

$http.post cannot find issue

Good afternoon everyone.
I'm working on a school project to create an application using the MEAN stack, and I'm having issues with routing.
I'm using the login-and-register application found here as a base for my work : http://jasonwatmore.com/post/2015/12/09/mean-stack-user-registration-and-login-example-tutorial
Basically, I am unable to post data that I get from a form I created to my database.
If I get the creation part to work, then I'll be able to continue working on my project. Here is the code :
The Controller
(function () {
'use strict';
function Controller(UserService, NoteService, FlashService) {
var vm = this;
vm.note = null;
function createNote() {
NoteService.Create(vm.note, vm.user)
.then(function () {
FlashService.Success('Note created');
})
.catch(function (error) {
FlashService.Error(error);
});
}
vm.createNote = createNote;
function initController() {...}
initController();
}
angular.module('app').controller('Home.IndexController', Controller);
}());
And then we have the service I'm calling, NoteService
(function () {
'use strict';
function Service($http, $q) {
var service = {};
function Create(note, user) {
return $http.post('/api/notes', note).then(handleSuccess, handleError);
}
service.Create = Create;
return service;
}
angular
.module('app')
.factory('NoteService', Service);
}());
This is the $http.post function that doesn't work : /api/notes cannot be found (error 404 on browser console) I am sure my object note is getting at least to this request, because adding a console.log(note) just before returns what I want in the console.
On the server side, I have another controller for handling errors :
var noteService = require('services/notes.service');
//routes
router.post('/create', createNote);
module.exports = router;
function createNote(req, res) {
noteService.create(req.body)
.then(function () {
res.sendStatus(200);
})
.catch(function (err) {
res.status(400).send(err);
});
}
the service on the server side to discuss with the data base :
var mongo = require('mongoskin');
var db = mongo.db(config.connectionString, { native_parser: true });
db.bind('notes');
var service = {};
service.create = create;
module.exports = service;
function create(noteParam, userParam) {...}
and my server.js file looks like this :
require('rootpath')();
app.set('view engine', 'ejs');
app.set('views', __dirname + '/views');
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(session({ secret: config.secret, resave: false, saveUninitialized: true }));
// use JWT auth to secure the api
app.use('/api', expressJwt({ secret: config.secret }).unless({ path: ['/api/users/authenticate', '/api/users/register'] }));
// routes
app.use('/login', require('./controllers/login.controller'));
app.use('/register', require('./controllers/register.controller'));
app.use('/app', require('./controllers/app.controller'));
app.use('/api/users', require('./controllers/api/users.controller'));
app.use('/api/notes', require('./controllers/api/notes.controller'));
// make '/app' default route
app.get('/', function (req, res) {
return res.redirect('/app');
});
// start server
var server = app.listen(3000, function () {
console.log('Server listening at http://' + server.address().address + ':' + server.address().port);
});
I thought this line in the server.js file : app.use('/api/notes', require('./controllers/api/notes.controller'))
would permit my post request to send my note object to the server side, to '/api/notes') but I'm not quite sure how all this works together.
I am hoping anyone can help me, even though the code I gave was lengthful.
I am just beginning with MEAN and have no idea what I'm doing wrong.
Thanks in Advance for your answer.

Socket.io client not working properly

I have created chat application using following
Rails
Rabbitmq
nodejs ( with amqplib/callback_api and socket.io )
I have following code in server side
var amqp = require('amqplib/callback_api');
var amqpConn = null;
var app = require('http').createServer()
var io = require('socket.io')(app);
var fs = require('fs');
io.on('connection', function (socket) {
socket.emit('news/1', msg.content.toString());
// socket.disconnect()
});
client side
<%= javascript_include_tag "http://localhost:53597/socket.io/socket.io.js" %>
<script>
var socket = io('http://localhost:53597', {reconnect: true});
socket.on('connect', function () {
console.log('connected');
socket.on('news/1', function (msg) {
console.log('inside coming');
console.log(msg);
});
});
</script>
When I send message, message successfully pushed to queue and messages emitted to socket. The problem is I can get messages when only refresh page and messages are not deleted.
I can't understand what was wrong here ?
Eventually I fixed my issue, the problem is I have placed emit function inside connection event, so that I can get data when only connection established​, connection is established when page load that is the reason I get data when only page load.
I have the following code for emit data
io.sockets.emit('news/1', msg.content.toString());

socket.io can't handle errors

I'm trying to make real time application with node.js and socket.io. As I can see the server can see when new user connects but can't return information to client side or something. This is what I've on client side:
<script src="<?= base_url('assets/js/socket.io.js') ?>"></script>
<script>
var socket;
socket = io('http://***.***.***.***:3030', {query: "key=key"});
socket.on('connect', function (data) {
console.log('Client side successfully connected with APP.');
});
socket.on('error', function (err) {
console.log('Error: ' + err);
});
</script>
and this is the server side:
var app = require("express")();
var http = require("http").createServer(app);
var io = require("socket.io")(http);
http.listen(3030, function () {
globals.debug('Server is running on port: 3030', 'success');
});
io.set('authorization', function (handshakeData, accept) {
var domain = handshakeData.headers.referer.replace('http://', '').replace('https://', '').split(/[/?#]/)[0];
if ('www.****.com' == domain) {
globals.debug('New user connected', 'warning');
} else {
globals.debug('Bad site authentication data, chat will be disabled.', 'danger');
return accept('Bad site authentication data, chat will be disabled.', false);
}
});
io.use(function (sock, next) {
var handshakeData = sock.request;
var userToken = handshakeData._query.key;
console.log('The user ' + sock.id + ' has connected');
next(null, true);
});
and when someone comes to website I'm expecting to see in console output "New user connected" and I see it: screen shot and the user should see on the browser console output: "Client side successfully connected with APP." but I doesn't show. Also I tried to emit data to user but it doesn't work too. I can't see any errors or something. This is not the first time I'm working with sockets but the first time facing such as problem. Maybe there is any error reporting methods to handle errors or something? Also I can't see output on io.use(....) method
The solution is to pass "OK" sign just after authenticating to do the next method:
io.set('authorization', function (handshakeData, accept) {
var domain = handshakeData.headers.referer.replace('http://', '').replace('https://', '').split(/[/?#]/)[0];
if ('www.****.com' == domain) {
globals.debug('New user connected', 'warning');
accept(null, true);
} else {
globals.debug('Bad site authentication data, chat will be disabled.', 'danger');
return accept('Bad site authentication data, chat will be disabled.', false);
}
});

Resources