can't connect to socket io in production - angularjs

I can't connect to socket.io in production. It works fine in my dev server, but I'm not getting the "websocket user connected" message in the console in production and my heat map isn't populating with the test data. I'm getting net:: ERR_CONNECTION_TIMED_OUT in the browser jscript console.
from the server:
io.origins('http://example.com/path:8080')
app.get('/somepath', function (req, res, next) {
// code here
io.emit('update', data)
console.log('update has been emitted') // this prints and I see the data object in the console
res.end("OK")
})
io.on('connection', function (socket) {
console.log('websocket user connected')
});
from the angular controller:
$http.get('http://example.com/somepath?'+str) // hits somepath with test data in query string 'str'
from the script in /path:
var socket = io('http://example.com:8080');
and I've also included the cdn for socket.io in the page /path
<script src="https://cdn.socket.io/socket.io-1.3.2.js"></script>

The problem was that I had to include to port number in the URL for the development server, but it will not make the connection if I use the port in my production server. I'm not sure exactly why this is, but I suppose that the port is implied in a request from my browser and maybe something about the format makes it unrecognizable if explicitly stated.
Changes I made:
I removed the io.origins statement from the server because the default for socket.io is to allow any origin. That removes one possible source of error.
I removed the port number from $http.get() in the angular controller and changed var socket = io('http://example.com:8080') to var socket = io('http://example.com') in another script

Related

how nodejs build webserever in frontend for fraework for react and angular

I am new to web development and slowly understanding the web process . I want to know which how nodejs helps to build webserver in frontend ? for react applications npm start --> react-scripts start which runs application in localhost .here where exactly it create webserver and executes in localhost
An application can have front end and back end. A ReactJs application can be the front end for example, and nodeJs can be the back end. The back end will offer the server and will communicate with the database.
So, concretely, you will have 2 different projects: client and server. The client project will be your ReactJS application. The server project will be the NodeJS server. You create each one separetly.
A server can be accessed by paths, for example
http://my-server.localhost/login
http://my-server.localhost/logout
http://my-server.localhost/users
So, a basic connection between client and server can be based on the url paths, so in your client project you can do:
window.location.href = "http://my-server.localhost/login";
to call the login service from the server. And then, in your server, you can redirect to a client's url path.
BUT: the best way (for me) to establish connection between client and server is by using socket.
Socket is very simple, your client can emit requests to the server, and vice-versa:
socket.emit('hello', data);//where data can be any type of object, a string for example..
Similarly, the server can also emit requests to the client:
socket.emit('welcom', new_data);
Then, in the server and the client, you should hear for each request. Finally the code can be something like this:
Client side:
socket.emit('hello', data);// I will say 'hello' message (request) to the server..
socket.on('welcome', (data, callback) => {//I will hear to 'welcome' message(request) from the server..
console.log('server emited welcome with data =>', data);
});
Server side:
socket.on('hello', (data, callback) => {//I will hear to 'hello' message(request) from the client..
console.log('client emited hello with data =>', data);
socket.emit('welcome', ':)');//I will say(reply) 'welcome' to the client..
});
Hope this helps you to understand the concept.

AngularJS - Request to localhost server fail

I have made an api end point using express.
Now im trying to get the data from my localhost server that is running on port 3010.
$scope.getBooks = function(){
$http.get('/api/books').then(function(resp){
$scope.books = resp;
});
}
The function is working good because i can test whit the JSONPlaceholder.com.
I cannot get my data, im using gulp on port 3002 and my server is in port 3010, he is running and working good, i can see my data using postman.
why can i get my data from the localhost server ?
Thank You
This issue happens because the API endpoint you are accessing does not implement CORS. If you run your code in Chrome and look at the console, you will see an error:
XMLHttpRequest cannot load .....
The solution is to change the API endpoint to set the Access-Control-Allow-Origin header to either the wildcard * or to the domain where the page using the JavaScript code will be served from.
For More Details on CORS
To prevent websites from tampering with each other, web browsers implement a security measure known as the same-origin policy. The same-origin policy lets resources (such as JavaScript) interact with resources from the same domain, but not with resources from a different domain. This provides security for the user by preventing abuse, such as running a script that reads the password field on a secure website.
If your site is on port 3002 and your server is on port 3010 then you must specify the URL of the entire server's location
$scope.getBooks = function(){
$http.get('http://localhost:3010/api/books').then(function(resp){
$scope.books = resp;
});
}
Specify the entire url in AngularJS code and use CORS middleware in the express backend.
https://github.com/expressjs/cors
This is bad way of doing front end(AngularJs) and backend development parallely on local on same machine. Try to fit Front-end repository to be hosted by BE server and use it in following way :
If you are doing FE development locally and backend server is also hosted locally.
use following line as common baseUrl
var baseUrl = "//" + window.location.host +'/'
Doing so, you don't need to update while committing changes to prod environment.
$scope.getBooks = function(){
var _url = baseUrl + '/api/books'
$http.get(_url).then(function(resp){
$scope.books = resp;
});
}
Above code works in case of same server FE and BE.
If you have different servers locally , you need to work more with setting :
You can use express-http-proxy
var proxy = require('express-http-proxy');
app.use('/api/', proxy('http://localhost:3010'));
In higher of version of angular 4+ , we have such setting as in initial configuration.
READ ARTICLE :
https://juristr.com/blog/2016/11/configure-proxy-api-angular-cli/
You cannot just write /api/books. You need to specify your port number of API running on localhost.
In your case localhost:3010/api/books

How can I emit socket event from my clientside controller in daftmonks angular fullstack?

I am using Daftmonk's angular-fullstack, and I want to send data through sockets TO the server. I found examples of how to receive from the server but not the other way around. The socket factory in the package doesn't seem to support any emit functions. So do I need to modify the socket service file to get that functionality or is there a better way?
first you need to require the socket.js file in script .js
i have installed it via bower and then in the controller create an instance of the socket like
var socket = io.connect('http://localhost:4000');
this connects the socket to server and then you can emit the events from the controller like
socket.emit("<event name>")
and listen that event on the server and you need an socket innstance attached to server if not then npm install socket and then require it and then attach it to the app
the server side is:
var server = require('http').createServer(app);
var io = require('socket.io').listen(server);
io.sockets.on('connection', function(socket){ console.log('a user connected'); })
server.listen(4000,function(){ console.log("The server running at port 4000"); });

Express Server, calling state.go and running a method in Controller

I am currently running an express server express.js with an angular js app. I use the UI router https://github.com/angular-ui/ui-router with stateprovider and state.go.
I have a requirement to allow a url to be typed in the browser
/getEmployeeDetails/1234
Am i going along the right lines , in that the following code can be added to the express server.js to achieve this or should I be handling this in the angular app states.
app.get('/p/:empId', function(req, res) {
controller.getEmpDetaails(req.params.empId);
state.go("employeeDetailsview")
});
I am not sure what was the reason for writing angular code inside your Express server but you should really separate your client code from your server code.
I assume you are trying to get some employee details by ID from your server.
The way it is usually done is by sending a HTTP request with the ID number from your client to the server. Then, the server will process the HTTP request (Maybe get some data from the database) and return a HTTP response to the client. And then the client will process the response and do something with it.
In your client yo can do something like this:
$http.post('SERVER_URL/getEmployeeDetails/', {'id': 1234})
.then(function(response){
// Response.data will have the data returned from the server
// Do something with it. for example, go to other state and pass the data to it
state.go("employeeDetailsview", {'employee': response.data});
});
The above will request an employee with id 1234 and do something with it.
In the server side:
app.post('getEmployeeDetails/', function(req, res) {
var employeeId = req.body.id; // YOU SHOULD USE THE BODY-PARSER MODULE IN ORDER FOR THIS TO WORK.
....
// Do something with ID
....
// Return some data to the client - for example an employee object
res.status(200).json({'data': employeeObject});
});

Node application Primus client's emitted data not received by Primus server

I have an AngularJS application as a Primus client and it is able to connect to the Primus server and emit to the Primus server too without any issues.
I built a new NodeJS application but acts as a Primus client. It's on the same machine as my Primus server. This is the code that I use to connect to the Primus server. It is able to connect to it as I see the hash generated when it connects.
var http = require('http'),
server = http.createServer(),
Primus = require('primus'),
primus = new Primus(server, { transformer : 'sockjs' }),
Socket = primus.Socket;
var client = new Socket('http://192.168.1.50:7777');
// prmius.use('emit', require('primus-emit'));
// client.use('emit', require('primus-emit'));
// primus.emit('motion-sensor-on', { isActive : true, area : 'living-room', src : 'node' });
client.emit('motion-sensor-on', { isActive : true, area : 'living-room', src : 'node' });
The client.emit gets executed but the Primus server doesn't receive it. It's on the same machine. I'm going to mention it again that when I start the node application, it is able to connect to the primus server. Previously, I first tried primus.emit but my primus server is unable to receive it too.
I finally got it working!!!
Well, I just added a new listener and event name 'data'. Looks like if you are emitting from the server as client using socket or client.write, you should not specify an event name. So my latest working code on the server acting as a client is
client.write({ isActive : true, area : 'living-room', src : 'node' });
then on the primus server, the code is
spark.on('data', function(data) {
console.log(spark.id, 'received message:', data);
primus.write(data);
});
I'm honestly not sure why custom event names works when using it in browsers but not when you are sending from inside your NodeJS app. That sucks! Maybe, I missed a code. Not sure! Anyways, I am now able to see the motion sensor changing from my browser and phone.

Resources