前端菜鸡之路——聊天室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.除此之外,还有一些地方是因为代码打错导致的,这些问题确实是很麻烦,很难看得出来,报的错误也是让我查了好久。

posted @ 2016-01-09 17:26  卡布奇诺233  阅读(337)  评论(0编辑  收藏  举报