Skip to content

Instantly share code, notes, and snippets.

@labonaboat
Forked from martinsik/chat-frontend.js
Created July 10, 2018 00:55
Show Gist options
  • Save labonaboat/63c41c70dfa03c85c8c6054cad66eb07 to your computer and use it in GitHub Desktop.
Save labonaboat/63c41c70dfa03c85c8c6054cad66eb07 to your computer and use it in GitHub Desktop.

Revisions

  1. @martinsik martinsik revised this gist Apr 10, 2013. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion chat-frontend.js
    Original file line number Diff line number Diff line change
    @@ -112,7 +112,7 @@ $(function () {
    * Add message to the chat window
    */
    function addMessage(author, message, color, dt) {
    content.append('<p><span style="color:' + color + '">' + author + '</span> @ ' +
    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>');
  2. @martinsik martinsik revised this gist Apr 10, 2013. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions frontend.html
    Original file line number Diff line number Diff line change
    @@ -8,8 +8,8 @@
    * { 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;
    border:1px solid #CCC; margin-top:10px; }
    #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; }
  3. @martinsik martinsik revised this gist Apr 10, 2013. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion chat-frontend.js
    Original file line number Diff line number Diff line change
    @@ -35,7 +35,7 @@ $(function () {
    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.</p>' } ));
    + 'connection or the server is down.' } ));
    };

    // most important part - incoming messages
  4. @martinsik martinsik revised this gist Apr 10, 2013. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions frontend.html
    Original file line number Diff line number Diff line change
    @@ -22,7 +22,7 @@
    <input type="text" id="input" disabled="disabled" />
    </div>

    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
    <script src="frontend.js"></script>
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
    <script src="./frontend.js"></script>
    </body>
    </html>
  5. @martinsik martinsik revised this gist Sep 13, 2012. 1 changed file with 2 additions and 1 deletion.
    3 changes: 2 additions & 1 deletion chat-server.js
    Original file line number Diff line number Diff line change
    @@ -46,7 +46,8 @@ server.listen(webSocketsServerPort, function() {
    * WebSocket server
    */
    var wsServer = new webSocketServer({
    // WebSocket server is tied to a HTTP server. To be honest I don't understand why.
    // 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
    });

  6. Martin Sikora revised this gist Apr 20, 2012. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion chat-server.js
    Original file line number Diff line number Diff line change
    @@ -95,7 +95,7 @@ wsServer.on('request', function(request) {
    color: userColor
    };
    history.push(obj);
    history.slice(-100);
    history = history.slice(-100);

    // broadcast message to all connected clients
    var json = JSON.stringify({ type:'message', data: obj });
  7. Martin Sikora revised this gist Apr 11, 2012. 2 changed files with 5 additions and 1 deletion.
    3 changes: 3 additions & 0 deletions chat-frontend.js
    Original file line number Diff line number Diff line change
    @@ -78,6 +78,9 @@ $(function () {
    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('');
    3 changes: 2 additions & 1 deletion chat-server.js
    Original file line number Diff line number Diff line change
    @@ -14,7 +14,7 @@ var http = require('http');
    /**
    * Global variables
    */
    // entire message history
    // latest 100 messages
    var history = [ ];
    // list of currently connected clients (users)
    var clients = [ ];
    @@ -95,6 +95,7 @@ wsServer.on('request', function(request) {
    color: userColor
    };
    history.push(obj);
    history.slice(-100);

    // broadcast message to all connected clients
    var json = JSON.stringify({ type:'message', data: obj });
  8. Martin Sikora revised this gist Mar 23, 2012. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion frontend.html
    Original file line number Diff line number Diff line change
    @@ -22,7 +22,7 @@
    <input type="text" id="input" disabled="disabled" />
    </div>

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
    <script src="frontend.js"></script>
    </body>
    </html>
  9. Martin Sikora revised this gist Mar 20, 2012. 1 changed file with 2 additions and 1 deletion.
    3 changes: 2 additions & 1 deletion chat-server.js
    Original file line number Diff line number Diff line change
    @@ -23,7 +23,8 @@ 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;');
    return String(str).replace(/&/g, '&amp;').replace(/</g, '&lt;')
    .replace(/>/g, '&gt;').replace(/"/g, '&quot;');
    }

    // Array with some colors
  10. Martin Sikora revised this gist Mar 19, 2012. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion chat-frontend.js
    Original file line number Diff line number Diff line change
    @@ -28,7 +28,7 @@ $(function () {

    connection.onopen = function () {
    // first we want users to enter their names
    input.removeAttr('disabled').focus();
    input.removeAttr('disabled');
    status.text('Choose name:');
    };

  11. Martin Sikora revised this gist Mar 19, 2012. 1 changed file with 9 additions and 2 deletions.
    11 changes: 9 additions & 2 deletions chat-server.js
    Original file line number Diff line number Diff line change
    @@ -19,6 +19,13 @@ 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
    @@ -68,7 +75,7 @@ wsServer.on('request', function(request) {
    if (message.type === 'utf8') { // accept only text
    if (userName === false) { // first message sent by user is their name
    // remember user name
    userName = message.utf8Data;
    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 }));
    @@ -82,7 +89,7 @@ wsServer.on('request', function(request) {
    // we want to keep history of all sent messages
    var obj = {
    time: (new Date()).getTime(),
    text: message.utf8Data,
    text: htmlEntities(message.utf8Data),
    author: userName,
    color: userColor
    };
  12. Martin Sikora revised this gist Mar 15, 2012. 1 changed file with 8 additions and 5 deletions.
    13 changes: 8 additions & 5 deletions chat-server.js
    Original file line number Diff line number Diff line change
    @@ -15,9 +15,9 @@ var http = require('http');
    * Global variables
    */
    // entire message history
    var history = new Array();
    var history = [ ];
    // list of currently connected clients (users)
    var clients = new Array();
    var clients = [ ];

    // Array with some colors
    var colors = [ 'red', 'green', 'blue', 'magenta', 'purple', 'plum', 'orange' ];
    @@ -42,12 +42,14 @@ var wsServer = new webSocketServer({
    httpServer: server
    });

    // This callback function is called every time someone tries to connect to the WebSocket 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)
    // 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;
    @@ -98,7 +100,8 @@ wsServer.on('request', function(request) {
    // user disconnected
    connection.on('close', function(connection) {
    if (userName !== false && userColor !== false) {
    console.log((new Date()) + " Peer " + connection.remoteAddress + " disconnected.");
    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
  13. Martin Sikora revised this gist Mar 15, 2012. 2 changed files with 145 additions and 0 deletions.
    117 changes: 117 additions & 0 deletions chat-frontend.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,117 @@
    $(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').focus();
    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.</p>' } ));
    };

    // 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();
    // 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.append('<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>');
    }
    });
    28 changes: 28 additions & 0 deletions frontend.html
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,28 @@
    <!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;
    border:1px solid #CCC; margin-top:10px; }
    #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="https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
    <script src="frontend.js"></script>
    </body>
    </html>
  14. Martin Sikora created this gist Mar 13, 2012.
    109 changes: 109 additions & 0 deletions chat-server.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,109 @@
    // 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
    */
    // entire message history
    var history = new Array();
    // list of currently connected clients (users)
    var clients = new Array();

    // 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. To be honest I don't understand why.
    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 = 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: message.utf8Data,
    author: userName,
    color: userColor
    };
    history.push(obj);

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

    });