How to connect to a websocket from a different server? - javascript

I have server A "windows 7 Pro" where I installed node.js and ran it using this command node ws_server.js following the instructions here
From server B "Windows Server 2008 R2" running Apache 2.4/php 5.6.13 I want to connect to the ws_server on Server A.
on **Server B* I have a script called websocket.php with the code below
<script>
$(function() {
var WebSocketClient = require('websocket').client;
var client = new WebSocketClient();
client.on('connectFailed', function(error) {
console.log('Connect Error: ' + error.toString());
});
client.on('connect', function(connection) {
console.log('WebSocket Client Connected');
connection.on('error', function(error) {
console.log("Connection Error: " + error.toString());
});
connection.on('close', function() {
console.log('echo-protocol Connection Closed');
});
connection.on('message', function(message) {
if (message.type === 'utf8') {
console.log("Received: '" + message.utf8Data + "'");
}
});
function sendNumber() {
if (connection.connected) {
var number = Math.round(Math.random() * 0xFFFFFF);
connection.sendUTF(number.toString());
setTimeout(sendNumber, 1000);
}
}
sendNumber();
});
client.connect('ws://ServerA:8080/', 'echo-protocol');
});
</script>
But for some reason I get this error in the console.
ReferenceError: require is not defined
Do I need to take files from the nodejs folder from server A and include it in the client script? if so which files do I need to include?
Note: I have included jQuery files as well
EDITED
this is my client code
<script>
"use strict";
// Initialize everything when the window finishes loading
window.addEventListener("load", function(event) {
var status = document.getElementById("status");
var url = document.getElementById("url");
var open = document.getElementById("open");
var close = document.getElementById("close");
var send = document.getElementById("send");
var text = document.getElementById("text");
var message = document.getElementById("message");
var socket;
status.textContent = "Not Connected";
url.value = "ws://serverB:8080";
close.disabled = true;
send.disabled = true;
// Create a new connection when the Connect button is clicked
open.addEventListener("click", function(event) {
open.disabled = true;
socket = new WebSocket(url.value, "echo-protocol");
socket.addEventListener("open", function(event) {
close.disabled = false;
send.disabled = false;
status.textContent = "Connected";
});
// Display messages received from the server
socket.addEventListener("message", function(event) {
message.textContent = "Server Says: " + event.data;
});
// Display any errors that occur
socket.addEventListener("error", function(event) {
message.textContent = "Error: " + event;
});
socket.addEventListener("close", function(event) {
open.disabled = false;
status.textContent = "Not Connected";
});
});
// Close the connection when the Disconnect button is clicked
close.addEventListener("click", function(event) {
close.disabled = true;
send.disabled = true;
message.textContent = "";
socket.close();
});
// Send text to the server when the Send button is clicked
send.addEventListener("click", function(event) {
socket.send(text.value);
text.value = "";
});
});
</script>

require is a library used by nodejs, it's not present in window naturally,. I believe you are trying to use a code that you had been using in a nodejs environment.
In order to create the socket in a web based environment, checkout the WebSocket reference.
WebSockets are implemented in most latest browsers versions and you create them as follows:
var exampleSocket = new WebSocket("ws://www.example.com/socketserver", "protocolOne");

Taxicala answer is correct, you dont need require.
I think that you could try this piece of code in order to see if the sockets are working
var ws = new WebSocket('wss://ServerA:8080/', 'echo-protocol');
ws.onopen = function () {
console.log('socket connection opened properly');
ws.send("Hello World"); // send a message
console.log('message sent');
};
ws.onmessage = function (evt) {
console.log("Message received = " + evt.data);
};
ws.onclose = function () {
// websocket is closed.
console.log("Connection closed...");
};
In order to avoid the security error you should create the web socket server as https instead of http, This is the code that you provided in the related links, it is adapted to generate a secure server that allow CORS for all sites and methods, its only for testing proposes.
Note that you need to generate the certificates, and store it in a folder named certs2, if you need instructions to create the certs just google a little, there are a lot of great answer for that.
//CUSTOM
var WebSocketServer = require('websocket').server;
var https = require('https');
var fs = require('fs');
var options = {
key: fs.readFileSync('./certs2/key.pem'),
cert: fs.readFileSync('./certs2/key-cert.pem')
};
var server = https.createServer(options, function (req, res) {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
res.writeHead(404);
res.end();
});
// END CUSTOM
// START YOUR CODE....
server.listen(8080, function() {
console.log((new Date()) + ' Server is listening on port 8080');
});
wsServer = new WebSocketServer({
httpServer: server,
// You should not use autoAcceptConnections for production
// applications, as it defeats all standard cross-origin protection
// facilities built into the protocol and the browser. You should
// *always* verify the connection's origin and decide whether or not
// to accept it.
autoAcceptConnections: false
});
function originIsAllowed(origin) {
// put logic here to detect whether the specified origin is allowed.
return true;
}
wsServer.on('request', function(request) {
if (!originIsAllowed(request.origin)) {
// Make sure we only accept requests from an allowed origin
request.reject();
console.log((new Date()) + ' Connection from origin ' + request.origin + ' rejected.');
return;
}
var connection = request.accept('echo-protocol', request.origin);
console.log((new Date()) + ' Connection accepted.');
connection.on('message', function(message) {
if (message.type === 'utf8') {
console.log('Received Message: ' + message.utf8Data);
connection.sendUTF(message.utf8Data);
}
else if (message.type === 'binary') {
console.log('Received Binary Message of ' + message.binaryData.length + ' bytes');
connection.sendBytes(message.binaryData);
}
});
connection.on('close', function(reasonCode, description) {
console.log((new Date()) + ' Peer ' + connection.remoteAddress + ' disconnected.');
});
});

I had faced socket hangup error.
const WebSocket = require('ws');
const ws = new WebSocket('wss://127.0.0.1:8080');
events.js:183
throw er; // Unhandled 'error' event
^
Error: socket hang up
at TLSSocket.onHangUp (_tls_wrap.js:1137:19)
at Object.onceWrapper (events.js:313:30)
at emitNone (events.js:111:20)
at TLSSocket.emit (events.js:208:7)
at endReadableNT (_stream_readable.js:1064:12)
at _combinedTickCallback (internal/process/next_tick.js:138:11)
at process._tickCallback (internal/process/next_tick.js:180:9)
And I could fix that by modifying websocket connection code.
const ws = new WebSocket('ws://127.0.0.1:8080/ws');

Related

OpenShift Node.js WebSocket server connection issues

I am trying to connect to my server running on OpenShift using WebSockets, but no matter how I configure it, nothing seems to go through. I've tried connecting ports 8000, 8080, and 80 with binding to 8000 and 8080, but nothing gets through.
My client attempts to connect:
var connection = new WebSocket('ws://trserve-trserver.1d35.starter-us-east-1.openshiftapps.com:8000');
connection.onopen = function() {
window.alert("Connected!");
};
But "Connected" never pops up in an alert window. On the server side:
var webSocketsServerPort = process.env.PORT ||
process.env.OPENSHIFT_NODEJS_PORT || 8080;
var webSocketIP = process.env.IP || process.env.OPENSHIFT_NODEJS_IP || '0.0.0.0';
var server = http.createServer(function(request, response) {});
server.listen(webSocketsServerPort, webSocketIP, function() {
console.log((new Date()) + " Server is listening on port " +
webSocketsServerPort);
});
var wsServer = new webSocketServer({
httpServer: server
});
wsServer.on('request', function(request) {
console.log((new Date()) + ' Connection from origin ' + request.origin + '.');
The server prints:
"The server is listening on port 8080"
but never list anything with Connection from the origin.
Client side:
Example 1: Using the W3C WebSocket API.
var W3CWebSocket = require('websocket').w3cwebsocket;
var client = new W3CWebSocket('ws://localhost:8080/', 'echo-protocol');
client.onerror = function() {
console.log('Connection Error');
};
client.onopen = function() {
console.log('WebSocket Client Connected');
};
Example 2:
var WebSocketClient = require('websocket').client;
var client = new WebSocketClient();
client.on('connect', function(connection) {
console.log('WebSocket Client Connected');
connection.on('error', function(error) {
console.log("Connection Error: " + error.toString());
});
});
client.connect('ws://localhost:8080/', 'echo-protocol');
Server side:
var WebSocketServer = require('websocket').server;
var http = require('http');
var server = http.createServer(function(request, response) {
console.log((new Date()) + ' Received request for ' + request.url);
response.writeHead(404);
response.end();
});
server.listen(8080, function() {
console.log((new Date()) + ' Server is listening on port 8080');
});
wsServer = new WebSocketServer({
httpServer: server,
autoAcceptConnections: false
});
function originIsAllowed(origin) {
return true;
}
wsServer.on('request', function(request) {
if (!originIsAllowed(request.origin)) {
request.reject();
}
return;
}
var connection = request.accept('echo-protocol', request.origin);
});
Source: WebSocket
Hope, this may help you. You just need to go step by step. Most important is to allow origin from backend from where client request is coming.

Firefox can’t establish a connection to the server at ws://localhost:8080/

I have two files one is test.html which is:
<script src="js/jquery-2.1.4.min.js"></script>
<script type="text/javascript">
$(function () {
// if user is running mozilla then use it's built-in WebSocket
window.WebSocket = window.WebSocket || window.MozWebSocket;
var connection = new WebSocket('ws://localhost:8080/');
connection.onopen = function () {
// connection is opened and ready to use
alert('connection Open');
};
connection.onerror = function (error) {
// an error occurred when sending/receiving data
alert('Error');
};
connection.onmessage = function (message) {
alert('Message');
};
});
</script>
And one nodejs file which is
var WebSocketServer = require('websocket').server;
var http = require('http');
var server = http.createServer(function(request, response) {
console.log((new Date()) + ' Received request for ' + request.url);
response.writeHead(404);
response.end();
});
server.listen(8080, function() {
console.log((new Date()) + ' Server is listening on port 8080');
});
wsServer = new WebSocketServer({
httpServer: server,
autoAcceptConnections: false
});
function originIsAllowed(origin) {
return true;
}
wsServer.on('request', function(request) {
if (!originIsAllowed(request.origin)) {
request.reject();
console.log((new Date()) + ' Connection from origin ' + request.origin + ' rejected.');
return;
}
var connection = request.accept('echo-protocol', request.origin);
console.log((new Date()) + ' Connection accepted.');
connection.on('message', function(message) {
console.log(message);
connection.sendBytes(message);
});
connection.on('close', function(reasonCode, description) {
console.log((new Date()) + ' Peer ' + connection.remoteAddress + ' disconnected.');
});
});
While I am trying to connect with web-socket with my HTML file its give me an error which is
Firefox can’t establish a connection to the server at ws://localhost:8080/
It should be able to find and connect to the server but the server will reject your request and shutdown because of request.accept('echo-protocol', request.origin) in your server file.
Check the log of you nodejs command prompt.
To fix this just modify
var connection = new WebSocket('ws://localhost:8080/');
to
var connection = new WebSocket('ws://localhost:8080/', 'echo-protocol');

cannot read property '<fieldname>' of null after some time running

I have an angularjs website with NodeJS socket methods as a client, and a NodeJS application as a server.
Data is being passed from the server to the client through socket events. The problem is that after working fine for about 5 minutes, intermittently data that is successfully being sent from the NodeJS server is being received as 'null' in the website, thus giving me the following error:
angular.js:11598 TypeError: Cannot read property '<fieldName>' of null
at ecabsAngular.js:42
at angular.js:12149
at angular.js:12137
at angular.js:12137
at Object.<anonymous> (angular.js:12837)
at l.$digest (angular.js:14222)
at l.$apply (angular.js:14493)
at Socket.<anonymous> (ecabsAngular.js:275)
at Socket.Emitter.emit (socket.io-1.2.0.js:1)
at Socket.onevent (socket.io-1.2.0.js:1)
Do you have any idea what is causing this and how this can be solved?
Thanks in advance!
Edit:
This is the code that is crashing on the client side (on the website)
(function(){
var app = angular.module('Module', []);
app.controller('MainCtrl', ['$scope', '$window', function($scope, $window){
$scope.bookings = [];
socket.on('updateBooking', function(booking){
$scope.loadAllocations();
for (var i=0; i<$scope.bookings.length; i++) {
if ($scope.bookings[i].CRMBookingID == booking.CRMBookingID) {
$scope.$apply(function(){
$scope.bookings[i] = booking;
});
}
}
});
}
]);
})();
This is the code from the NodeJS (server):
var app = require('express')();
var http = require('http');
http.globalAgent.maxSockets = 200;
var server = http.createServer(app);
var io = require('socket.io').listen(server);
var sql = require('mssql');
server.listen(3000);
app.post('/updatebooking', function(request, response) // receive web service request
{
response.writeHeader(200, {"Content-Type": "text/plain"}); // build response header
response.end(); // end the response
request.on('data', function(changes)
{
try{
var c = JSON.parse(changes.toString()); // parse data received
var connection = new sql.Connection(config); // create DB connection
connection.connect(function (err) // connect to the database
{
if (err!=null) { logger.error('Update booking connection error: ' + c + ' ' + err); }
var request = new sql.Request(connection); // create SQL request
request.stream = true;
try{
var sqlquery = <sqlquery>; // build SQL query
logger.trace("Executing SP in DB: " + sqlquery);
request.query(sqlquery); // execute SP
request.on('row', function (row) // once committed send to the client (website)
{
logger.trace("Updated booking with Reference ID " + row.Ref + " " + sqlquery);
io.emit('updateBooking', row); // sending data
})
request.on('error', function(err) {
logger.error('Update booking SP request error: ' + sqlquery + err);
});
}catch( e){
logger.error('Update booking request error' + sqlquery + ' ' + e);
}
});
} catch(e)
{
var c = JSON.parse(changes.toString());
logger.error('Update booking error for: ' + c + ' ' +e);
}
connection.on('error', function(err) {
logger.error('Update error connection: ' + err);
});
});
});

Websocket server with ssl support (using websocket.io)

I have a simple Websocket server using node.js and websocket.io
var ws = require('websocket.io')
, server = ws.listen(8000);
server.on('connection', function (socket) {
console.log("connected");
socket.on('message', function (message) {
on_message_callback(socket, message);
});
socket.on('close', function () {
on_close_callback(socket);
});
});
And this is a major part of client:
const HOST = "wss://127.0.0.1:8000/";
var websocket = new WebSocket(HOST);
websocket.onopen = function(evt) { ... };
websocket.onclose = function(evt) { ... },
websocket.onerror = function(evt) { ... };
websocket.onmessage = function(evt) { ... };
(I've tested it with wss://echo.websocket.org:443 and works as desired)
Works for HTTP pages as desired. Problem is that I need to work under HTTPS pages, too. I not able to "upgrade" my code to make it work. Can anyone help me? I haven't found any tutorial for websocket.io (I want to keep using the same technologies).
I'm also not sure how to handle certificates. I can only generate self-signed. What for this case? When I create them, I have to import them manually to each browser, so they'll allow this communication?
Thank you.
Finally figured out solution (using Worlize/websocket-node)
const PORT = 8000;
const SUBPROTOCOL = 'sub-protocol';
var WebSocketServer = require('websocket').server;
var https = require('https');
var fs = require('fs');
// Private key and certification (self-signed for now)
var options = {
key: fs.readFileSync('cert/server.key'),
cert: fs.readFileSync('cert/server.crt')
};
// callback function is called only when localhost:8000 is accessed via https protocol
var server = https.createServer(options, function(request, response) {
// it sends 404 response so browser stops loading, otherwise it keeps loading
console.log((new Date()) + ' Received HTTP(S) request for ' + request.url);
response.writeHead(404);
response.end();
});
// bind server object to listen to PORT number
server.listen(PORT, function() {
console.log((new Date()) + ' Server is listening on port ' + PORT);
});
wsServer = new WebSocketServer({
httpServer: server,
// You should not use autoAcceptConnections for production
// applications, as it defeats all standard cross-origin protection
// facilities built into the protocol and the browser. You should
// *always* verify the connection's origin and decide whether or not
// to accept it.
autoAcceptConnections: false
});
function originIsAllowed(origin) {
// put logic here to detect whether the specified origin is allowed.
return true;
}
// If autoAcceptConnections is set to false, a request event will be emitted
// by the server whenever a new WebSocket request is made
wsServer.on('request', function(request) {
if (!originIsAllowed(request.origin)) {
// Make sure we only accept requests from an allowed origin
request.reject();
console.log((new Date()) + ' Connection from origin ' + request.origin + ' rejected.');
return;
}
// accepts connection and return socket for this connection
var connection = request.accept(SUB_PROTOCOL, request.origin);
console.log((new Date()) + ' Connection accepted.');
// when message is received
connection.on('message', function(message) {
// echo
connection.send(connection, message.utf8Data);
});
connection.on('close', function(reasonCode, description) {
console.log((new Date()) + ' Peer ' + connection.remoteAddress + ' disconnected.');
});
});

Windows 8 app and nodejs websocket not connecting to each other

I'm working with a windows app and trying to connect it to node server.
I'm using web sockets in the windows app and and 'websocket' from npm for node.
I'm have trouble connecting the two it seems like there connecting but when I try to send information across(simple hello world string) nothing happens.
I have a simple javascript windows app.
In my default.html there is just a simple button:
<button onclick="Check()">Check status</button>
In the default.js I have the Check function which is:
function Check()
{
var host = "ws://192.168.201.91:8080";
try
{
socket = new WebSocket(host);
socket.onopen = function (openEvent)
{
console.log("Sockets open");
socket.send("Hello, world");
console.log("Socket state: " + socket.readyState);
console.log("Message is sent to: " + socket.url);
};
socket.onerror = function (errorEvent)
{
console.log(" 'WebSocket Status:: Error was reported';")
};
socket.onclose = function (closeEvent)
{
console.log("WebSocket Status:: Socket Closed");
};
socket.onmessage = function (messageEvent)
{
console.log(socket.toString);
var received_msg = messageEvent.data;
console.log("Message recieved: " + received_msg);
}
}
catch(exception)
{
if (window.console)
console.log(exception);
}
}
socket.readyState return me 1 which states a connection is made and the socket is ready for sending!
My node server then looks like this:
#!/usr/bin/env node
var WebSocketServer = require('websocket').server;
var http = require('http');
var server = http.createServer(function(request, response) {
console.log((new Date()) + ' Received request for ' + request.url);
response.writeHead(404);
response.end();
});
server.listen(8080, function() {
console.log((new Date()) + ' Server is listening on port 8080');
});
wsServer = new WebSocketServer({
httpServer: server,
// You should not use autoAcceptConnections for production
// applications, as it defeats all standard cross-origin protection
// facilities built into the protocol and the browser. You should
// *always* verify the connection's origin and decide whether or not
// to accept it.
autoAcceptConnections: true
});
console.log("Here wsServer");
function originIsAllowed(origin) {
// put logic here to detect whether the specified origin is allowed.
return true;
}
wsServer.on('request', function(request) {
//if (!originIsAllowed(request.origin)) {
// Make sure we only accept requests from an allowed origin
//request.reject();
// console.log((new Date()) + ' Connection from origin ' + request.origin + ' rejected.');
// return;
//}
console.log("Here");
var connection = request.accept('echo-protocol', request.origin);
console.log((new Date()) + ' Connection accepted.');
connection.on('message', function(message) {
if (message.type === 'utf8') {
console.log('Received Message: ' + message.utf8Data);
connection.sendUTF(message.utf8Data);
}
});
connection.on('close', function(reasonCode, description) {
console.log((new Date()) + ' Peer ' + connection.remoteAddress + ' disconnected.');
});
});
I have taken out any security checks as I just want the message to send to the server.
But this is not happening and I dont know why! Any help would be greatly appreciated.
Edit --
Just thought it should be possible to send information to see if it hits the sever but i am just not sure on a windows app what the ip is! If I can tell my node server to send information that will at least let me know that a channel is open.
Any ideas how to get the ip of a windows app through javascript?

Categories