Node.js中使用socket创建私聊和公聊聊天室


Posted in Javascript onNovember 19, 2015

先给大家展示效果图:

Node.js中使用socket创建私聊和公聊聊天室

在上篇文章给大家介绍使用Angular和Nodejs、socket.io搭建聊天室及多人聊天室,本文继续介绍Node.js中使用socket创建私聊和公聊聊天室,具体详情请看下文吧。

nodejs的应用中,关于socket应该是比较出彩的了,socket.io在github上有几万人的star,它的成功应该是不输于express的,为了方便了解整个socket.io的使用.

例子请点击http://chat.lovewebgames.com/

源码下载https://github.com/tianxiangbing/chat

由于本人太穷,所以服务器和数据库都是使用的国外免费的,访问速度上可以会稍慢。

先说下我对socket.io的理解,websocket更像是开启了一个端口服务,来监视过往的通讯。所以我们可以依赖于当前站点80端口启socket服务,也可以放于其他端口上,比如:

 require('socket.io').listen(3000);

这样就是监视3000端口了,由于我用的免费服务器,没有权限打开其他端口,所以,我还是使用80了,由于80已经被express使用了,所以我只好在express使用的时候传进来了。

 var server = http.createServer(app);

 var socket = require(‘./socket/msg')(server);

然后 我在msg.js里是这样写的

var db = require('../db/mysql');

var sio = require('socket.io');

var IO = function(server) {

var io = sio.listen(server)

这样就和谐了,db是创建mysql连接的方法,不在本节内容里,略。

在socket.io里是这样的,首先创建一个io通道的连接,然后监视里面的socket的事件,nodejs是事件驱动嘛。代码如下:

io.on('connection', function(socket) {

        console.log('a user connected.');

        socket.on('disconnect', function() {

            console.log('user disconnected.');

        });

})

这时只要有用户连接上,就会进入connection中了,然后它的参数是个socket,如果是公聊,我们可以直接用

io.emit('chat message', {});

这种形式了。但我们这里是私聊,所以我们要临时的把这个socket对象保存在全局里,供与你私聊的对象使用找到你的socket,很绕口,其实这里的私聊,不算完全的点对点,它还是经过了服务器的,消息传给服务器,服务器再找到你要传达给的那个人的socket对象,发给他。这就是整个的过程了。这里我使用的是一个类数组对象来存储的.

var users = {},

usocket = {};

socket.on('user join', function(data) {

    users[username] = username;

    usocket[username] = socket;

})

由于我这里需要用户名登录,所以我就把用户名作为了唯一的标识(这只是一个例子,不要跟我谈用户名重复的情况),这里用类数组的形式的好处就是我不用循环也能够很快的找到它。再我给A发送私聊时,我会先在这个uscoket里面找到它,然后调用它的emit。

function sendUserMsg(data) {
 if (data.to in usocket) {
 console.log('================')
 console.log('to' + data.to, data);
 usocket[data.to].emit('to' + data.to, data);
 usocket[data.user].emit('to' + data.user, data);
 console.log('================')
 }
}

这里我emit了两次的原因是,我发给对方消息的同时,我自己也要收到这个消息,然后把它显示出来,为什么这样?其一,接口统一了,聊天里的内容全是服务器过来的,其二,证明我发送成功了。

然后我在客户端监听时,也用我自己的用户名起了一个to+用户名的事件监听。

socket.on('to' + user, function(data) {
 //console.log(data);
 formatMsg(data);
})

这样,不管是我发的消息,还是我收到消息,都会进入这个事件了。最后,在用户离开的时候别忘记delete掉这个对象。

socket.on('disconnect', function() {
 console.log('disconnect')
 if (username) {
 counter--;
 delete users[username];
 delete usocket[username];
 if (home.name == username) {
  homeLeave(username);
 }
 sendmsg({
  type: 0,
  msg: "用户<b>" + username + "</b>离开聊天室",
  counter: counter,
  users: users
 })
 }
});

好了,这样就大功告成了。

Javascript 相关文章推荐
javascript CSS画图之基础篇
Jul 29 Javascript
js中for in的用法示例解析
Dec 25 Javascript
js处理表格对table进行修饰
May 26 Javascript
基于jQuery+Cookie实现的防止刷新的在线考试倒计时
Jun 19 Javascript
js绘制圆形和矩形的方法
Aug 05 Javascript
酷! 不同风格页面布局幻灯片特效js实现
Feb 19 Javascript
深入理解(function(){... })();
Aug 16 Javascript
jquery对象与DOM对象转化
Feb 08 Javascript
Vue.js中轻松解决v-for执行出错的三个方案
Jun 09 Javascript
详解RequireJs官方使用教程
Oct 31 Javascript
Vue.js 中的 v-cloak 指令及使用详解
Nov 19 Javascript
jQuery-Citys省市区三级菜单联动插件使用详解
Jul 26 jQuery
Jquery实现仿京东商城省市联动菜单
Nov 19 #Javascript
javascript实现二级级联菜单的简单制作
Nov 19 #Javascript
jquery通过扩展select控件实现支持enter或focus选择的方法
Nov 19 #Javascript
javascript中checkbox使用方法实例演示
Nov 19 #Javascript
jquery实现表格隔行换色效果
Nov 19 #Javascript
javascript设计简单的秒表计时器
Sep 05 #Javascript
跟我学习javascript的定时器
Nov 19 #Javascript
You might like
PHP内置过滤器FILTER使用实例
2014/06/25 PHP
PHP实现删除字符串中任何字符的函数
2015/08/11 PHP
PHP输出XML格式数据的方法总结
2017/02/08 PHP
yii2 commands模式以及配置crontab定时任务的方法
2017/08/19 PHP
laravel中短信发送验证码的实现方法
2018/04/25 PHP
兼容多浏览器的iframe自适应高度(ie8 、谷歌浏览器4.0和 firefox3.5.3)
2009/11/04 Javascript
javascript 三种编解码方式
2010/02/01 Javascript
基于jQuery的倒计时插件代码
2011/05/07 Javascript
js性能优化 如何更快速加载你的JavaScript页面
2012/03/17 Javascript
JS图片预加载 JS实现图片预加载应用
2012/12/03 Javascript
DOM操作一些常用的属性汇总
2015/03/13 Javascript
Vuex利用state保存新闻数据实例
2017/06/28 Javascript
vue.js 获取select中的value实例
2018/03/01 Javascript
JS实现调用本地摄像头功能示例
2018/05/18 Javascript
详解在vue-cli中使用graphql即vue-apollo的用法
2018/09/08 Javascript
JavaScript对象原型链原理解析
2020/01/22 Javascript
微信小程序点击item使之滚动到屏幕中间位置
2020/03/25 Javascript
vue下载二进制流图片操作
2020/10/26 Javascript
[01:14]3.19DOTA2发布会 三代刀塔人第二代
2014/03/25 DOTA
[00:32]2018DOTA2亚洲邀请赛出场——VP
2018/04/04 DOTA
[06:53]2018DOTA2国际邀请赛寻真——勇于创新的Vici Gaming
2018/08/14 DOTA
用Python实现一个简单的多线程TCP服务器的教程
2015/05/05 Python
Python爬虫模拟登录带验证码网站
2016/01/22 Python
Python下使用Scrapy爬取网页内容的实例
2018/05/21 Python
Python 多线程不加锁分块读取文件的方法
2018/12/11 Python
Python3批量生成带logo的二维码方法
2019/06/24 Python
django模板获取list中指定索引的值方式
2020/05/14 Python
HelloFresh澳大利亚:订购你的美味食品盒、健康餐食
2018/03/28 全球购物
巴西网上药店:Drogaria Araujo
2021/01/06 全球购物
Java方面的关于数组和继承的笔面试题
2015/09/18 面试题
中学生差生评语
2014/01/30 职场文书
物流管理专业毕业生自荐信
2014/03/04 职场文书
销售业务员岗位职责
2015/02/13 职场文书
酒店财务部岗位职责
2015/04/14 职场文书
浅谈Python响应式类库RxPy
2021/06/14 Python
MyBatis-Plus 批量插入数据的操作方法
2021/09/25 Java/Android