写了一个socket.io服务,实现了用户区分、公聊、私聊等。。。
码云地址https://gitee.com/liuoomei/so...
app.js
//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/www
#!/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.html
Title
我是