猿记录

一个记录、分享的博客

您的位置:主页 > 技术专栏 > node >

nodejs中socket的应用(二)

2017-12-25 09:34:28 作者:yxl 次阅读 node

这是一个基于nodejs服务的一个简单版的群聊
1、服务端重要的代码
   const server = require('http').Server(app.callback());
   const io = require('socket.io')(server);
   server.listen(80);
   //io
/*在线人员*/
var onLineUsers = {};
/* 在线人数*/
var onLineCounts = 0;
io.on('connection',(socket)=> {
console.log('a user connected');
/*监听新用户加入*/
socket.on('login', function (user) {
//暂存socket.name 为user.userId;在用户退出时候将会用到
socket.name = user.userId;
/*不存在则加入 */
if (!onLineUsers.hasOwnProperty(user.userId)) {
//不存在则加入
onLineUsers[user.userId] = user.userName;
onLineCounts++;
}
/*一个用户新加入,向所有客户端监听login的socket的实例发送响应,响应内容为一个对象*/
io.emit('login', {onLineUsers: onLineUsers, onLineCounts: onLineCounts, user: user});
console.log(user.userName, "加入了聊天室");//在服务器控制台中打印么么么用户加入到了聊天室
});
/*监听用户退出聊天室*/
socket.on('disconnect', function () {
if (onLineUsers.hasOwnProperty(socket.name)) {
var user = {userId: socket.name, userName: onLineUsers[socket.name]};
delete onLineUsers[socket.name];
onLineCounts--;
 
/*向所有客户端广播该用户退出群聊*/
io.emit('logout', {onLineUsers: onLineUsers, onLineCounts: onLineCounts, user: user});
console.log(user.userName, "退出群聊");
}
})
 
/*监听到用户发送了消息,就使用io广播信息,信息被所有客户端接收并显示。注意,如果客户端自己发送的也会接收到这个消息,故在客户端应当存在这的判断,是否收到的消息是自己发送的,故在emit时,应该将用户的id和信息封装成一个对象进行广播*/
socket.on('message', function (obj) {
/*监听到有用户发消息,将该消息广播给所有客户端*/
io.emit('message', obj);
console.log(obj.userName, "说了:", obj.content);
});
 
});
2、客服端代码
     $(function(){
var Mychat = function(){
this.socket = null;
this.userName = null;
this.userId = null;
};
Mychat.prototype = {
init:function(userName){
var that = this;
//http://192.168.1.105:80
this.socket = io.connect('http://localhost');
//监听服务消息
//随机数生成uid
this.userId = this.genUid();
this.userName = userName;
this.socket.emit('login', {userId: this.userId, userName: this.userName});
 
/*监听到有用户login了,更新信息*/
this.socket.on('login', function (o) {
//更新系统信息
that.updateSysMsg(o, 'login');
});
 
/*监听到有用户发送消息了*/
this.socket.on("message", function (obj) {
//判断消息是不是自己发送的
var isMe = (obj.userId === that.userId);
var userNameDiv = '<span>' + obj.userName + '</span>';
var contentDiv = '<div>' + obj.content + '</div>';
 
var section = document.createElement('section');
if (isMe) {
section.className = 'user clearfix';
section.innerHTML = contentDiv + userNameDiv;
} else {
section.className = 'service clearfix';
section.innerHTML = userNameDiv + contentDiv;
}
$('#message').append(section);
that.scrollToBottom();
});
this.socket.on('connect',function(){
console.log('连接成功');
 
})
//与服务端断开连接
this.socket.on('disconnect',function(){
console.log('连接断开');
})
//错误发生,并且无法被其他事件类型所处理
this.socket.on('error',function(e){
console.log('e:' + e);
})
 
 
 
},
/**客户端根据时间和随机数生成ID,聊天用户名称可以重复*/
genUid: function () {
return new Date().getTime() + "" + Math.floor(Math.random() * 889 + 100);
},
/*更新系统信息
主要是在客户端显示当前在线人数,在线人列表等,当有新用户加入或者旧用户退出群聊的时候做出页面提示。*/
updateSysMsg: function (o, action) {
var onLineUsers = o.onLineUsers;
var onLineCounts = o.onLineCounts;
var user = o.user;
//更新在线人数
var userHtml = '';
var separator = '';
for (var key in onLineUsers) {
if (onLineUsers.hasOwnProperty(key)) {
userHtml += separator + onLineUsers[key];
separator = '、';
}
}
//插入在线人数和在线列表
$('#onLineCounts').html( '当前共有' + onLineCounts + "人在线、在线列表: " + userHtml);
//添加系统消息
var html = '';
html += '<div class="msg_system">';
html += user.userName;
html += (action === "login") ? "加入了群聊" : "退出了群聊";
html += '</div>';
var section = document.createElement('section');
section.className = 'system J-mjrlinkWrap J-cutMsg';
section.innerHTML = html;
$('#message').append(section);
this.scrollToBottom();
},
//聊天内容提交
sendMsg:function(){
var content = $('#content').val();
if (content != '') {
var obj = {
userId: this.userId,
userName: this.userName,
content: content
};
//如在服务器端代码所说,此对象就行想要发送的信息和发送人组合成为对象一起发送。
this.socket.emit('message', obj);
$('#content').val('');
}
return false;
},
/*滚动条始终在最底部*/
scrollToBottom: function () {
window.scrollTo(0, $('#message')[0].scrollHeight);
},
userNameSubmit: function () {
var userName = $('#userName').val();
if (userName != '') {
$('#userName').val('');
$('#loginbox').hide();
$('#chatbox').show();
this.init(userName);//调用init方法
}
return false;
},
}
var mychat = new Mychat();
//初始化 聊天
//通过“回车键”提交用户名
$('#userName').on('keydown',function(e){
e = e || event;
if (e.keyCode === 13) {
mychat.userNameSubmit();
}
})
//按钮提交
$('#J-sub').on('click',function(){
mychat.userNameSubmit();
})
 
$('#mjr_send').on('click',function(){
mychat.sendMsg();
})
 
})
3、html结构
     <div id="loginbox">
    <div style="width: 260px;margin: 200px auto;background:#dedede;padding:20px">
        输入你在群聊中的昵称
        <br/>
        <br/>
        <input type="text" style="width:180px;" placeholder="请输入用户名" id="userName" name="userName"/>
        <input type="button" style="width: 50px;" value="提交" id="J-sub"/>
    </div>
</div>
 
<div id="chatbox" style="display: none;">
    <div style="background: #3d3d3d;height: 28px;width: 100%;font-size: 12px">
        <div style="line-height: 28px;color:#fff;">
            <span style="text-align: left;margin-left: 10px;">群聊</span>
            <span style="float: right;margin-right: 10px"><span id="showUserName"></span>|
            <a href="javascript:;" onclick="CHAT.logout()" style="color: #fff;">退出</a></span>
        </div>
    </div>
    <div id="doc">
        <div id="chat">
            <div id="message" class="message">
                <div id="onLineCounts"
                     style="background: #EFEFF4; font-size: 12px;margin-top: 10px;margin-left: 10px;color: #666;">
                </div>
            </div>
            <div class="input-box">
                <div class="input">
                    <input type="text" maxlength="140" placeholder="输入聊天内容 " id="content" name="content" >
                </div>
                <div class="action">
                    <button type="button" id="mjr_send" >提交</button>
                </div>
            </div>
        </div>
    </div>
</div>
最后你就可以了 npm start 启动服务,然后开两个窗口进行聊天了

凡本站注明“本站”或“投稿”的所有文章,版权均属于本站或投稿人,未经本站授权不得转载、摘编或利用其它方式使用上述作品。

编辑:yxl 关键词:
0

网友评论