How to write and test dynamic server for Office.js add-in? - node.js

I'm developing an Office.js add-in for Excel, and I'm kind of lost on how to create the server side of the application and test it on localhost.
I've created the add-in project/structure using Yo Generator, and I'm using gulp to test it on localhost (port:8443). Using this approach, I was able to successfully load my add-in and test the client-side of the same. Also, I've tested a http request to a static json file and it worked fine.
The issue is that I need to run code on server side for dealing with files and doing some processing, and I simply can't find a way to do that.
I've already tried to start a localhost server on a different port (port:8000) using the code bellow and node command:
var https = require('https');
var fs = require('fs');
var httpsOptions = {
key: fs.readFileSync('key.pem'),
cert: fs.readFileSync('cert.pem')
};
var app = function (req, res) {
res.writeHead(200);
res.end("hello world\n");
}
https.createServer(httpsOptions, app).listen(8000);
The server started ok, but as my application is running on port:8443, I'm unable to do cross origin requests (which I understand would also not work on a production environment).
I also tried to start add-in server on port:8443 using gulp serve-static command, and then start a server listening on the same port:8443 using node command, but this results on the error bellow:
Error: listen EADDRINUSE 127.0.0.1:8443
at Object.exports._errnoException (util.js:870:11)
at exports._exceptionWithHostPort (util.js:893:20)
at Server._listen2 (net.js:1234:14)
at listen (net.js:1270:10)
at net.js:1379:9
at GetAddrInfoReqWrap.asyncCallback [as callback] (dns.js:64:16)
at GetAddrInfoReqWrap.onlookup [as oncomplete] (dns.js:83:10)
May someone please help on how to get this working?
Please let me know if any further information is required.
Thanks in advance.

First, you can't have two servers listening on the same port simulateneously. That's why you're getting the Address in Use error.
Second, I am in a similar situation like you and my thinking here was, that the way to go would be writing a server that provides an API (e.g. REST). Then, the javascript code that get's loaded into office (for starters the App.js in your yo office generated project) makes requests to this API.

Related

Express website hosted on Azure giving unexpected error

I'm running very simple express website on Azure shared resource in Australia Southeast region. Website run locally on port 3000 however when deployed to Azure doesnt render at all. When try to run from Azure throws below error
node server.js
events.js:141
throw er; // Unhandled 'error' event
Error: listen EADDRINUSE 0.0.0.0:3000
at Object.exports._errnoException (util.js:874:11)
at exports._exceptionWithHostPort (util.js:897:20)
at Server._listen2 (net.js:1234:14)
at listen (net.js:1270:10)
at Server.listen (net.js:1366:5)
at EventEmitter.listen (D:\home\site\wwwroot\node_modules\express\lib\application.js:617:24)
at Object.<anonymous> (D:\home\site\wwwroot\server.js:21:5)
at Module._compile (module.js:435:26)
at Object.Module._extensions..js (module.js:442:10)
at Module.load (module.js:356:32)
Server.js looks like
var express = require('express');
var app = express();
var path = require("path");
var port = process.env.PORT || 3000;
console.log(__dirname);
app.use(express.static('public'));
app.get('/', function (req, res) {
res.sendFile(path.join(__dirname+'/index.html'));
});
app.get('/contact', function (req, res) {
res.sendFile(path.join(__dirname+'/contact.html'));
});
app.listen(port, function () {
console.log('Example app listening on port!' + port);
});
Not sure what am I missing?
Thanks
Azure website allows hosting of node.js application via IIS module called iisnode. Please see the wiki for iisnode to know it.
Especially note the content below.
Minimal changes to node.js application code. The iisnode module enables hosting of existing HTTP node.js applications with very minimal changes. Typically all that is required is to change the listed address of the HTTP server to one provided by the iisnode module via the process.env.PORT environment variable.
So you don't need to start up the node app via command node server.js manually in Kudu Console. Please try to only deploy or update the code via FTP or VS, and directly access the website to check the deployment successfully. You can try to restart the application on Azure portal if it not works.
If you want to check the running process, you can see them in the Process explorer of Kudu tool, please see the figure below.
Any concern, please feel free to let me know.
Ok,
This may be due to you have already running an instance of node on 3000.
go to terminal interface using ssh connection to your server.invoke this command.
ps -ax | grep Server.js
a list of running process will be there like
get 1257 from there and on terminal
kill 1257
now try to run your server again.
It means the port you are trying to bind the server to is in use. Try another port or close the program using that port on azure.

Issue with HTTP request using node through TOR

I am relatively new to both node and TOR. I'm trying to send a request using a node application through TOR. Ive set up a basic app using socks5-HTTP-client. Also, TOR is installed (sudo port install tor) and I ran the server using tor..
Executing the app, node gives me the following error
Error: SOCKS connection failed. General SOCKS server failure.
at Socket.<anonymous> (/Users/MyName/node_modules/socks5-client/lib/Socket.js:199:12)
at Socket.g (events.js:260:16)
at emitOne (events.js:77:13)
at Socket.emit (events.js:169:7)
at readableAddChunk (_stream_readable.js:146:16)
at Socket.Readable.push (_stream_readable.js:110:10)
at TCP.onread (net.js:523:20)
The TOR server reports the following to me:
[warn] Rejecting SOCKS request for anonymous connection to private address [scrubbed].
The topic I found here does not seem to apply to this case. Also, this earlier article does not answer my question. Neither can I find any difference between the example given by the developer of the socks5 module and my case.
I am unsure whether this is an issue with my configuration in node or my TOR configuration.
Below is the JS code
var shttp = require('socks5-http-client');
var config =
{ url: 'http://whatismyipaddress.com/', // I'd like to see a different IP on every request, that should be the end result, correct?
socksHost: '127.0.0.1',
socksPort: 9050
}
shttp.get(config, function(res) {
res.setEncoding('utf8');
res.on('readable', function() {
console.log(res.read());
});
});
Also, in my torrc.sample configuration file, I made sure the following is set up:
SOCKSPort 127.0.0.1:9050
Also, my SOCKSPolicy is set up as follows:
SOCKSPolicy accept 192.168.0.0/16
SOCKSPolicy accept6 FC00::/7
SOCKSPolicy reject *
At the time of trying, my internal IP address was 192.168.0.11, seems fine to me.
Any help would be appreciated!
You are getting that error because the URL isn't getting passed to the request properly so it is trying to issue a SOCKS request to localhost instead of the site you want to visit.
URLs are parsed using url.parse.
Try changing your code to:
var shttp = require('socks5-http-client');
var url = require('url');
var config = url.parse('http://whatismyipaddress.com/');
config.socksHost = '127.0.0.1';
config.socksPort = 9050;
shttp.get(config, function(res) {
res.setEncoding('utf8');
res.on('readable', function() {
console.log(res.read());
});
});
Also, it appears whatismyipaddress.com might be blocking Tor as I don't get a response back from them. Try ipchicken.com or some other site. You may need to set a User-Agent header to get the former site to reply, but this code change does work.

Openshift Zombiejs

I have a Node.js/Express application which I'm trying to deploy to Openshift.
The server itself starts up properly and serves almost everything.
One request to the server opens up a Zombiejs browser, which then crawls some webpages.
When the browser tries to visit a webpage however, I get this error:
{ [Error: bind EACCES] code: 'EACCES', errno: 'EACCES', syscall: 'bind' }
Possibly unhandled Error: bind EACCES
at errnoException (net.js:901:11)
at connect (net.js:747:21)
at net.js:842:9
at asyncCallback (dns.js:68:16)
at Object.onanswer [as oncomplete] (dns.js:121:9)
The browser fails as soon as I call visit:
browser.visit(menus_url).then(function () {
// do things
});
Before doing the above, I start an Express-based server as follows:
var server_port = process.env.OPENSHIFT_NODEJS_PORT || 8080;
var server_ip_address = process.env.OPENSHIFT_NODEJS_IP;
app.listen(server_port, server_ip_address, function() {
console.log('Server running on port ' + server_port);
});
The server starts up fine, however as soon as I make a request that calls browser.visit() the error is raised.
Update 11/15
I still haven't found a solution to this issue.
When the browser is created, it tries to use the ip address of 0.0.0.0 to bind to (https://github.com/assaf/zombie/blob/master/src/zombie/browser.coffee#L1224) by default, which is not available on OpenShift for your use, you need it to bind to your OPENSHIFT_NODEJS_IP ip address, just like you use for your express server. It looks like, at the top of the file that I linked to (https://github.com/assaf/zombie/blob/master/src/zombie/browser.coffee#L42), that one of the Browser options you can pass in is 'localAddress' when creating the Browser object, which should be the OPENSHIFT_NODEJS_IP. I think that will get it fixed up for you.

socket.io on openshift with angular-fullstack

I generated a node.js app using Yeomans angular-fullstack generator.
Everything worked fine except the use of socket.io. After uploading my app to openshift using angular-fullstack:openshift, I got informed that I have to:
Openshift websockets use port 8000, you will need to update the client
to connect to the correct port for sockets to work.
in /client/app/components/socket/socket.service: var ioSocket = io.connect('http://my-domain.rhcloud.com/:8000')"
I dont know where to do this. I am using socket.io version 1.0.6 which is shown inside package.json file.
==> app-root/logs/nodejs.log <==
/var/lib/openshift/xxx/app-root/runtime/repo/server/config/socketio.js:41
socket.address = socket.handshake.address.address + ':' +
^
TypeError: Cannot read property 'address' of null
at Namespace. (/var/lib/openshift/xxx/app-root/runtime/repo/server/config/socketio.js:41:46)
at Namespace.EventEmitter.emit (events.js:95:17)
at Namespace.emit (/var/lib/openshift/xxx/app-root/runtime/repo/node_modules/socket.io/lib/namespace.js:205:10)
at /var/lib/openshift/xxx/app-root/runtime/repo/node_modules/socket.io/lib/namespace.js:172:14
at process._tickCallback (node.js:415:13)
DEBUG: Program node server/app.js exited with code 8
DEBUG: Starting child process with 'node server/app.js'
By the way, the app, including socket.io, works fine on my local development machine!
Thanks for any help!
Fall.Guy
My working solution is now:
I changed the creation of the openshift app to "not create a scalable app" (I disabled the -s switch in the yo angular-fullstack:openshift command)
After that, I changed the connection of socket.io to:
var ioSocket = io('http://my-domain.rhcloud.com:8000', {
// Send auth token on connection, you will need to DI the Auth service above
// 'query': 'token=' + Auth.getToken()
});
in the "/client/components/socket/socket.service.js" file.
Socket.io works now fine!
I'm not sure why openshift requires this, but you just need to modify your client code.
In your client side code, you should have something like this:
var socket = io();
You'll apparently need to update it to:
var socket = io('http://mywebsite.com:8000');
It's worth noting that there are plenty of other hosting providers (even free) which don't require you to jump through these hoops.

Redis in Nodejs on Cloud9 IDE: [Error: Auth error: undefined]

Here is my code:
var express = require("express"),
app = express(),
server = require("http").createServer(app),
io = require("socket.io").listen(server),
redis = require("redis"),
env = {PORT: process.env.PORT || 8080, IP: process.env.IP || "localhost"};
client = redis.createClient(env.PORT , env.IP);
client.on("error", function(err) {
console.log(err);
});
server.listen(env.PORT);
console.log("Server started # " + env.IP + ":" + env.PORT);
After trying to run, I received the followings on the console:
Running Node Process
Your code is running at 'http://modified.address.c9.io'.
Important: use 'process.env.PORT' as the port and 'process.env.IP' as the host in your scripts!
info: socket.io started
Server started # modified.ip.address.1:8080
[Error: Auth error: undefined]
I tried establishing the connection, and it connects to the IP and PORT perfectly. However, the error [Error: Auth error: undefined] appears and stops there. I Googled the error, the supports from the IDE I used..., and surprisingly, there are only 7 links to my problems. So I think it may be a hole in my knowledge or it is not really a problem yet a thing I don't know to work it out. All I could pull out from those Google results were (I was not sure) I need to use client.auth(pass) right after creating it. But where should I find the password? When I installed it npm install redis I didn't configure anything and wasn't told to set password whatsoever. So I reach the impasse.
I use Cloud9 IDE (c9.io), and the modules used as shown in the code above.
----With best regards,
----Tim.
I've found out what was wrong.
I did install Redis, but that is a Redis library that acts like a bridge between Redis driver and NodeJS. On Cloud9, I have to manually install Redis, too.
So it would take 2 commands to actually install Redis:
Install the Redis Driver on Cloud9
nada-nix install redis
Install Redis library for NodeJS
npm install redis
Thanks for anyone who was trying to help me.
You can run the redis-server using your own config file.You can create your own config like below.
//port and ip of ur redis server
port 6371
bind 127.0.0.1
//password for this server
requirepass ucanmentionurpwd
//storing snapshots of the data
save 60 1
dbfilename dump.rdb
dir /tmp/db
//starting redis server
redis-server //ur config file location
See this link for redis configuration
https://raw.github.com/antirez/redis/2.6/redis.conf
If you mention requirepass with your password means only you need to do
client.auth('urPwd');
Otherwise no need to call the client.auth method.

Resources