3

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>
Junior
  • 11,602
  • 27
  • 106
  • 212

3 Answers3

5

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
  • 21,408
  • 7
  • 37
  • 66
  • I installed websocket on a server I am trying to connect to it from the client which is giving me the error. how to I include the require library in my client code? – Junior Aug 14 '15 at 18:36
  • you can use requirejs but it's different than the nodejs library. I don't think there is a need to include anything here, browsers give you the WebSocket interface out of the box. You are mixing server side js with client side js here. – taxicala Aug 14 '15 at 18:40
  • You should read and investigate about CORS and Same Origin Policy. – taxicala Aug 14 '15 at 18:50
3

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.');
    });
});
ecarrizo
  • 2,758
  • 17
  • 29
  • I just tested your code. I get this `SecurityError: The operation is insecure.` – Junior Aug 14 '15 at 18:56
  • 1
    You need to enable CORS headers in your server. Also, note that mixed content is another issue here, you are trying to create a communication between http and https. – taxicala Aug 14 '15 at 19:01
  • Yes, you can't perform insecure request to a secure environment and viceversa, (HTTP to HTTPS or HTTPS to HTTP) is a browser limitation that was added to newer browser versions. – ecarrizo Aug 14 '15 at 19:04
  • @MikeA I've edited the answer. Take into account that you may need to access https:// server:8080 manually at least once if the certificates are not trusted. – ecarrizo Aug 14 '15 at 19:27
  • I just stoppen the server and tried to bring it up again. but now I get an error `Error: error:0906D06C:PEM routines:PEM_read_bio:no start line at Error (native) at Object.createSecureContext (_tls_common.js:132:17) at Server (_tls_wrap.js:598:25) at new Server (https.js:36:14) at Object.exports.createServer (https.js:56:10) at Object. (C:\Program Files\nodejs\icws.js:12:20) at Module._compile (module.js:460:26) at Object.Module._extensions..js (module.js:478:10) at Module.load (module.js:355:32) at Function.Module._load (module.js:310:12)` – Junior Aug 14 '15 at 21:04
  • I looked at the answer here http://stackoverflow.com/questions/22584268/node-js-https-pem-error-routinespem-read-biono-start-line but still same error – Junior Aug 14 '15 at 21:12
  • 2
    Try creating the certificates like this `openssl req -newkey rsa:2048 -new -nodes -x509 -days 3650 -keyout key.pem -out cert.pem`, after that restart the script. (With the line that you provided I can reproduce the issue, with this it work) – ecarrizo Aug 14 '15 at 21:13
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/87040/discussion-between-mike-a-and-ecarrizo). – Junior Aug 14 '15 at 21:30
0

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');
Zhong Ri
  • 2,556
  • 1
  • 19
  • 23