簡體   English   中英

NGROK + Web服務器-NODE.JS + WEBSOCKET + NPM

[英]NGROK + WEB-SERVER + NODE.JS + WEBSOCKET + NPM

我在本地主機上有一個Web服務器,並且通過ngrock用手機連接到該服務器。 由於ngrock創建了一個網址,例如http://94815c96.ngrok.io ,它可以將我重定向到localhost:8888,在這里我可以看到我的項目和文件。

然后,我需要通過websocket連接我的Web服務器並創建一個聊天應用程序,為此,我已經安裝了npm和node.js並運行命令node filename.js,該filename.js文件創建了一個監聽端口的套接字1337並在網絡服務器的側面打開端口1337上的websocket。如果我通過本地設備上的網絡瀏覽器進行操作,則可以正常工作,但是當我通過帶有ngrock網址的手機嘗試操作時,它將返回錯誤,連接到WebSocket服務器。

我使用的代碼很簡單。 我有一個名為frontend.html的html查看和輸出聊天應用程序,另一個名為chat-c​​lient.js的文件打開了端口1337到websocket的連接,最后一個文件名為chat-server.js,監聽了端口1337。每個文件的代碼如下:

frontend.html:

    <!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>WebSockets - Simple chat</title>

        <style>
        * { 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; }
        </style>
    </head>
    <body>
        <div id="content"></div>
        <div>
            <span id="status">Connecting...</span>
            <input type="text" id="input" disabled="disabled" />
        </div>

        <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
        <script src="./chat-frontend.js"></script>
    </body>
</html>

chat-c​​lient.js:

$(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>');
}
});

chat-server.js

// 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, '&amp;').replace(/</g, '&lt;')
                      .replace(/>/g, '&gt;').replace(/"/g, '&quot;');
}

// 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);
    }
});

});

執行ngrok的命令

使用chat-server.js執行節點

ngrok返回的錯誤

您需要向公眾展示您的第二個端口1337,該端口由WebSockets使用。 您將需要有2個單獨的ngrok實例運行並轉發1337和8888端口。 同樣在chat-c​​lient.js中,應將行“ ws://127.0.0.1:1337”更改為新的ngrok轉發網址(例如ws://111111.ngrok.io)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM