程序员

简易聊天室

2018-04-24  本文已影响163人  金际一线天

前言

本来我做的这个简易聊天室程序是想上课堂展示的,但是这个idea和我的好朋友本门课程的大作业有一些相似,所以为了不尴尬,我就不上去展示。
我就展示给简书上面感兴趣的用户吧,希望大家能够欣赏,从中收获到一些东西。

整个项目的github地址

前端设计

对于前端的设计,这个真的是很考验一个人的审美观,我想我也很难讲明白,我就讲讲我的设计灵感吧。或许你能够从中受到一些启发,设计出更加出色的聊天室。

整个界面如图所示

image.png

对于整个聊天室的顶端,是一个仿Mac的设计,主要的作用是用来显示,当前聊天室的名称。其实,一开始我是没有想到这样的设计,但是我在观看socket.io官网主页的时候,发现这是一个不错的设计,所以我就提取了其中的html和css作为自己聊天室的顶部栏。

至于侧边栏显示当前用户的头像和昵称,我是借鉴了微信的设计,但是代码并没有抄微信的,而是根据这个排版,自己去设计。
至于在线人数的设计,我是参考了这个网站的设计MDBootstrap, 我觉得这个框架是基于Bootstrap进一步的美化,所有的控件我觉得都是做的非常好看,至少比Bootstrap的好看,希望自己的网页炫酷的可以看看这个。

至于左边用户显示栏,一开始我想的是用<ul>布局,后来觉得有点麻烦,还是改用<div> 布局吧。我觉得比较重要的一点就是关注用 float来对齐,让某一个元素脱离文档流。

至于消息气泡的设计,就是一个圆角矩形 + 一个三角形,至于三角形的制作,就是将widthheight 全部设为0, 通过设置 border,设置一面有颜色,其余三面都是透明,就可以实现这个效果。

聊天的效果图

GIF.gif

后端开发

后端的开发主要是 nodejs + angularjs + express + socket.io

其中 nodejs 主要用于服务端开发,angularjs 用于数据绑定,将更改后的数据快速映射到前端页面。socket.io用于通信,消息传递。

其中,服务端开启监听端口,监听客户端的连接,每次监听到客户端的连接时,负责随机为用户生成一个昵称和头像,以及一个uid用来标识用户。

服务端监听到客户端连接的代码如下:

socket.uid = uuidv4();
var userinfo = randomUserInfo();
socket.nickname = userinfo.nickname;
socket.avatar = userinfo.avatar;

connectedSockets[socket.uid] = socket;
userinfo.uid = socket.uid;
userinfo.tag = 'user';
userinfo.hasMessages = 0;
allUsers.push(userinfo);

socket.emit('accept', userinfo);
socket.broadcast.emit('userAdded', userinfo);
socket.emit("allUser", allUsers);

当服务器接收到发送消息的请求是,首先判断这个发送的消息是给特定的用户还是群聊消息,如果是特定的用户,只需要找到对应用户的socket,即可发送相应的消息;如果是群聊消息,则需要将这条消息广播出去。

对应的代码如下:

socket.on('addMessage',function(data){ //有用户发送新消息
    data.position = 'left';
    if(data.to.tag === "user"){//发给特定用户
        connectedSockets[data.to.uid].emit('messageAdded',data);
    }else{//群发
        socket.broadcast.emit('messageAdded',data);//广播消息,除原发送者外都可看到
    }
});

客户端要做的就是,当用户点击发送按钮,或者按下回车键之后,构造发送的消息,消息的字段包括了发送者,接收者,发送内容,消息的显示位置等信息。
还有就是判断当前的是否是群聊,如果是群聊,则需要将消息广播出去。
具体实现的代码如下:

$scope.postMessage = function() {
    var msg = {
        content: $scope.chatContent,
        from: $scope.self,
        to: $scope.receiver,
        type: "normal",
        position: 'right',
        time : new Date()
    };

    if(msg.content.length === 0) return; // 内容为空

    var rec = $scope.receiver;
    if (rec.tag === "user") { //私信
        if (!$scope.privateMessages[rec.uid]) {
            $scope.privateMessages[rec.uid] = [];
        }
        $scope.privateMessages[rec.uid].push(msg);
    } else { //群聊
        $scope.publicMessages.push(msg);
    }

    $scope.chatContent = "";
    if (rec.uid !== $scope.self.uid) { //排除给自己发的情况
        socket.emit("addMessage", msg);
    }
}       

其实,客户端之间的通信,都是用服务器作为了一个中间媒介,所有的消息发送可以看成是客户端与服务器之间的通信,而这两者之间的通信有很类似TCP协议中的三次握手。

参考博客

总结

这个项目还有挺多没有完善的,比如发送表情,发送图片,登陆用户自己设定用户名与头像等,如果有人感兴趣的话,我可以把大家加为合作者,一起把整个项目完善,甚至做的更好。

上一篇下一篇

猜你喜欢

热点阅读