寫了一個socket.io服務,實現了用戶區分、公聊、私聊等。。。
碼雲地址https://gitee.com/liuoomei/so...javascript
app.jscss
//app.js var express = require('express') var app = express(); var server = require('http').Server(app); // var io = require('socket.io')(server); var path = require('path'); app.use(express.static(path.join(__dirname, 'public'))) app.get('/', function(req, res){ res.sendFile(path.join(__dirname, 'index.html')); }); module.exports = app;
bin/wwwhtml
#!/usr/bin/env node /** * Module dependencies. */ let app = require('../app'); let debug = require('debug')('mysocket:server'); let http = require('http'); let _ = require('underscore'); /** * Get port from environment and store in Express. */ let userLs = [] let port = normalizePort(process.env.PORT || '3000'); app.set('port', port); /** * Create HTTP server. */ let server = http.createServer(app); /** * Listen on provided port, on all network interfaces. */ server.listen(port); let io = require('socket.io')(server); io.on('connection', function(socket){ socket.on('login', function(userid){ let obj = { userid, id: socket.id } userLs.push(obj) console.log(userid + '創建了連接'); socket.emit('userLs',userLs) socket.emit('login',socket.id) }); // 判斷用戶離線事件能夠經過socket.io自帶的disconnect事件完成,當一個用戶斷開鏈接,disconnect事件就會觸發 socket.on('disconnect', function(){ let _user = _.where(userLs,{id:socket.id}) console.log('_user',_user) console.log(socket.id + '中斷了連接'); userLs = userLs.filter(it =>{ return _user.every(item =>{ return it.id != item.id }) }) // do somethings console.log('del',userLs) }); socket.on('message', function (data) { //服務端像因此也沒發送數據 let _user = _.where(userLs,{id:socket.id}) io.sockets.emit('message', {id:_user[0].id,userid:_user[0].userid,message:data.message}); //給全部人(包括本身)發送消息 // socket.broadcast.emit('message', data.message); //給全部人(不包括本身)發送消息 }); socket.on('sayTo', function (data) { let toMsg = data.message; let toId = data.id; // nodejs的underscore擴展中的findWhere方法,能夠在對象集合中,經過對象的屬性值找到該對象並返回。 let _user = _.where(userLs,{id:toId}) if(_user){ let toSocket = _.findWhere(io.sockets.sockets, {id: toId}); // 經過該鏈接對象(toSocket)與連接到這個對象的客戶端進行單獨通訊 socket.emit('message', {id:socket.id,message:toMsg}) //向創建該鏈接的客戶端廣播 toSocket.emit('message', {id:socket.id,message:toMsg}); }else{ socket.emit('error','該用戶不在線') } // socket.emit() :向創建該鏈接的客戶端廣播 // socket.broadcast.emit() :向除去創建該鏈接的客戶端的全部客戶端廣播 // io.sockets.emit() : 向全部客戶端廣播,等同於上面兩個的和 }); }); server.on('error', onError); server.on('listening', onListening); /** * Normalize a port into a number, string, or false. */ function normalizePort(val) { let port = parseInt(val, 10); if (isNaN(port)) { // named pipe return val; } if (port >= 0) { // port number return port; } return false; } /** * Event listener for HTTP server "error" event. */ function onError(error) { if (error.syscall !== 'listen') { throw error; } let bind = typeof port === 'string' ? 'Pipe ' + port : 'Port ' + port; // handle specific listen errors with friendly messages switch (error.code) { case 'EACCES': console.error(bind + ' requires elevated privileges'); process.exit(1); break; case 'EADDRINUSE': console.error(bind + ' is already in use'); process.exit(1); break; default: throw error; } } /** * Event listener for HTTP server "listening" event. */ function onListening() { let addr = server.address(); let bind = typeof addr === 'string' ? 'pipe ' + addr : 'port ' + addr.port; debug('Listening on ' + bind); console.log(`服務已啓動,端口:${addr.port}`) }
public/index.htmljava
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> .chat{ width: 300px; height: 500px; text-align: center; margin: 0 auto; border: 1px solid #ccc; } .message{ width: 100%; height: 460px; } #table{ border: 1px solid } </style> </head> <body> <div class="chat"> <select name="" id="select" onchange="console.log()"> </select> <div class="message"></div> <div>我是<span id="_id"></span></div> <input id="text" type="text" placeholder="請輸入聊天信息"> <button onclick="chat()">發送信息</button> </div> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script> <!-- 這裏socket不須要引用外部文件,node後臺運行會自動生成能夠引用的js文件 --> <!-- <script src="https://cdn.bootcss.com/socket.io/2.2.0/socket.io.js"></script> --> <script src="/socket.io/socket.io.js"></script> <!-- <script src="./javascripts/underscore.min.js"></script> --> <script> let message = document.getElementsByClassName('message')[0] let socket = io.connect('http://localhost:3000'); // let userid = this.getUuid() let userLs = [] socket.emit('login', userid); //從服務端接收數據 socket.on('login',function (data) { document.getElementById("_id").innerHTML = data; }) socket.on('message',function (data) { message.innerHTML += `${data.id}:${data.message}` + '<br>'; }) socket.on('sayTo',function (data) { message.innerHTML += `${data.id}:${data.message}` + '<br>'; }) socket.on('userLs',function (data) { console.log(data) $("#select").append(`<option value="">全部人</option>`) if(data.length > 0){ for(let item of data){ $("#select").append(`<option value="${item.id}">${item.id}</option>`) } } }) socket.on('error', function(msg) { //錯誤提示 alert(msg) }); function chat(){ let text = document.getElementById('text').value if(!text){ alert('不能發送空消息!') return } //向服務端發送數據 if($('#select option:selected').val()){ console.log($('#select option:selected').val()) // return socket.emit('sayTo', {id:$('#select option:selected').val(),message:text}); }else{ socket.emit('message', {message:text}); } } function getUuid () { function S4 () { return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1) } return (S4() + S4() + '-' + S4() + '-' + S4() + '-' + S4() + '-' + S4() + S4() + S4()) } </script> </body> </html>