How to put my Web Socket server application in the Heroku? - javascript

I created a heroku account to use Node.js but I don't know how to put my Server.js in the server (that I created): http://calnetaskmanager.herokuapp.com/, I've read a lot of guides from Heroku and I've searched a LOT, but I can't find anyone explaining simply how to put a Server.js into a Heroku server. Can someone leave a simple example of putting a websocket server in the heroku. This server need to be accessible by anyone.
I placed the Client side if necessary, and the Server.js
P.S.: "If you see any english mistake or something sounds weird, edit please!"
Thanks in Advance.
Client Side:
$(function() {
"use strict";
// for better performance - to avoid searching in DOM
var content = $('#content');
var input = $('#input');
var status = $('#status');
// my color assigned by the server
var myColor = false;
// my name sent to the server
var myName = false;
// if user is running mozilla then use it's built-in WebSocket
window.WebSocket = window.WebSocket || window.MozWebSocket;
// if browser doesn't support WebSocket, just show some notification and exit
if (!window.WebSocket) {
content.html($('<p>', {
text: 'Sorry, but your browser doesn\'t ' + 'support WebSockets.'
}));
input.hide();
$('span').hide();
return;
}
// open connection
var connection = new WebSocket('ws://127.0.0.1:1337');
connection.onopen = function() {
// first we want users to enter their names
input.removeAttr('disabled');
status.text('Choose name:');
};
connection.onerror = function(error) {
// just in there were some problems with conenction...
content.html($('<p>', {
text: 'Sorry, but there\'s some problem with your ' + 'connection or the server is down.'
}));
};
// most important part - incoming messages
connection.onmessage = function(message) {
// try to parse JSON message. Because we know that the server always returns
// JSON this should work without any problem but we should make sure that
// the massage is not chunked or otherwise damaged.
try {
var json = JSON.parse(message.data);
} catch (e) {
console.log('This doesn\'t look like a valid JSON: ', message.data);
return;
}
// NOTE: if you're not sure about the JSON structure
// check the server source code above
if (json.type === 'color') { // first response from the server with user's color
myColor = json.data;
status.text(myName + ': ').css('color', myColor);
input.removeAttr('disabled').focus();
// from now user can start sending messages
} else if (json.type === 'history') { // entire message history
// insert every single message to the chat window
for (var i = 0; i < json.data.length; i++) {
addMessage(json.data[i].author, json.data[i].text,
json.data[i].color, new Date(json.data[i].time));
}
} else if (json.type === 'message') { // it's a single message
input.removeAttr('disabled'); // let the user write another message
addMessage(json.data.author, json.data.text,
json.data.color, new Date(json.data.time));
} else {
console.log('Hmm..., I\'ve never seen JSON like this: ', json);
}
};
/**
* Send mesage when user presses Enter key
*/
input.keydown(function(e) {
if (e.keyCode === 13) {
var msg = $(this).val();
if (!msg) {
return;
}
// send the message as an ordinary text
connection.send(msg);
$(this).val('');
// disable the input field to make the user wait until server
// sends back response
input.attr('disabled', 'disabled');
// we know that the first message sent from a user their name
if (myName === false) {
myName = msg;
}
}
});
/**
* This method is optional. If the server wasn't able to respond to the
* in 3 seconds then show some error message to notify the user that
* something is wrong.
*/
setInterval(function() {
if (connection.readyState !== 1) {
status.text('Error');
input.attr('disabled', 'disabled').val('Unable to comminucate ' + 'with the WebSocket server.');
}
}, 3000);
/**
* Add message to the chat window
*/
function addMessage(author, message, color, dt) {
content.prepend('<p><span style="color:' + color + '">' + author + '</span> # ' +
+(dt.getHours() < 10 ? '0' + dt.getHours() : dt.getHours()) + ':' + (dt.getMinutes() < 10 ? '0' + dt.getMinutes() : dt.getMinutes()) + ': ' + message + '</p>');
}
});
* {
font-family: tahoma;
font-size: 12px;
padding: 0px;
margin: 0px;
}
p {
line-height: 18px;
}
div {
width: 500px;
margin-left: auto;
margin-right: auto;
}
#content {
padding: 5px;
background: #ddd;
border-radius: 5px;
overflow-y: scroll;
border: 1px solid #CCC;
margin-top: 10px;
height: 160px;
}
#input {
border-radius: 2px;
border: 1px solid #ccc;
margin-top: 10px;
padding: 5px;
width: 400px;
}
#status {
width: 88px;
display: block;
float: left;
margin-top: 15px;
}
<!DOCTYPE html>
<html>
<head>
<style type="text/css"></style>
<meta charset="utf-8">
<title>WebSockets - Simple chat</title>
</head>
<body>
<div id="content"></div>
<div>
<span id="status">Choose name:</span>
<input type="text" id="input">
</div>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="./frontend.js"></script>
</body>
Server Side
// http://ejohn.org/blog/ecmascript-5-strict-mode-json-and-more/
"use strict";
// Optional. You will see this name in eg. 'ps' or 'top' command
process.title = 'node-chat';
// Port where we'll run the websocket server
var webSocketsServerPort = 1337;
// websocket and http servers
var webSocketServer = require('websocket').server;
var http = require('http');
/**
* Global variables
*/
// latest 100 messages
var history = [];
// list of currently connected clients (users)
var clients = [];
/**
* Helper function for escaping input strings
*/
function htmlEntities(str) {
return String(str).replace(/&/g, '&').replace(/</g, '<')
.replace(/>/g, '>').replace(/"/g, '"');
}
// Array with some colors
var colors = ['red', 'green', 'blue', 'magenta', 'purple', 'plum', 'orange'];
// ... in random order
colors.sort(function(a, b) {
return Math.random() > 0.5;
});
/**
* HTTP server
*/
var server = http.createServer(function(request, response) {
// Not important for us. We're writing WebSocket server, not HTTP server
});
server.listen(webSocketsServerPort, function() {
console.log((new Date()) + " Server is listening on port " + webSocketsServerPort);
});
/**
* WebSocket server
*/
var wsServer = new webSocketServer({
// WebSocket server is tied to a HTTP server. WebSocket request is just
// an enhanced HTTP request. For more info http://tools.ietf.org/html/rfc6455#page-6
httpServer: server
});
// This callback function is called every time someone
// tries to connect to the WebSocket server
wsServer.on('request', function(request) {
console.log((new Date()) + ' Connection from origin ' + request.origin + '.');
// accept connection - you should check 'request.origin' to make sure that
// client is connecting from your website
// (http://en.wikipedia.org/wiki/Same_origin_policy)
var connection = request.accept(null, request.origin);
// we need to know client index to remove them on 'close' event
var index = clients.push(connection) - 1;
var userName = false;
var userColor = false;
console.log((new Date()) + ' Connection accepted.');
// send back chat history
if (history.length > 0) {
connection.sendUTF(JSON.stringify({
type: 'history',
data: history
}));
}
// user sent some message
connection.on('message', function(message) {
if (message.type === 'utf8') { // accept only text
if (userName === false) { // first message sent by user is their name
// remember user name
userName = htmlEntities(message.utf8Data);
// get random color and send it back to the user
userColor = colors.shift();
connection.sendUTF(JSON.stringify({
type: 'color',
data: userColor
}));
console.log((new Date()) + ' User is known as: ' + userName + ' with ' + userColor + ' color.');
} else { // log and broadcast the message
console.log((new Date()) + ' Received Message from ' + userName + ': ' + message.utf8Data);
// we want to keep history of all sent messages
var obj = {
time: (new Date()).getTime(),
text: htmlEntities(message.utf8Data),
author: userName,
color: userColor
};
history.push(obj);
history = history.slice(-100);
// broadcast message to all connected clients
var json = JSON.stringify({
type: 'message',
data: obj
});
for (var i = 0; i < clients.length; i++) {
clients[i].sendUTF(json);
}
}
}
});
// user disconnected
connection.on('close', function(connection) {
if (userName !== false && userColor !== false) {
console.log((new Date()) + " Peer " + connection.remoteAddress + " disconnected.");
// remove user from the list of connected clients
clients.splice(index, 1);
// push back user's color to be reused by another user
colors.push(userColor);
}
});
});

Before you will upload any server to Heroku - your project need 2 files:
Procfile - (file will run your server js code)
package.json - (json that contain all the description of your server, include the server code name file)
After you have those,
For the easy way you can open Git account, and than open there a Repository. install Git on your computer. open Git shell and upload your project to Git-Hub. then, you can open your Heroku account - and pull your project right from your online Git repository.

You can deploy through git to heroku. That way the only thing you have to do is do a git push heroku master for example.
But first you need to add the heroku remotes to the git repo, if you have the heroku toolbelt all you need to do is:
$ heroku git:remote -a falling-wind-1624
Git remote heroku added.
Here's the link to the documentation. Hope it helps!

Related

Django websocket cannot connect through https request blocked in railway app

My websocket works fine on localhost. But fails to run when I deploy my project on railway app
(which uses https)
It shows this error in the console log:
first error -
(index):382 Mixed Content: The page at 'https://supreme-key-production.up.railway.app/rooms/bangladesh_ott/' was loaded over HTTPS, but attempted to connect to the insecure WebSocket endpoint 'ws://supreme-key-production.up.railway.app/ws/bangladesh_ott/'. This request has been blocked; this endpoint must be available over WSS.
second error -
(index):382 Uncaught DOMException: Failed to construct 'WebSocket': An insecure WebSocket connection may not be initiated from a page loaded over HTTPS.
at window.onload (https://supreme-key-production.up.railway.app/rooms/bangladesh_ott/:382:24)
This is in my script :
window.onload = function() {
const roomName = JSON.parse(document.getElementById('json-roomname').textContent);
const userName = JSON.parse(document.getElementById('json-username').textContent);
const chatSocket = new WebSocket(
'ws://'
+ window.location.host
+ '/ws/'
+ roomName
+ '/'
);
chatSocket.onmessage = function(e) {
console.log('onmessage')
const data = JSON.parse(e.data);
if (data.message) {
let html = '<div class="message">';
html += '<p class="messsage_username">' + data.username + '</p>';
html += '<p class="message_message">' + data.message + '</p></div>';
document.querySelector('#chat-messages').innerHTML += html;
} else {
alert('The message was empty!');
}
}
chatSocket.onclose = function(e) {
console.log('onclose')
}
//
document.querySelector('#chat-message-submit').onclick = function(e) {
e.preventDefault();
const messageInputDom = document.querySelector('#chat-message-input');
const message = messageInputDom.value;
chatSocket.send(JSON.stringify({
'message': message,
'username': userName,
'room': roomName
}));
messageInputDom.value = '';
return false;
}
}
Any solution for this?

MESIBO Web(javascript), not receiving message in other end

I created two test users from MESIBO API, to test messaging between them.
Created exact same script in two files, and add send function in one file, to send message to the second user.
I tried the second user's token, UID, and address but the message gets sent from the first user but 2nd user's script listener doesn't catch it. Both the user tokens, appid (app name) are valid, I tried even in HTTPS connection too, but still couldn't receive a message on another end.
Second User (two.html) : Sender
FIrst User (one.html) : Receiver
Script form first user: which supposed to get the message
<script type="text/javascript" src="https://api.mesibo.com/mesibo.js"></script>
<script>
var demo_user_token = 'XXXXXXXXXXXXXXXXXX';
var demo_appid = 'legal.web';
var api = new Mesibo();
api.setListener(new MesiboListener());
api.setAppName(demo_appid);
api.setCredentials(demo_user_token);
api.setAccessToken(demo_user_token);
//api.setDatabase("mesibo");
api.start();
console.log('First User');
function MesiboListener() {
}
MesiboListener.prototype.Mesibo_OnConnectionStatus = function(status, value) {
console.log("Mesibo_OnConnectionStatus: " + status);
}
MesiboListener.prototype.Mesibo_OnMessageStatus = function(m) {
console.log("Mesibo_OnMessageStatus: from "
+ m.peer + " status: " + m.status);
}
MesiboListener.prototype.Mesibo_OnMessage = function(m, data) {
console.log("Mesibo_OnMessage: from " + m.peer);
}
MesiboListener.prototype.Mesibo_OnCall = function(callid, from, video) {
console.log("Mesibo_onCall: " + (video?"Video":"Voice") + " call from: " + from);
}
</script>
Script from the second user, who send message to the first user using first user's token
<script type="text/javascript" src="https://api.mesibo.com/mesibo.js"></script>
<input type="button" value="Send" onclick="sendTextMessage()" >
<script>
var demo_user_token = 'XXXXXXXXXXXXXXXXXXX';
var demo_appid = 'legal.web';
var api = new Mesibo();
api.setListener(new MesiboListener());
api.setAppName(demo_appid);
api.setCredentials(demo_user_token);
api.setAccessToken(demo_user_token);
api.start();
console.log('Scond User User');
function MesiboListener() {
}
MesiboListener.prototype.Mesibo_OnConnectionStatus = function(status, value) {
console.log("Mesibo_OnConnectionStatus: " + status);
}
MesiboListener.prototype.Mesibo_OnMessageStatus = function(m) {
console.log("Mesibo_OnMessageStatus: from "
+ m.peer + " status: " + m.status);
}
MesiboListener.prototype.Mesibo_OnMessage = function(m, data) {
console.log("Mesibo_OnMessage: from " + m.peer);
}
function sendTextMessage() {
let to = "2757b980f05600c48d75f17f6cb0480ed3a91557655dc7d2ebb3f2dc5vaa1cbe86178"
var profile = api.getProfile(to, 0);
console.log(profile);
var id = parseInt(Math.random()*10000);
profile.sendMessage(id, "this is text message");
}
</script>
Why are you using a token in the "to" parameter? It should be the address "USER_2". Please do not share your tokens in a public forum.
function sendTextMessage() {
let to = "USER_2"
var profile = api.getProfile(to, 0);
console.log(profile);
var id = parseInt(Math.random()*10000);
profile.sendMessage(id, "this is text message");
}
Refer to the tutorial here https://mesibo.com/documentation/tutorials/get-started/javascript/

Can not connect web socket with javascript

I want to connect to my web socket that put on amazone instance with some ip. I can connect my web socket with some ip and port with google rest client app and its working very well.
Screen Shot :
But if i want to connect this with java script it can not connect. This is working fine before 2-3 month. i have not change and thing but its not working now.
If i want to connect with firefox it produce an error.
Here is my code :-
function init() {
var host = "ws://XX.XX.XXX.XXX:XXXX"; // SET THIS TO YOUR SERVER
try {
var socket = new WebSocket(host);
// alert('WebSocket - status ' + socket.readyState);
log('WebSocket - status ' + socket.readyState);
socket.onopen = function (msg) {
alert('open');
alert("Welcome - status " + this.readyState);
log("Welcome - status " + this.readyState);
if (this.readyState != 1)
{
reconnect();
}
};
socket.onmessage = function (msg) {
// alert("Received: " + msg.data);
log("Received: " + msg.data);
};
socket.onclose = function (msg) {
// alert("Disconnected - status " + this.readyState);
log("Disconnected - status " + this.readyState);
};
} catch (ex) {
alert(ex);
log(ex);
}
$("msg").focus();
}
This is alerting status 0 and error show in console :-
Firefox can't establish a connection to the server at ws://XX.XX.XXX.XXX:XXXX.
var socket = new WebSocket(host);
I'd try your code and for me is working just fine, I'd test it with this webpage: https://www.websocket.org/echo.html , maybe could be helpful for testing purposes. But also i found this question: websocket-rails, websocket handshake error , maybe also help.
However i'd just change the host in your code to this:"ws://echo.websocket.org", and everything works without problems.
Hope you find a solution and that this info was of any help. Here's your code that i used for the test:
function init() {
var host = "ws://echo.websocket.org";
try {
var socket = new WebSocket(host);
alert('WebSocket - status ' + socket.readyState);
socket.onopen = function (msg) {
alert('open');
alert("Welcome - status " + this.readyState);
if (this.readyState != 1)
{
reconnect();
}
};
socket.onmessage = function (msg) {
alert("Received: " + msg.data);
};
socket.onclose = function (msg) {
alert("Disconnected - status " + this.readyState);
};
} catch (ex) {
alert(ex);
}
$("msg").focus();
}
*Sorry for my bad english.

Check for an specific .js file being served in response

I need to detect whether an specific .js file was served in a http response and additionally, check the domain it came from, like this:
I need to automatically detect the lack of the js file and email the incidence
I tried Net::Http, rest-client, mechanize and a lot of gems, they just return the html header. It seems I need to monitor http traffic with tools like PhantomJS and checking for the file, but is there any rubyesque way of doing this?
Thanks in advance
I ended with the phantomjs approach. A ruby script iterate over a database table and then calls this phantomjs script for each record representing an URL
This is the phantomjs script
var page = require('webpage').create(),
system = require('system'),
address,
isScript = false;
var fs = require('fs');
// main
analizePage(system.args[1]);
//open page.
//onResourceRequested event, compares domain of each one with 'my.domain.net'
//append to a log file: -1 for failed url, 1 for script presence, 0 for no script presence
function analizePage(address){
page.open(address, function (status) {
if (status !== 'success') {
console.log('FAIL to load the address ' + address);
fileWriter(-1, address);
}
else
{
if (!isScript){
fileWriter(0, address);
}
else
{
fileWriter(1, address);
}
console.log('Has script: ' + isScript);
}
phantom.exit(0);
});
page.onResourceRequested = function (req) {
try {
var link = document.createElement('a');
link.setAttribute('href', req.url); //extract asset's domain from URL
if (link.hostname == 'my.domain.net') {
isScript = true;
}
} catch(e) {
console.log("PAGE OPEN ERROR: " + e);
}
};
}
function fileWriter(type, line){
try {
fs.write("scriptlog.csv", type + ',' + line + ',' + Date.now() + ',' + system.args[2] + '\n', 'a');
} catch(e) {
console.log("FILE ERROR: " + e);
}
}

Javascript callbacks work in Firefox but not in Chrome or Safari

I am working with Ejabberd and Orbited and I am having a few issues with my JavaScript callback functions not being called. The following is my JavaScript file where the TCPSocket connection happens and I have two callback functions namely
onSocketConnect: which is called when the Orbited established connection with port 5222 of the XMPP server and
onLoginSuccess: which is called on the successful completion of the xmpp_client.login function
The problem I'm facing is the connection happens successfully but my callbacks get called only when I'm using FireFox and not while using Safari or Chrome. I'm totally clueless about what is causing this problem but I'm sure that the method xmpp_client.login does get called because the user is logged in and is displayed as online in the ejabberd admin console.
TCPSocket = Orbited.TCPSocket;
Orbited.settings.port = 8000;
Orbited.settings.hostname = 'localhost';
document.domain = document.domain;
<script src='http://localhost:8000/static/protocols/xmpp/xmpp.js'></script>
//xmpp.js file is included after this which is available with the Orbited. I have not included the code here.
<% if current_user %>
<script>
notifier = ' ';
user = "<%= current_user.jabber_id %>";
alert(user);
password = '123456';
domain = XMPPDOMAIN;
/* function onLoginSuccess(){
$('.status').html("Connected and Logged In");
xmpp_client.set_presence('available');
} */
var onLoginSuccess = function(){
$('.status').html("Connected and Logged In");
}
function onLoginFailure(){
alert('User could not be logged in');
}
function connectSuccess(){
$('.status').html("Connection Successful.");
}
function connectFailure(){
$('.status').html("Connection Failed!");
}
function onSetupNotification(){}
xmpp_client = new XMPPClient();
xmpp_client.connect('localhost',5222);
xmpp_client.onPresence = function(ntype, from) {
alert('Presence message' + ntype + ' From :' + from)
}
xmpp_client.onSocketConnect = function(domain, connectSuccess, connectFailure){
var domain = XMPPDOMAIN;
$('.status').html('Connected');
alert(user);
if(domain)
{
xmpp_client.connectServer(domain, connectSuccess, connectFailure);
xmpp_client.login(user, password, onLoginSuccess, onLoginFailure);
xmpp_client.set_presence('available');
}
}
function send_message(id, msg){
var j_id = id + '#' + 'siddharth-ravichandrans-macbook-pro.local';
alert('jid_id' + j_id);
var status = xmpp_client.msg(j_id, msg);
alert(status);
}
xmpp_client.onMessage = function(jid, username, text) {
alert('message-recieved');
if ( $('.discussion-area').length > 0 ){
$('.discussion-area').append('<div class=\'new-message\'>' + text + '</div>');
return false;
}
}
/* self.login = function(nick, pass, s, f) {
conn.onread = setUser;
success = s;
failure = f;
user = nick;
bare_jid = nick + "#" + domain;
full_jid = bare_jid + "/Orbited";
self.send(construct(LOGIN, [user, pass]));
}
self.set_presence = function(status, status_msg) {
self.send(EXT_PRESENCE[0] + full_jid + EXT_PRESENCE[1] + room_jid + EXT_PRESENCE[3] + status + EXT_PRESENCE[4] + status_msg + EXT_PRESENCE[5]);
}
*/
</script>
<% end %>
This is part of the xmpp.js which I got when I installed orbited and in order to test if my requests were actually reaching I added an alert in the login method as follows
...
...
self.login = function(nick, pass, s, f) {
conn.onread = setUser;
success = s;
failure = f;
user = nick;
bare_jid = nick + "#" + domain;
full_jid = bare_jid + "/Orbited";
self.send(construct(LOGIN, [user, pass]));
alert("bazingaa");
}
self.connectServer = function(d, s, f) {
success = s;
failure = f;
doma
...
...
Now I have no clue how this got my callbacks and would really appreciate some help on this.
Thanks
Actually I find that removing the xmpp_client.set_presence and moving it to the onLoginSuccess is what seems to have done the trick. The minute I add the set_presence method after the login method call the functionality fails in chrome. So why would that prevent it from invoking the callback on successful login?
var onLoginSuccess = function(){
$('.status').html("Connected and Logged In");
xmpp_client.set_presence('available');
}
xmpp_client.onSocketConnect = function(domain, connectSuccess, connectFailure){
var d = "";
$('.status').html('Connected');
xmpp_client.connectServer(d, connectSuccess, connectFailure);
xmpp_client.login(user, password, onLoginSuccess, onLoginFailure);
//xmpp_client.set_presence('available');
}
Help!
I think your problem is related to the Same Origin Policy for Javascript
https://developer.mozilla.org/en/Same_origin_policy_for_JavaScript
I'm sure the Safari/Chrome Web Inspector (with Javascript enabled) will verify this in the javascript console
Modern browsers (ie. not Internet Explorer!) get around this issue by implementing Cross-Origin Resource Sharing. But then your Javascript XMPP client library has to implement CORS too
http://metajack.im/2010/01/19/crossdomain-ajax-for-xmpp-http-binding-made-easy/
I'm not familiar with Orbited but I have done this type of browser XMPP connections using the Strophejs library and ejabberd's XMPP BOSH connection manager
To get around the Same Origin policy across all browsers you need to employ a proxy
http://flxhr.flensed.com/ (client-side proxy library)
If using apache you can employ a server-side proxy with the ProxyPass directive under the mod_proxy module

Categories