前端菜鸡之路——聊天室2.0
前段时间在网上偶然的看到了一个用socket.io做的一个聊天室,觉得很有意思,于是也试着做了一个,这是那时写的博客,效果看这里,最近又在《nodejs实战》中看到了类似的例子,又来做了一次聊天室。
//app.js var express = require('express'); var app = express(); var path = require('path'); var port = process.env.PORT||3000; var messages = []; app.use(express.static(path.join(__dirname,'/static')));//将静态文件放在static目录下 app.use(function(req,res){ res.sendFile(path.join(__dirname,'./static/index.html'));//除了静态文件的请求,其他所有的HTTP请求,都会输出index.html }); var server = app.listen(port,function(){ console.log('technode is on port : ' + port + '!'); }); var io = require('socket.io').listen(server); //服务器监听connection事件,有用户连接时,会产生一个socket对象 io.on('connection',function(socket){ socket.on('getAllMessages',function(){ socket.emit('allMessages',messages); }); socket.on('createMessage',function(message){ messages.push(message); io.sockets.emit('messageAdded',message); }); });
//technode.js var tech = angular.module('technodeApp',[]); tech.factory('socket',function($rootScope){ var socket = io.connect(null); return { on: function(eventName, callback){ socket.on(eventName,function(){ var args = arguments; $rootScope.$apply(function(){ callback.apply(socket,args); }); }); }, emit: function(eventName, data, callback){ socket.emit(eventName, data, function(){ var args = arguments; $rootScope.$apply(function(){ if(callback){ callback.apply(socket,args); } }); }); } } }); tech.controller('RoomCtrl',function($scope,socket){ $scope.messages = ['123','456']; socket.emit('getAllMessages'); socket.on('allMessages',function(messages){ $scope.messages = messages; }); socket.on('messageAdded',function(message){ $scope.messages.push(message); }); }); tech.controller('MessageCreatorCtrl',function($scope,socket){ $scope.newMessage = ''; $scope.createMessage = function(){ if($scope.newMessage == ''){ return } socket.emit('createMessage',$scope.newMessage); $scope.newMessage = ''; } }); tech.directive('autoScrollToBottom',function(){ return { link: function(scope,element,attrs){ scope.$watch( function(){ return element.children().length; }, function(){ element.animate({ scrollTop:element.prop('scrollHeight') },1000); } ); } }; }); tech.directive('ctrlEnterBreakLine',function(){ return function(scope,element,attrs){ var ctrlDown = false; element.bind("keydown",function(evt){ if(evt.which === 17){ ctrlDown = true; setTimeout(function(){ ctrlDown = false; },1000); } if(evt.which === 13){ if(ctrlDown){ scope.$apply(function(){ scope.$eval(attrs.ctrlEnterBreakLine); }); evt.preventDefault(); }else{ element.val(element.val()+'\n'); } } }); }; });
这里贴出了主要的两个文件的代码,由于之前做过一次,许多相似的地方都能理解,接下来讲讲遇到的问题吧。
1.这里用到了AngularJS,我不会,稍微恶补了一下,还是感觉很抠脚,还好AnguarJS不是主角,知道了大概的用法就可以了。
2.在创建连接时,书里用的是var socket = io.connect("/");但是我这么写会报错,查了半天也没找到解决方案,但是如果写成var socket = io.connect("null");就正常了。
3.用node-inspector调试还不是很熟练,导致有很多地方调试了很久。
4.除此之外,还有一些地方是因为代码打错导致的,这些问题确实是很麻烦,很难看得出来,报的错误也是让我查了好久。