(聊天室下篇)
index HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>chat-room</title>
<link rel="stylesheet" href="css/index.css">
</head>
<body>
<div class="chat-box">
<!--聊天框头部-->
<div class="chat-header">
<div class="button-box">
<input type="button" class="log-out" value="退出用户" onclick=window.open('http://127.0.0.1:3000/login.html')>
</div>
</div>
<!--聊天框主体-->
<div class="chat-body">
<!--聊天框左侧-->
<div class="chat-body-left">
<!--聊天框左侧聊天内容-->
<div class="chat-content"></div>
<!--聊天框左侧聊天输入框-->
<div class="chat-edit">
<input type="text" class="edit-box" placeholder="请输入您要发送的消息" maxlength="15">
<input type="button" class="edit-button" value="发送">
</div>
</div>
<!--聊天框右侧-->
<div class="chat-body-right">
<!--聊天框右侧头像-->
<img class="user-img" />
<!--聊天框右侧统计人数-->
<div class="online-count">在线:0</div>
<!--聊天框右侧用户名-->
<div class="user-name">用户名</div>
</div>
</div>
</div>
]
</body>
<script src="js/socket.io.js"></script>
<script src="js/index.js"></script>
</html>
index css
* {
margin: 0;
padding: 0;
font-family: "Mircrosoft Yahei";
/*border: 1px solid black;*/
}
html,
body {
width: 100%;
height: 100%;
}
/*背景色*/
body {
display: flex;
justify-content: center;
align-items: center;
background-image: url(../img/12.jpg);
/* background: linear-gradient(-135deg, #51D15B, #42A855);
background: -moz-linear-gradient(-135deg, #51D15B, #42A855);
background: -webkit-linear-gradient(-135deg, #51D15B, #42A855);
background: -o-linear-gradient(-135deg, #51D15B, #42A855); */
}
/*最外层*/
.chat-box {
width: 50%;
max-width: 720px;
min-width: 400px;
height: 80%;
min-height: 630px;
max-height: 630px;
display: flex;
flex-direction: column;
background: #fff;
box-shadow: 1px 1px 15px #333333;
}
/*头部*/
.chat-header {
margin: 5px;
box-shadow: 1px 1px 15px #7B8C99;
}
.button-box {
display: flex;
justify-content: flex-end;
}
.log-out {
height: 100%;
font-size: 14px;
font-weight: bold;
padding: 5px 15px;
color: silver;
background: #fff;
outline: none;
border: none;
border-radius: 15px;
cursor: pointer;
}
/*主体*/
.chat-body {
height: 90%;
display: flex;
flex-direction: row;
justify-content: space-around;
align-items: center;
margin: 5px;
padding: 5px;
}
/*主体左侧*/
.chat-body-left {
height: 100%;
width: 70%;
display: flex;
flex-direction: column;
justify-content: space-around;
margin: 5px;
}
/*左侧内容*/
.chat-content {
margin-bottom: 5px;
height: 100%;
box-shadow: 1px 1px 15px #7B8C99;
overflow: scroll;
background: #f5f5f5;
}
/*聊天气泡*/
.my-message-box {
display: flex;
justify-content: flex-end;
align-content: center;
margin: 5px;
}
.other-message-box {
display: flex;
justify-content: flex-start;
align-content: center;
margin: 5px;
}
.message-content {
height: 40px;
display: flex;
justify-content: center;
align-content: center;
background-color: skyblue;
padding: 5px 10px;
border-radius: 15px;
color: black;
}
.other-message-content {
height: 40px;
display: flex;
justify-content: center;
align-content: center;
background-color: #fff;
padding: 5px 10px;
border-radius: 15px;
color: black;
}
.message-content span {
padding: 10px 0px;
}
.other-message-content span {
padding: 10px 0px;
}
.message-arrow {
width: 0px;
height: 0px;
border-width: 8px;
border-style: solid;
border-color: transparent transparent transparent skyblue;
margin-top: 20px;
/* align-self: center; 居中 */
}
.other-message-arrow {
width: 0px;
height: 0px;
border-width: 8px;
border-style: solid;
border-color: transparent white transparent transparent;
margin-top: 20px;
/* align-self: center; 居中 */
}
.user-information {
display: flex;
flex-direction: column;
align-content: flex-end;
}
.other-user-information {
display: flex;
flex-direction: column;
align-content: flex-end;
}
.user-chat-img {
width: 50px;
height: 50px;
border-radius: 50%; /* 圆形头像 */
}
.user-chat-name {
color: #333333;
font-size: 16px;
text-align: center;
}
/*聊天输入框*/
.chat-edit {
margin-top: 5px;
display: flex;
justify-content: space-between;
align-items: center;
box-shadow: 1px 1px 15px #7B8C99;
overflow: hidden;
}
/*聊天输入框输入区域*/
.edit-box {
width: 80%;
height: 100%;
margin: 5px;
color: silver;
border: none;
outline: none;
}
/*聊天框输入按钮*/
.edit-button {
height: 100%;
padding: 5px 15px;
background: #fff;
color: silver;
outline: none;
border: none;
border-radius: 15px;
cursor: pointer;
font-size: 14px;
font-weight: bold;
}
/*主体右侧*/
.chat-body-right {
height: 100%;
width: 30%;
display: flex;
flex-direction: column;
/* justify-content: center; */
align-items: center;
margin: 5px;
box-shadow: 1px 1px 15px #7B8C99;
/* background-image: url(../img/11.jpeg); */
}
/*右侧内容*/
.user-name {
margin: 10px;
font-size: 18px;
font-weight: bold;
color: silver;
}
.user-img {
width: 100%;
height: 80%;
}
.online-count {
margin: 10px;
font-size: 18px;
font-weight: bold;
color: silver;
}
/*兼容小屏幕*/
@media screen and (max-width: 420px) {
.chat-box {
width: 50%;
max-width: 720px;
min-width: 300px;
height: 80%;
min-height: 530px;
max-height: 530px;
}
.chat-body-left {
height: 100%;
width: 100%;
display: flex;
flex-direction: column;
justify-content: space-around;
margin: 5px;
}
.chat-body-right {
display: none;
}
}
聊天服务器运行的 js
// 引入必须模块
var express = require(‘express’);
var app = express();
var http = require(‘http’).Server(app);
var io = require(‘socket.io’)(http);
var path = require(‘path’);
// 在线人数统计
var onlineCount = 0;
app.use(express.static(__dirname));
// 路径映射
app.get(’/login.html’, function (request, response) {
response.sendFile(‘login.html’);
});
// 当有用户连接进来时
io.on(‘connection’, function (socket) {
console.log(‘a user connected’);
// 发送给客户端在线人数
io.emit('connected', ++onlineCount);
// 当有用户断开
socket.on('disconnect', function () {
console.log('user disconnected');
// 发送给客户端断在线人数
io.emit('disconnected', --onlineCount);
console.log(onlineCount);
});
// 收到了客户端发来的消息
socket.on('message', function (message) {
// 给客户端发送消息
io.emit('message', message);
});
});
var server = http.listen(3000, function () {
console.log(‘Sever is running’);
});
插件 socket.io 文件
!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.io=e():t.io=e()}(this,function(){return function(t){function e(r){if(n[r])return n[r].exports;var o=n[r]={exports:{},id:r,loaded:!1};return t[r].call(o.exports,o,o.exports,e),o.loaded=!0,o.exports}var n={};return e.m=t,e.c=n,e.p="",e(0)}([function(t,e,n){"use strict";function r(t,e){"object"===("undefined"==typeof t?"undefined":o(t))&&(e=t,t=void 0),e=e||{};var n,r=i(t),s=r.source,u=r.id,h=r.path,f=p[u]&&h in p[u].nsps,l=e.forceNew||e["force new connection"]||!1===e.multiplex||f;return l?(c("ignoring socket cache for %s",s),n=a(s,e)):(p[u]||(c("new io instance for %s",s),p[u]=a(s,e)),n=p[u]),r.query&&!e.query&&(e.query=r.query),n.socket(r.path,e)}var o="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},i=n(1),s=n(7),a=n(13),c=n(3)("socket.io-client");t.exports=e=r;var p=e.managers={};e.protocol=s.protocol,e.connect=r,e.Manager=n(13),e.Socket=n(39)},function(t,e,n){(function(e){"use strict";function r(t,n){var r=t;n=n||e.location,null==t&&(t=n.protocol+"//"+n.host),"string"==typeof t&&("/"===t.charAt(0)&&(t="/"===t.charAt(1)?n.protocol+t:n.host+t),/^(https?|wss?):\/\//.test(t)||(i("protocol-less url %s",t),t="undefined"!=typeof n?n.protocol+"//"+t:"https://"+t),i("parse %s",t),r=o(t)),r.port||(/^(http|ws)$/.test(r.protocol)?r.port="80":/^(http|ws)s$/.test(r.protocol)&&(r.port="443")),r.path=r.path||"/";var s=r.host.indexOf(":")!==-1,a=s?"["+r.host+"]":r.host;return r.id=r.protocol+"://"+a+":"+r.port,r.href=r.protocol+"://"+a+(n&&n.port===r.port?"":":"+r.port),r}var o=n(2),i=n(3)("socket.io-client:url");t.exports=r}).call(e,function(){return this}())},function(t,e){var n=/^(?:(?![^:@]+:[^:@\/]*@)(http|https|ws|wss):\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?((?:[a-f0-9]{0,4}:){2,7}[a-f0-9]{0,4}|[^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/,r=["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"];t.exports=function(t){var e=t,o=t.indexOf("["),i=t.indexOf("]");o!=-1&&i!=-1&&(t=t.substring(0,o)+t.substring(o,i).replace(/:/g,";")+t.substring(i,t.length));for(var s=n.exec(t||""),a={},c=14;c--;)a[r[c]]=s[c]||"";return o!=-1&&i!=-1&&(a.source=e,a.host=a.host.substring(1,a.host.length-1).replace(/;/g,":"),a.authority=a.authority.replace("[","").replace("]","").replace(/;/g,":"),a.ipv6uri=!0),a}},function(t,e,n){(function(r){function o(){return!("undefined"==typeof window||!window.process||"renderer"!==window.process.type)||("undefined"!=typeof document&&document.documentElement&&document.documentElement.style&&document.documentElement.style.WebkitAppearance||"undefined"!=typeof window&&window.console&&(window.console.firebug||window.console.exception&&window.console.table)||"undefined"!=typeof navigator&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/)&&parseInt(RegExp.$1,10)>=31||"undefined"!=typeof navigator&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/))}function i(t){var n=this.useColors;if(t[0]=(n?"%c":"")+this.namespace+(n?" %c":" ")+t[0]+(n?"%c ":" ")+"+"+e.humanize(this.diff),n){var r="color: "+this.color;t.splice(1,0,r,"color: inherit");var o=0,i=0;t[0].replace(/%[a-zA-Z%]/g,function(t){"%%"!==t&&(o++,"%c"===t&&(i=o))}),t.splice(i,0,r)}}function s(){return"object"==typeof console&&console.log&&Function.prototype.apply.call(console.log,console,arguments)}function a(t){try{null==t?e.storage.removeItem("debug"):e.storage.debug=t}catch(n){}}function c(){var t;try{t=e.storage.debug}catch(n){}return!t&&"undefined"!=typeof r&&"env"in r&&(t=r.env.DEBUG),t}function p(){try{return window.localStorage}catch(t){}}e=t.exports=n(5),e.log=s,e.formatArgs=i,e.save=a,e.load=c,e.useColors=o,e.storage="undefined"!=typeof chrome&&"undefined"!=typeof chrome.storage?chrome.storage.local:p(),e.colors=["lightseagreen","forestgreen","goldenrod","dodgerblue","darkorchid","crimson"],e.formatters.j=function(t){try{return JSON.stringify(t)}catch(e){return"[UnexpectedJSONParseError]: "+e.message}},e.enable(c())}).call(e,n(4))},function(t,e){function n(){throw new Error("setTimeout has not been defined")}function r(){throw new Error("clearTimeout has not been defined")}function o(t){if(u===setTimeout)return setTimeout(t,0);if((u===n||!u)&&setTimeout)return u=setTimeout,setTimeout(t,0);try{return u(t,0)}catch(e){try{return u.call(null,t,0)}catch(e){return u.call(this,t,0)}}}function i(t){if(h===clearTimeout)return clearTimeout(t);if((h===r||!h)&&clearTimeout)return h=clearTimeout,clearTimeout(t);try{return h(t)}catch(e){try{return h.call(null,t)}catch(e){return h.call(this,t)}}}function s(){y&&l&&(y=!1,l.length?d=l.concat(d):m=-1,d.length&&a())}function a(){if(!y){var t=o(s);y=!0;for(var e=d.length;e;){for(l=d,d=[];++m<e;)l&&l[m].run();m=-1,e=d.length}l=null,y=!1,i(t)}}function c(t,e){this.fun=t,this.array=e}function p(){}var u,h,f=t.exports={};!function(){try{u="function"==typeof setTimeout?setTimeout:n}catch(t){u=n}try{h="function"==typeof clearTimeout?clearTimeout:r}catch(t){h=r}}();var l,d=[],y=!1,m=-1;f.nextTick=function(t){var e=new Array(arguments.length-1);if(arguments.length>1)for(var n=1;n<arguments.length;n++)e[n-1]=arguments[n];d.push(new c(t,e)),1!==d.length||y||o(a)},c.prototype.run=function(){this.fun.apply(null,this.array)},f.title="browser",f.browser=!0,f.env={},f.argv=[],f.version="",f.versions={},f.on=p,f.addListener=p,f.once=p,f.off=p,f.removeListener=p,f.removeAllListeners=p,f.emit=p,f.prependListener=p,f.prependOnceListener=p,f.listeners=function(t){return[]},f.binding=function(t){throw new Error("process.binding is not supported")},f.cwd=function(){return"/"},f.chdir=function(t){throw new Error("process.chdir is not supported")},f.umask=function(){return 0}},function(t,e,n){function r(t){var n,r=0;for(n in t)r=(r<<5)-r+t.charCodeAt(n),r|=0;return e.colors[Math.abs(r)%e.colors.length]}function o(t){function n(){if(n.enabled){var t=n,r=+new Date,o=r-(p||r);t.diff=o,t.prev=p,t.curr=r,p=r;for(var i=new Array(arguments.length),s=0;s<i.length;s++)i[s]=arguments[s];i[0]=e.coerce(i[0]),"string"!=typeof i[0]&&i.unshift("%O");var a=0;i[0]=i[0].replace(/%([a-zA-Z%])/g,function(n,r){if("%%"===n)return n;a++;var o=e.formatters[r];if("function"