//引用http和socket.io模块 var us = {} //包含http模块 us.http = require('http'); //包含文件模块,以实现能够读取本目录下面任意文件的功能 var fs = require('fs'); //支持目录文件模块 var path = require('path'); //包含socket.io模块 var socketio = require('socket.io'); //nodejs的underscore扩展中的findWhere方法,可以是我们很容易在对象集合中,通过对象的属性值找到该对象并返回。 var _ = require('underscore'); //构建文件读取路径。自己实现web服务器功能 us.handler=function(request, response) { console.log('request starting...'); var filePath = '.' + request.url; if (filePath == './') filePath = './index.html'; var extname = path.extname(filePath); var contentType = 'text/html'; switch (extname) { case '.js': contentType = 'text/javascript'; break; case '.css': contentType = 'text/css'; break; case '.json': contentType = 'application/json'; break; case '.png': contentType = 'image/png'; break; case '.jpg': contentType = 'image/jpg'; break; case '.wav': contentType = 'audio/wav'; break; } fs.readFile(filePath, function(error, content) { if (error) { if(error.code == 'ENOENT'){ fs.readFile('./404.html', function(error, content) { response.writeHead(200, { 'Content-Type': contentType }); response.end(content, 'utf-8'); }); } else { response.writeHead(500); response.end('Sorry, check with the site admin for error: '+error.code+' ..\n'); response.end(); } } else { response.writeHead(200, { 'Content-Type': contentType }); response.end(content, 'utf-8'); } }); } //创建httpserver,管理文件路径 us.app = us.http.createServer(us.handler); //开启888端口,服务开始监听 //us.app.listen(888); const hostname="127.0.0.1"; const port=888; us.app.listen(port, hostname); console.log(`Server running at http://${hostname}:${port}/`); //也可以采用下面的写法,但代码更多 /*us.app.listen(port, hostname, function() { console.log(`Server running at http://${hostname}:${port}/`); });*/ //输出调试信息 //console.log("Http Server start at 888"); //socketio开始监听http请求 us.socketio = socketio.listen(us.app); //webSocket协议握手成功 ////'connection' 是socket.io 保留的.不能错,结果在变量socket中 us.socketio.sockets.on('connection', function (socket) { //用户登录后端,以实现私聊,此处的登录只是把唯一的用户名放入内存。还未未实现cookie认证功能。 socket.on('socketLogin',function (data) { //如果存在相同名称用户,弹出提示 var toSocket= _.findWhere(us.socketio.sockets.sockets,{name:data.msg}); if(toSocket){ //如果用户名重复,自己给自己发送消息,现在的socket是自己的socket。 socket.emit("UserNameRepeat",data.msg); return; } //以唯一的用户名给该用户设置socket。 socket.name = data.msg; //把该用户名广播给其他用户,让其他用户好友列表中出现该用户 socket.broadcast.emit('addFriend', data); }); //向其他人发送信息 socket.on('sayTo',function (data) { var toName = data.to; //查找是否存在该用户的socket。 var toSocket= _.findWhere(us.socketio.sockets.sockets,{name:toName}); //如果存在,则发送消息 if(toSocket){ //私聊 toSocket.emit('sayTo',data.msg); } }) //前端javascript使用socket.emit('msg', { msg: str }); //字符串msg是自己定义的, //socket.on('msg',function (data) {}); 后端需要用msg接收前端发送来的消息。'msg'需要和客户端发送时定义的事件名相同。 socket.on('broadCast', function (data) { console.log('Get a msg from client ...'); //console.log(data); //向客户端javascript发送广播,注意:这里广播消息为bcast, //则前端javascript用socket.on('bcast', function (r) {alert(r); });接收消息 socket.broadcast.emit('broadCast', data); }); //console.log("WebSocket connect ok...."); //断开链接 socket.on('disconnect', function(){ console.log(socket.name+' connection is disconnect!'); }); })