<html>
<head>
    <title>SignalR Simple Chat</title>
    <style type="text/css">
        .container {
            background-color: #99CCFF;
            border: thick solid #808080;
            padding: 20px;
            margin: 20px;
        }
    </style>
</head>
<body>
    <div class="container">
        <input type="text" id="message" />
        <input type="button" id="sendmessage" value="Send" />
        <!--<input type="hidden" id="displayname" />-->
        <ul id="discussion"></ul>
    </div>
   
</body>
</html>
@import url(https://fonts.googleapis.com/css?family=Lato:400,700);
$green: #86BB71;
$blue: #94C2ED;
$orange: #E38968;
$gray: #92959E;
*,
*:before,
*:after {
  box-sizing: border-box;
}

body {
  background: #79A8A9;
  font: 14px/20px "Lato", Arial, "儷黑 Pro", "微軟正黑體", sans-serif;
  padding: 40px 0;
  color: white;
}

.status {
  position: absolute;
  background: #444753;
  width: 170px;
  height: 200px;
  padding: 15px;
  left: 30px;
  border-radius: 5px;
  letter-spacing: 0.075rem;
  li {
    color: $gray;
    margin: 10px 0;
  }
}

.container {
  margin: 0 auto;
  width: 490px;
  background: #444753;
  border-radius: 5px;
}

.people-list {
  width: 260px;
  float: left;
  .search {
    padding: 20px;
  }
  input {
    border-radius: 3px;
    border: none;
    padding: 14px;
    color: white;
    background: #6A6C75;
    width: 90%;
    font-size: 14px;
  }
  .fa-search {
    position: relative;
    left: -25px;
  }
  ul {
    padding: 20px;
    height: 770px;
    li {
      padding-bottom: 20px;
    }
  }
  img {
    float: left;
  }
  .about {
    float: left;
    margin-top: 8px;
  }
  .about {
    padding-left: 8px;
  }
  .status {
    color: $gray;
  }
}

.chat {
  width: 490px;
  float: right;
  background: #F2F5F8;
  border-radius: 5px;
  color: #434651;
  .chat-header {
    padding: 20px;
    border-bottom: 2px solid white;
    img {
      float: left;
    }
    .chat-about {
      float: left;
      padding-left: 10px;
      margin-top: 6px;
    }
    .chat-with {
      font-weight: bold;
      font-size: 16px;
    }
    .chat-num-messages {
      color: $gray;
    }
    .fa-star {
      float: right;
      color: #D8DADF;
      font-size: 20px;
      margin-top: 12px;
    }
  }
  .chat-history {
    padding: 30px 30px 20px;
    border-bottom: 2px solid white;
    overflow-y: scroll;
    height: 575px;
    .message-data {
      margin-bottom: 15px;
    }
    .message-data-time {
      color: lighten($gray, 8%);
      padding-left: 6px;
    }
    .message {
      color: white;
      padding: 18px 20px;
      line-height: 26px;
      font-size: 16px;
      border-radius: 7px;
      margin-bottom: 30px;
      width: 90%;
      position: relative;
      &:after {
        bottom: 100%;
        left: 7%;
        border: solid transparent;
        content: " ";
        height: 0;
        width: 0;
        position: absolute;
        pointer-events: none;
        border-bottom-color: $green;
        border-width: 10px;
        margin-left: -10px;
      }
    }
    .my-message {
      background: $green;
    }
    .other-message {
      background: $blue;
      &:after {
        border-bottom-color: $blue;
        left: 93%;
      }
    }
  }
  .chat-message {
    padding: 30px;
    textarea {
      width: 100%;
      border: none;
      padding: 10px 20px;
      font: 14px/22px "Lato", Arial, sans-serif;
      margin-bottom: 10px;
      border-radius: 5px;
      resize: none;
    }
    .fa-file-o,
    .fa-file-image-o {
      font-size: 16px;
      color: gray;
      cursor: pointer;
    }
    button {
      float: right;
      color: $blue;
      font-size: 16px;
      text-transform: uppercase;
      border: none;
      cursor: pointer;
      font-weight: bold;
      background: #F2F5F8;
      &:hover {
        color: darken($blue, 7%);
      }
    }
  }
}

.online,
.offline,
.me {
  margin-right: 3px;
  font-size: 10px;
}

.online {
  color: $green;
}

.offline {
  color: $orange;
}

.me {
  color: $blue;
}

.align-left {
  text-align: left;
}

.align-right {
  text-align: right;
}

.float-right {
  float: right;
}

.clearfix:after {
  visibility: hidden;
  display: block;
  font-size: 0;
  content: " ";
  clear: both;
  height: 0;
}

.hidden {
  opacity: 0;
  display: none;
}
View Compiled
        document.addEventListener('DOMContentLoaded', function () {
            var messageInput = document.getElementById('message');
            // Get the user name and store it to prepend to messages.
            var name = prompt('Enter your name:', '');
            // Set initial focus to message input box.
            messageInput.focus();
            // Start the connection.
            startConnection('https://localhost:44380/chat', function(connection) {
                // Create a function that the hub can call to broadcast messages.
                connection.on('broadcastMessage', function (name, message) {
                    // Html encode display name and message.
                    var encodedName = name;
                    var encodedMsg = message;
                    // Add the message to the page.
                    var liElement = document.createElement('li');
                    liElement.innerHTML = '<strong>' + encodedName + '</strong>:&nbsp;&nbsp;' + encodedMsg;
                    document.getElementById('discussion').appendChild(liElement);
                });
            })
            .then(function(connection) {
                console.log('connection started');
                document.getElementById('sendmessage').addEventListener('click', function (event) {
                    // Call the Send method on the hub.
                    connection.invoke('send', name, messageInput.value);
                    // Clear text box and reset focus for next comment.
                    messageInput.value = '';
                    messageInput.focus();
                    event.preventDefault();
                });
            })
            .catch(error => {
                console.error(error.message);
            });
            // Starts a connection with transport fallback - if the connection cannot be started using
            // the webSockets transport the function will fallback to the serverSentEvents transport and
            // if this does not work it will try longPolling. If the connection cannot be started using
            // any of the available transports the function will return a rejected Promise.
            function startConnection(url, configureConnection) {
                return function start(transport) {
                    console.log(`Starting connection using ${signalR.TransportType[transport]} transport`)
                    var connection = new signalR.HubConnection(url, {transport: transport,useDefaultPath: false});
                    if (configureConnection && typeof configureConnection === 'function') {
                        configureConnection(connection);
                    }
                    return connection.start()
                        .then(function() {
                            return connection;
                        })
                        .catch(function(error) {
                            console.log(`Cannot start the connection use ${signalR.TransportType[transport]} transport. ${error.message}`);
                            if (transport !== signalR.TransportType.LongPolling) {
                                return start(transport + 1);
                            }
                            return Promise.reject(error);
                        });
                }(signalR.TransportType.WebSockets);
            }
        });
View Compiled
Run Pen

External CSS

  1. https://maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.0/jquery.min.js
  2. https://rawgit.com/wpitallo/scripts/master/signalr-client-1.0.0-alpha2-final.js