├── README.md ├── app.js ├── doc ├── 1508489067(1).png └── 1508489279(1).png ├── package.json └── www ├── css └── index.css ├── index.html └── js ├── index.js └── socket.io.js /README.md: -------------------------------------------------------------------------------- 1 | # express-socket 2 | > express+socket.io聊天室 3 | 4 | #### 完成 5 | - [x] 登陆提醒 6 | - [x] 退出提醒 7 | - [x] 在线聊天 8 | - [x] 在线人数统计 9 | 10 | #### todo 11 | - [ ] 多个房间 12 | - [ ] 单独聊天 13 | - [ ] 头像 14 | 15 | ## 项目大概 16 | 17 | ![](./doc/1508489067(1).png) 18 | ![](./doc/1508489279(1).png) 19 | 20 | ## 安装运行 21 | ``` 22 | git clone https://github.com/pengrongjie/express-socket.git 23 | cd express-socket 24 | cnpm install 25 | node app.js 26 | ``` 27 | > http://localhost:80/ 28 | -------------------------------------------------------------------------------- /app.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var app = express(); 3 | var server = require('http').createServer(app); 4 | var io = require('socket.io').listen(server); 5 | // 存储用户 6 | var users = []; 7 | 8 | app.use('/',express.static(__dirname + '/www')); 9 | server.listen(80); 10 | console.log("http://localhost:80/"); 11 | 12 | // socket.io 13 | 14 | io.on('connection', function(socket){ 15 | // 登录 16 | socket.on('login', function(nickname){ 17 | if(users.indexOf(nickname) > -1){ 18 | socket.emit('loginFailed'); 19 | }else{ 20 | socket.nickname = nickname; 21 | users.push(nickname); 22 | console.log(nickname + '已经上线了,总在线人数为:' + users.length); 23 | socket.emit('loginSuccess'); 24 | io.sockets.emit('system', nickname, users.length, 'login'); 25 | } 26 | }) 27 | 28 | //断开连接,实时更新users数组 29 | socket.on('disconnect', function(){ 30 | var index = users.indexOf(socket.nickname); 31 | users.splice(index, 1); 32 | io.sockets.emit('system', socket.nickname, users.length, 'logout'); 33 | console.log(socket.nickname + '已经下线了'); 34 | console.log(users); 35 | }) 36 | // 发送消息 37 | socket.on('msgSend', function(msg){ 38 | socket.broadcast.emit('newMsg', socket.nickname, msg); 39 | }) 40 | }) 41 | -------------------------------------------------------------------------------- /doc/1508489067(1).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pengrongjie/express-socket/6032259179cd2294f0635ca7e73be543cf64a148/doc/1508489067(1).png -------------------------------------------------------------------------------- /doc/1508489279(1).png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pengrongjie/express-socket/6032259179cd2294f0635ca7e73be543cf64a148/doc/1508489279(1).png -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "socket7ss", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "express": "^4.16.2", 13 | "socket.io": "^2.0.3" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /www/css/index.css: -------------------------------------------------------------------------------- 1 | * { 2 | padding: 0; 3 | margin: 0; 4 | } 5 | ul { 6 | list-style: none; 7 | } 8 | a { 9 | text-decoration: none; 10 | } 11 | button, 12 | input { 13 | outline: none; 14 | } 15 | body { 16 | padding: 50px 0; 17 | background-color: #f1f1f1; 18 | } 19 | /*头部*/ 20 | body .header { 21 | position: fixed; 22 | top: 0; 23 | left: 0; 24 | height: 50px; 25 | width: 100%; 26 | text-align: center; 27 | line-height: 50px; 28 | color: #fff; 29 | background-color: #00aaee; 30 | z-index: 999; 31 | } 32 | /*登录框*/ 33 | body .loginWrapper{ 34 | position: fixed; 35 | top: 0; 36 | left: 0; 37 | bottom: 0; 38 | right: 0; 39 | text-align: center; 40 | padding-top: 40%; 41 | background-color: rgba(0,0,0,.1); 42 | z-index: 1000; 43 | } 44 | body .loginWrapper .info{ 45 | height: 50px; 46 | line-height: 50px; 47 | } 48 | body .loginWrapper input{ 49 | display: block; 50 | height: 40px; 51 | width: 80%; 52 | line-height: 40px; 53 | margin: 20px auto; 54 | text-align: center; 55 | border: 1px solid #ccc; 56 | border-radius: 4px; 57 | } 58 | body .loginWrapper input:focus{ 59 | border: 1px solid #00aaee; 60 | } 61 | body .loginWrapper input.button{ 62 | background-color: #00aaee; 63 | color: #fff; 64 | } 65 | /*输入框*/ 66 | body .control{ 67 | position: fixed; 68 | display: flex; 69 | bottom: 0; 70 | left: 0; 71 | width: 100%; 72 | height: 40px; 73 | z-index: 1000; 74 | } 75 | body .control input { 76 | flex: 1; 77 | padding-left: 10px; 78 | background-color: #fff; 79 | border: 1px solid #ccc; 80 | border-radius: 4px; 81 | } 82 | body .control input:focus{ 83 | border: 1px solid #00aaee; 84 | } 85 | body .control button{ 86 | flex: 0 0 60px; 87 | width: 60px; 88 | background-color: #00aaee; 89 | color: #fff; 90 | border: 1px solid #00aaee; 91 | border-radius: 4px; 92 | } 93 | /*系统消息*/ 94 | body .historyMsg{ 95 | 96 | } 97 | body .historyMsg .system{ 98 | height: 40px; 99 | line-height: 40px; 100 | text-align: center; 101 | } 102 | body .historyMsg .system .nickname{ 103 | color: #00aaee; 104 | } 105 | /*我自己发送的消息*/ 106 | body .historyMsg .myMsg { 107 | margin: 0 10px 10px 0; 108 | text-align: right; 109 | } 110 | body .historyMsg .myMsg .timespan{ 111 | display: block; 112 | font-size: 12px; 113 | color: #333; 114 | } 115 | body .historyMsg .myMsg .nickname{ 116 | display: none; 117 | } 118 | body .historyMsg .myMsg .text{ 119 | display: inline-block; 120 | height: 30px; 121 | line-height: 30px; 122 | margin-top: 5px; 123 | padding: 0 8px; 124 | background-color: #00aaee; 125 | color: #fff; 126 | border: 1px solid #00aaee; 127 | border-radius: 10px; 128 | } 129 | 130 | /*别人发送的消息*/ 131 | body .historyMsg .newMsg{ 132 | margin: 0 0 10px 10px; 133 | } 134 | body .historyMsg .newMsg .timespan{ 135 | display: block; 136 | font-size: 12px; 137 | color: #333; 138 | } 139 | body .historyMsg .newMsg .nickname{ 140 | display: inline-block; 141 | height: 30px; 142 | line-height: 30px; 143 | margin-top: 5px; 144 | padding: 0 4px; 145 | background-color: #fff; 146 | color: #00aaee; 147 | border: 1px solid #fff; 148 | border-radius: 10px 0 0 10px;; 149 | } 150 | body .historyMsg .newMsg .text{ 151 | display: inline-block; 152 | height: 30px; 153 | line-height: 30px; 154 | margin-top: 5px; 155 | padding: 0 4px 0 4px; 156 | background-color: #fff; 157 | color: #333; 158 | border: 1px solid #fff; 159 | border-radius: 0 10px 10px 0; 160 | } 161 | .nickWrapper{ 162 | display: none; 163 | } 164 | -------------------------------------------------------------------------------- /www/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | express+socket聊天室 7 | 8 | 9 | 10 | 11 |
12 | express+socket聊天室(0) 13 |
14 | 15 | 16 |
17 | 18 |
19 | 20 | 21 |
22 | 23 | 24 | 25 |
26 | 27 | 28 |
29 |

欢迎来到express+socket聊天室

30 |
31 | 32 | 33 |
34 |
35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /www/js/index.js: -------------------------------------------------------------------------------- 1 | window.onload = function(){ 2 | var kchat = new KChat(); 3 | kchat.init(); 4 | }; 5 | 6 | var KChat = function(){ 7 | this.socket = null; 8 | }; 9 | 10 | KChat.prototype = { 11 | 12 | init: function(){ 13 | var that = this; 14 | 15 | //建立与服务器的socket连接 16 | this.socket = io.connect(); 17 | 18 | //监听socket的connect事件,此事件表示连接已经建立 19 | this.socket.on('connect',function(){ 20 | document.getElementById('info').textContent = '欢迎来到express+socket聊天室'; 21 | document.getElementById('nickWrapper').style.display = 'block'; 22 | document.getElementById('nicknameInput'); 23 | }); 24 | 25 | //登录失败 26 | this.socket.on('loginFailed', function(){ 27 | var info = document.getElementById('info'); 28 | info.textContent = '该呢称已存在,请重新输入新的呢称'; 29 | info.style.color = 'red'; 30 | }); 31 | 32 | //登录成功 33 | this.socket.on('loginSuccess', function(){ 34 | document.title = '聊天室成员(' + document.getElementById('nicknameInput').value + ')'; 35 | document.getElementById('loginWrapper').style.display = 'none'; 36 | document.getElementById('inputMsg').focus(); 37 | }); 38 | 39 | //系统人数更新,提示用户新加入或离开 40 | this.socket.on('system', function(nickname, count, type){ 41 | that._systemInfo(nickname, count, type); 42 | }); 43 | 44 | //收到新消息 45 | this.socket.on('newMsg', function(nickname, msg){ 46 | that._displayNewMsg(nickname, msg, 'newMsg'); 47 | // alert(nickname + ': ' + msg); 48 | }); 49 | 50 | 51 | //设置登陆按钮和nicknameInput的监听事件(click&keyup)login 52 | document.getElementById('loginBtn').addEventListener('click', function(){ 53 | var nickname = document.getElementById('nicknameInput').value.trim(); 54 | var info = document.getElementById('info'); 55 | var nicknameInput = document.getElementById('nicknameInput'); 56 | 57 | 58 | if (nickname.length == 0 || nickname.length > 10){ 59 | //如果用户名为空或超出长度限制 60 | info.textContent = '呢称不能为空,并且不能超过10个字符'; 61 | info.style.color = 'red'; 62 | nicknameInput.value = ''; 63 | nicknameInput.focus(); 64 | }else{ 65 | //用户名合法 66 | that.socket.emit('login', nickname); 67 | 68 | } 69 | }, false); 70 | document.getElementById('nicknameInput').addEventListener('keyup', function(e){ 71 | if (e.keyCode == 13){ 72 | var nicknameInput = document.getElementById('nicknameInput'); 73 | var nickname = nicknameInput.value.trim(); 74 | var info = document.getElementById('info'); 75 | 76 | 77 | if (nickname.length == 0 || nickname.length > 10){ 78 | //如果用户名为空或超出长度限制 79 | info.textContent = '该呢称已存在,请重新输入新的呢称'; 80 | info.style.color = 'red'; 81 | nicknameInput.value = ''; 82 | nicknameInput.focus(); 83 | }else{ 84 | //用户名合法 85 | that.socket.emit('login', nickname); 86 | } 87 | } 88 | }, false); 89 | 90 | 91 | //发送按钮和inputMsg监听事件 92 | document.getElementById('sendBtn').addEventListener('click', function(){ 93 | //1.获取用户输入 94 | //2.检测是否超出长度限制 95 | //3.通过检测则直接广播 96 | var inputMsg = document.getElementById('inputMsg'); 97 | var msg = inputMsg.value.replace('\n',''); 98 | if (msg == ''){ 99 | inputMsg.focus(); 100 | return; 101 | } 102 | 103 | if (msg.length > 15){ 104 | alert('Sorry啊,字数上限为15字:)'); 105 | inputMsg.focus(); 106 | }else{ 107 | that.socket.emit('msgSend', msg); 108 | inputMsg.value = ''; 109 | that._displayNewMsg('', msg, 'myMsg'); 110 | } 111 | }, false); 112 | 113 | document.getElementById('inputMsg').addEventListener('keyup', function(e){ 114 | if (e.keyCode == 13){ 115 | var inputMsg = document.getElementById('inputMsg'); 116 | inputMsg.value = inputMsg.value.replace('\n',''); 117 | var msg = inputMsg.value.replace('\n',''); 118 | if (msg == ''){ 119 | inputMsg.focus(); 120 | return; 121 | } 122 | 123 | if (msg.length > 15){ 124 | alert('Sorry啊,字数上限为15字:)'); 125 | inputMsg.focus(); 126 | }else{ 127 | that.socket.emit('msgSend', msg); 128 | inputMsg.value = ''; 129 | inputMsg.focus(); 130 | that._displayNewMsg('', msg, 'myMsg'); 131 | } 132 | } 133 | }, false); 134 | 135 | 136 | }, 137 | 138 | _displayNewMsg: function(nickname, msg, who){ 139 | var historyMsg = document.getElementById('historyMsg'); 140 | 141 | var p = document.createElement('p'); 142 | p.setAttribute('class',who); 143 | 144 | var span_nickname = document.createElement('span'); 145 | span_nickname.setAttribute('class','nickname'); 146 | span_nickname.textContent = nickname + ':'; 147 | 148 | var span_timespan = document.createElement('span'); 149 | span_timespan.setAttribute('class','timespan'); 150 | var time = new Date().toTimeString().substr(0, 8); 151 | span_timespan.textContent = time; 152 | 153 | // var text = document.createTextNode(msg); 154 | var span_text = document.createElement('span'); 155 | span_text.setAttribute('class','text'); 156 | span_text.textContent = msg; 157 | 158 | p.appendChild(span_timespan); 159 | p.appendChild(span_nickname); 160 | p.appendChild(span_text); 161 | 162 | historyMsg.appendChild(p); 163 | 164 | //控制滚动条自动滚到底部 165 | historyMsg.scrollTop = historyMsg.scrollHeight; 166 | 167 | }, 168 | 169 | _systemInfo: function(nickname, count, type){ 170 | 171 | document.getElementById('status').textContent = count; 172 | 173 | var historyMsg = document.getElementById('historyMsg'); 174 | //

kyrieliu加入了群聊

175 | var p = document.createElement('p'); 176 | var span = document.createElement('span'); 177 | var text; 178 | if (type == 'login'){ 179 | text = document.createTextNode(' 加入了群聊'); 180 | }else if (type == 'logout'){ 181 | text = document.createTextNode(' 离开了群聊'); 182 | } 183 | 184 | p.setAttribute('class','system'); 185 | span.setAttribute('class','nickname'); 186 | span.textContent = nickname; 187 | 188 | p.appendChild(span); 189 | p.appendChild(text); 190 | 191 | 192 | historyMsg.appendChild(p); 193 | } 194 | 195 | }; 196 | -------------------------------------------------------------------------------- /www/js/socket.io.js: -------------------------------------------------------------------------------- 1 | !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=[];++m1)for(var n=1;n100)){var e=/^((?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|y)?$/i.exec(t);if(e){var n=parseFloat(e[1]),r=(e[2]||"ms").toLowerCase();switch(r){case"years":case"year":case"yrs":case"yr":case"y":return n*u;case"days":case"day":case"d":return n*p;case"hours":case"hour":case"hrs":case"hr":case"h":return n*c;case"minutes":case"minute":case"mins":case"min":case"m":return n*a;case"seconds":case"second":case"secs":case"sec":case"s":return n*s;case"milliseconds":case"millisecond":case"msecs":case"msec":case"ms":return n;default:return}}}}function r(t){return t>=p?Math.round(t/p)+"d":t>=c?Math.round(t/c)+"h":t>=a?Math.round(t/a)+"m":t>=s?Math.round(t/s)+"s":t+"ms"}function o(t){return i(t,p,"day")||i(t,c,"hour")||i(t,a,"minute")||i(t,s,"second")||t+" ms"}function i(t,e,n){if(!(t0)return n(t);if("number"===i&&isNaN(t)===!1)return e["long"]?o(t):r(t);throw new Error("val is not a non-empty string or a valid number. val="+JSON.stringify(t))}},function(t,e,n){function r(){}function o(t){var n=""+t.type;return e.BINARY_EVENT!==t.type&&e.BINARY_ACK!==t.type||(n+=t.attachments+"-"),t.nsp&&"/"!==t.nsp&&(n+=t.nsp+","),null!=t.id&&(n+=t.id),null!=t.data&&(n+=JSON.stringify(t.data)),h("encoded %j as %s",t,n),n}function i(t,e){function n(t){var n=d.deconstructPacket(t),r=o(n.packet),i=n.buffers;i.unshift(r),e(i)}d.removeBlobs(t,n)}function s(){this.reconstructor=null}function a(t){var n=0,r={type:Number(t.charAt(0))};if(null==e.types[r.type])return u();if(e.BINARY_EVENT===r.type||e.BINARY_ACK===r.type){for(var o="";"-"!==t.charAt(++n)&&(o+=t.charAt(n),n!=t.length););if(o!=Number(o)||"-"!==t.charAt(n))throw new Error("Illegal attachments");r.attachments=Number(o)}if("/"===t.charAt(n+1))for(r.nsp="";++n;){var i=t.charAt(n);if(","===i)break;if(r.nsp+=i,n===t.length)break}else r.nsp="/";var s=t.charAt(n+1);if(""!==s&&Number(s)==s){for(r.id="";++n;){var i=t.charAt(n);if(null==i||Number(i)!=i){--n;break}if(r.id+=t.charAt(n),n===t.length)break}r.id=Number(r.id)}return t.charAt(++n)&&(r=c(r,t.substr(n))),h("decoded %s as %j",t,r),r}function c(t,e){try{t.data=JSON.parse(e)}catch(n){return u()}return t}function p(t){this.reconPack=t,this.buffers=[]}function u(){return{type:e.ERROR,data:"parser error"}}var h=n(3)("socket.io-parser"),f=n(8),l=n(9),d=n(11),y=n(12);e.protocol=4,e.types=["CONNECT","DISCONNECT","EVENT","ACK","ERROR","BINARY_EVENT","BINARY_ACK"],e.CONNECT=0,e.DISCONNECT=1,e.EVENT=2,e.ACK=3,e.ERROR=4,e.BINARY_EVENT=5,e.BINARY_ACK=6,e.Encoder=r,e.Decoder=s,r.prototype.encode=function(t,n){if(t.type!==e.EVENT&&t.type!==e.ACK||!l(t.data)||(t.type=t.type===e.EVENT?e.BINARY_EVENT:e.BINARY_ACK),h("encoding packet %j",t),e.BINARY_EVENT===t.type||e.BINARY_ACK===t.type)i(t,n);else{var r=o(t);n([r])}},f(s.prototype),s.prototype.add=function(t){var n;if("string"==typeof t)n=a(t),e.BINARY_EVENT===n.type||e.BINARY_ACK===n.type?(this.reconstructor=new p(n),0===this.reconstructor.reconPack.attachments&&this.emit("decoded",n)):this.emit("decoded",n);else{if(!y(t)&&!t.base64)throw new Error("Unknown type: "+t);if(!this.reconstructor)throw new Error("got binary data when not reconstructing a packet");n=this.reconstructor.takeBinaryData(t),n&&(this.reconstructor=null,this.emit("decoded",n))}},s.prototype.destroy=function(){this.reconstructor&&this.reconstructor.finishedReconstruction()},p.prototype.takeBinaryData=function(t){if(this.buffers.push(t),this.buffers.length===this.reconPack.attachments){var e=d.reconstructPacket(this.reconPack,this.buffers);return this.finishedReconstruction(),e}return null},p.prototype.finishedReconstruction=function(){this.reconPack=null,this.buffers=[]}},function(t,e,n){function r(t){if(t)return o(t)}function o(t){for(var e in r.prototype)t[e]=r.prototype[e];return t}t.exports=r,r.prototype.on=r.prototype.addEventListener=function(t,e){return this._callbacks=this._callbacks||{},(this._callbacks["$"+t]=this._callbacks["$"+t]||[]).push(e),this},r.prototype.once=function(t,e){function n(){this.off(t,n),e.apply(this,arguments)}return n.fn=e,this.on(t,n),this},r.prototype.off=r.prototype.removeListener=r.prototype.removeAllListeners=r.prototype.removeEventListener=function(t,e){if(this._callbacks=this._callbacks||{},0==arguments.length)return this._callbacks={},this;var n=this._callbacks["$"+t];if(!n)return this;if(1==arguments.length)return delete this._callbacks["$"+t],this;for(var r,o=0;o0&&!this.encoding){var t=this.packetBuffer.shift();this.packet(t)}},r.prototype.cleanup=function(){h("cleanup");for(var t=this.subs.length,e=0;e=this._reconnectionAttempts)h("reconnect failed"),this.backoff.reset(),this.emitAll("reconnect_failed"),this.reconnecting=!1;else{var e=this.backoff.duration();h("will wait %dms before reconnect attempt",e),this.reconnecting=!0;var n=setTimeout(function(){t.skipReconnect||(h("attempting reconnect"),t.emitAll("reconnect_attempt",t.backoff.attempts),t.emitAll("reconnecting",t.backoff.attempts),t.skipReconnect||t.open(function(e){e?(h("reconnect attempt error"),t.reconnecting=!1,t.reconnect(),t.emitAll("reconnect_error",e.data)):(h("reconnect success"),t.onreconnect())}))},e);this.subs.push({destroy:function(){clearTimeout(n)}})}},r.prototype.onreconnect=function(){var t=this.backoff.attempts;this.reconnecting=!1,this.backoff.reset(),this.updateSocketIds(),this.emitAll("reconnect",t)}},function(t,e,n){t.exports=n(15)},function(t,e,n){t.exports=n(16),t.exports.parser=n(23)},function(t,e,n){(function(e){function r(t,n){if(!(this instanceof r))return new r(t,n);n=n||{},t&&"object"==typeof t&&(n=t,t=null),t?(t=u(t),n.hostname=t.host,n.secure="https"===t.protocol||"wss"===t.protocol,n.port=t.port,t.query&&(n.query=t.query)):n.host&&(n.hostname=u(n.host).host),this.secure=null!=n.secure?n.secure:e.location&&"https:"===location.protocol,n.hostname&&!n.port&&(n.port=this.secure?"443":"80"),this.agent=n.agent||!1,this.hostname=n.hostname||(e.location?location.hostname:"localhost"),this.port=n.port||(e.location&&location.port?location.port:this.secure?443:80),this.query=n.query||{},"string"==typeof this.query&&(this.query=f.decode(this.query)),this.upgrade=!1!==n.upgrade,this.path=(n.path||"/engine.io").replace(/\/$/,"")+"/",this.forceJSONP=!!n.forceJSONP,this.jsonp=!1!==n.jsonp,this.forceBase64=!!n.forceBase64,this.enablesXDR=!!n.enablesXDR,this.timestampParam=n.timestampParam||"t",this.timestampRequests=n.timestampRequests,this.transports=n.transports||["polling","websocket"],this.transportOptions=n.transportOptions||{},this.readyState="",this.writeBuffer=[],this.prevBufferLen=0,this.policyPort=n.policyPort||843,this.rememberUpgrade=n.rememberUpgrade||!1,this.binaryType=null,this.onlyBinaryUpgrades=n.onlyBinaryUpgrades,this.perMessageDeflate=!1!==n.perMessageDeflate&&(n.perMessageDeflate||{}),!0===this.perMessageDeflate&&(this.perMessageDeflate={}),this.perMessageDeflate&&null==this.perMessageDeflate.threshold&&(this.perMessageDeflate.threshold=1024),this.pfx=n.pfx||null,this.key=n.key||null,this.passphrase=n.passphrase||null,this.cert=n.cert||null,this.ca=n.ca||null,this.ciphers=n.ciphers||null,this.rejectUnauthorized=void 0===n.rejectUnauthorized||n.rejectUnauthorized,this.forceNode=!!n.forceNode;var o="object"==typeof e&&e;o.global===o&&(n.extraHeaders&&Object.keys(n.extraHeaders).length>0&&(this.extraHeaders=n.extraHeaders),n.localAddress&&(this.localAddress=n.localAddress)),this.id=null,this.upgrades=null,this.pingInterval=null,this.pingTimeout=null,this.pingIntervalTimer=null,this.pingTimeoutTimer=null,this.open()}function o(t){var e={};for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n]);return e}var i=n(17),s=n(8),a=n(3)("engine.io-client:socket"),c=n(37),p=n(23),u=n(2),h=n(38),f=n(31);t.exports=r,r.priorWebsocketSuccess=!1,s(r.prototype),r.protocol=p.protocol,r.Socket=r,r.Transport=n(22),r.transports=n(17),r.parser=n(23),r.prototype.createTransport=function(t){a('creating transport "%s"',t);var e=o(this.query);e.EIO=p.protocol,e.transport=t;var n=this.transportOptions[t]||{};this.id&&(e.sid=this.id);var r=new i[t]({query:e,socket:this,agent:n.agent||this.agent,hostname:n.hostname||this.hostname,port:n.port||this.port,secure:n.secure||this.secure,path:n.path||this.path,forceJSONP:n.forceJSONP||this.forceJSONP,jsonp:n.jsonp||this.jsonp,forceBase64:n.forceBase64||this.forceBase64,enablesXDR:n.enablesXDR||this.enablesXDR,timestampRequests:n.timestampRequests||this.timestampRequests,timestampParam:n.timestampParam||this.timestampParam,policyPort:n.policyPort||this.policyPort,pfx:n.pfx||this.pfx,key:n.key||this.key,passphrase:n.passphrase||this.passphrase,cert:n.cert||this.cert,ca:n.ca||this.ca,ciphers:n.ciphers||this.ciphers,rejectUnauthorized:n.rejectUnauthorized||this.rejectUnauthorized,perMessageDeflate:n.perMessageDeflate||this.perMessageDeflate,extraHeaders:n.extraHeaders||this.extraHeaders,forceNode:n.forceNode||this.forceNode,localAddress:n.localAddress||this.localAddress,requestTimeout:n.requestTimeout||this.requestTimeout,protocols:n.protocols||void 0});return r},r.prototype.open=function(){var t;if(this.rememberUpgrade&&r.priorWebsocketSuccess&&this.transports.indexOf("websocket")!==-1)t="websocket";else{if(0===this.transports.length){var e=this;return void setTimeout(function(){e.emit("error","No transports available")},0)}t=this.transports[0]}this.readyState="opening";try{t=this.createTransport(t)}catch(n){return this.transports.shift(),void this.open()}t.open(),this.setTransport(t)},r.prototype.setTransport=function(t){a("setting transport %s",t.name);var e=this;this.transport&&(a("clearing existing transport %s",this.transport.name),this.transport.removeAllListeners()),this.transport=t,t.on("drain",function(){e.onDrain()}).on("packet",function(t){e.onPacket(t)}).on("error",function(t){e.onError(t)}).on("close",function(){e.onClose("transport close")})},r.prototype.probe=function(t){function e(){if(f.onlyBinaryUpgrades){var e=!this.supportsBinary&&f.transport.supportsBinary;h=h||e}h||(a('probe transport "%s" opened',t),u.send([{type:"ping",data:"probe"}]),u.once("packet",function(e){if(!h)if("pong"===e.type&&"probe"===e.data){if(a('probe transport "%s" pong',t),f.upgrading=!0,f.emit("upgrading",u),!u)return;r.priorWebsocketSuccess="websocket"===u.name,a('pausing current transport "%s"',f.transport.name),f.transport.pause(function(){h||"closed"!==f.readyState&&(a("changing transport and sending upgrade packet"),p(),f.setTransport(u),u.send([{type:"upgrade"}]),f.emit("upgrade",u),u=null,f.upgrading=!1,f.flush())})}else{a('probe transport "%s" failed',t);var n=new Error("probe error");n.transport=u.name,f.emit("upgradeError",n)}}))}function n(){h||(h=!0,p(),u.close(),u=null)}function o(e){var r=new Error("probe error: "+e);r.transport=u.name,n(),a('probe transport "%s" failed because of error: %s',t,e),f.emit("upgradeError",r)}function i(){o("transport closed")}function s(){o("socket closed")}function c(t){u&&t.name!==u.name&&(a('"%s" works - aborting "%s"',t.name,u.name),n())}function p(){u.removeListener("open",e),u.removeListener("error",o),u.removeListener("close",i),f.removeListener("close",s),f.removeListener("upgrading",c)}a('probing transport "%s"',t);var u=this.createTransport(t,{probe:1}),h=!1,f=this;r.priorWebsocketSuccess=!1,u.once("open",e),u.once("error",o),u.once("close",i),this.once("close",s),this.once("upgrading",c),u.open()},r.prototype.onOpen=function(){if(a("socket open"),this.readyState="open",r.priorWebsocketSuccess="websocket"===this.transport.name,this.emit("open"),this.flush(),"open"===this.readyState&&this.upgrade&&this.transport.pause){a("starting upgrade probes");for(var t=0,e=this.upgrades.length;t1?{type:b[o],data:t.substring(1)}:{type:b[o]}:w}var i=new Uint8Array(t),o=i[0],s=f(t,1);return k&&"blob"===n&&(s=new k([s])),{type:b[o],data:s}},e.decodeBase64Packet=function(t,e){var n=b[t.charAt(0)];if(!p)return{type:n,data:{base64:!0,data:t.substr(1)}};var r=p.decode(t.substr(1));return"blob"===e&&k&&(r=new k([r])),{type:n,data:r}},e.encodePayload=function(t,n,r){function o(t){return t.length+":"+t}function i(t,r){e.encodePacket(t,!!s&&n,!1,function(t){r(null,o(t))})}"function"==typeof n&&(r=n,n=null);var s=h(t);return n&&s?k&&!g?e.encodePayloadAsBlob(t,r):e.encodePayloadAsArrayBuffer(t,r):t.length?void c(t,i,function(t,e){return r(e.join(""))}):r("0:")},e.decodePayload=function(t,n,r){if("string"!=typeof t)return e.decodePayloadAsBinary(t,n,r);"function"==typeof n&&(r=n,n=null);var o;if(""===t)return r(w,0,1);for(var i,s,a="",c=0,p=t.length;c0;){for(var s=new Uint8Array(o),a=0===s[0],c="",p=1;255!==s[p];p++){if(c.length>310)return r(w,0,1);c+=s[p]}o=f(o,2+c.length),c=parseInt(c);var u=f(o,0,c);if(a)try{u=String.fromCharCode.apply(null,new Uint8Array(u))}catch(h){var l=new Uint8Array(u);u="";for(var p=0;pr&&(n=r),e>=r||e>=n||0===r)return new ArrayBuffer(0);for(var o=new Uint8Array(t),i=new Uint8Array(n-e),s=e,a=0;s=55296&&e<=56319&&o65535&&(e-=65536,o+=w(e>>>10&1023|55296),e=56320|1023&e),o+=w(e);return o}function c(t,e){if(t>=55296&&t<=57343){if(e)throw Error("Lone surrogate U+"+t.toString(16).toUpperCase()+" is not a scalar value");return!1}return!0}function p(t,e){return w(t>>e&63|128)}function u(t,e){if(0==(4294967168&t))return w(t);var n="";return 0==(4294965248&t)?n=w(t>>6&31|192):0==(4294901760&t)?(c(t,e)||(t=65533),n=w(t>>12&15|224),n+=p(t,6)):0==(4292870144&t)&&(n=w(t>>18&7|240),n+=p(t,12),n+=p(t,6)),n+=w(63&t|128)}function h(t,e){e=e||{};for(var n,r=!1!==e.strict,o=s(t),i=o.length,a=-1,c="";++a=v)throw Error("Invalid byte index");var t=255&g[b];if(b++,128==(192&t))return 63&t;throw Error("Invalid continuation byte")}function l(t){var e,n,r,o,i;if(b>v)throw Error("Invalid byte index");if(b==v)return!1;if(e=255&g[b],b++,0==(128&e))return e;if(192==(224&e)){if(n=f(),i=(31&e)<<6|n,i>=128)return i;throw Error("Invalid continuation byte")}if(224==(240&e)){if(n=f(),r=f(),i=(15&e)<<12|n<<6|r,i>=2048)return c(i,t)?i:65533;throw Error("Invalid continuation byte")}if(240==(248&e)&&(n=f(),r=f(),o=f(),i=(7&e)<<18|n<<12|r<<6|o,i>=65536&&i<=1114111))return i;throw Error("Invalid UTF-8 detected")}function d(t,e){e=e||{};var n=!1!==e.strict;g=s(t),v=g.length,b=0;for(var r,o=[];(r=l(n))!==!1;)o.push(r);return a(o)}var y="object"==typeof e&&e,m=("object"==typeof t&&t&&t.exports==y&&t,"object"==typeof o&&o);m.global!==m&&m.window!==m||(i=m);var g,v,b,w=String.fromCharCode,k={version:"2.1.2",encode:h,decode:d};r=function(){return k}.call(e,n,e,t),!(void 0!==r&&(t.exports=r))}(this)}).call(e,n(28)(t),function(){return this}())},function(t,e){t.exports=function(t){return t.webpackPolyfill||(t.deprecate=function(){},t.paths=[],t.children=[],t.webpackPolyfill=1),t}},function(t,e){!function(){"use strict";for(var t="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",n=new Uint8Array(256),r=0;r>2],i+=t[(3&r[n])<<4|r[n+1]>>4],i+=t[(15&r[n+1])<<2|r[n+2]>>6],i+=t[63&r[n+2]];return o%3===2?i=i.substring(0,i.length-1)+"=":o%3===1&&(i=i.substring(0,i.length-2)+"=="),i},e.decode=function(t){var e,r,o,i,s,a=.75*t.length,c=t.length,p=0;"="===t[t.length-1]&&(a--,"="===t[t.length-2]&&a--);var u=new ArrayBuffer(a),h=new Uint8Array(u);for(e=0;e>4,h[p++]=(15&o)<<4|i>>2,h[p++]=(3&i)<<6|63&s;return u}}()},function(t,e){(function(e){function n(t){for(var e=0;e0);return e}function r(t){var e=0;for(u=0;u';i=document.createElement(e)}catch(t){i=document.createElement("iframe"),i.name=o.iframeId,i.src="javascript:0"}i.id=o.iframeId,o.form.appendChild(i),o.iframe=i}var o=this;if(!this.form){var i,s=document.createElement("form"),a=document.createElement("textarea"),u=this.iframeId="eio_iframe_"+this.index;s.className="socketio",s.style.position="absolute",s.style.top="-1000px",s.style.left="-1000px",s.target=u,s.method="POST",s.setAttribute("accept-charset","utf-8"),a.name="d",s.appendChild(a),document.body.appendChild(s),this.form=s,this.area=a}this.form.action=this.uri(),r(),t=t.replace(p,"\\\n"),this.area.value=t.replace(c,"\\n");try{this.form.submit()}catch(h){}this.iframe.attachEvent?this.iframe.onreadystatechange=function(){"complete"===o.iframe.readyState&&n()}:this.iframe.onload=n}}).call(e,function(){return this}())},function(t,e,n){(function(e){function r(t){var e=t&&t.forceBase64;e&&(this.supportsBinary=!1),this.perMessageDeflate=t.perMessageDeflate,this.usingBrowserWebSocket=h&&!t.forceNode,this.protocols=t.protocols,this.usingBrowserWebSocket||(l=o),i.call(this,t)}var o,i=n(22),s=n(23),a=n(31),c=n(32),p=n(33),u=n(3)("engine.io-client:websocket"),h=e.WebSocket||e.MozWebSocket;if("undefined"==typeof window)try{o=n(36)}catch(f){}var l=h;l||"undefined"!=typeof window||(l=o),t.exports=r,c(r,i),r.prototype.name="websocket",r.prototype.supportsBinary=!0,r.prototype.doOpen=function(){if(this.check()){var t=this.uri(),e=this.protocols,n={agent:this.agent,perMessageDeflate:this.perMessageDeflate};n.pfx=this.pfx,n.key=this.key,n.passphrase=this.passphrase,n.cert=this.cert,n.ca=this.ca,n.ciphers=this.ciphers,n.rejectUnauthorized=this.rejectUnauthorized,this.extraHeaders&&(n.headers=this.extraHeaders),this.localAddress&&(n.localAddress=this.localAddress);try{this.ws=this.usingBrowserWebSocket?e?new l(t,e):new l(t):new l(t,e,n)}catch(r){return this.emit("error",r)}void 0===this.ws.binaryType&&(this.supportsBinary=!1),this.ws.supports&&this.ws.supports.binary?(this.supportsBinary=!0,this.ws.binaryType="nodebuffer"):this.ws.binaryType="arraybuffer",this.addEventListeners()}},r.prototype.addEventListeners=function(){var t=this;this.ws.onopen=function(){t.onOpen()},this.ws.onclose=function(){t.onClose()},this.ws.onmessage=function(e){t.onData(e.data)},this.ws.onerror=function(e){t.onError("websocket error",e)}},r.prototype.write=function(t){function n(){r.emit("flush"),setTimeout(function(){r.writable=!0,r.emit("drain")},0)}var r=this;this.writable=!1;for(var o=t.length,i=0,a=o;i0&&t.jitter<=1?t.jitter:0,this.attempts=0}t.exports=n,n.prototype.duration=function(){var t=this.ms*Math.pow(this.factor,this.attempts++);if(this.jitter){var e=Math.random(),n=Math.floor(e*this.jitter*t);t=0==(1&Math.floor(10*e))?t-n:t+n}return 0|Math.min(t,this.max)},n.prototype.reset=function(){this.attempts=0},n.prototype.setMin=function(t){this.ms=t},n.prototype.setMax=function(t){this.max=t},n.prototype.setJitter=function(t){this.jitter=t}}])}); 3 | //# sourceMappingURL=socket.io.js.map 4 | --------------------------------------------------------------------------------