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 相关文章推荐
Prototype1.5 rc2版指南最后一篇之Position
Jan 10 Javascript
对frameset、frame、iframe的js操作示例代码
Aug 16 Javascript
js判断字符长度及中英文数字等
Mar 19 Javascript
基于jQuery实现表单提交验证
Nov 24 Javascript
jquery div模态窗口的简单实例
May 28 Javascript
JavaScript中的冒泡排序法
Aug 03 Javascript
Bootstrap Table使用心得总结
Nov 29 Javascript
原生js实现轮播图
Feb 27 Javascript
webpack进阶——缓存与独立打包的用法
Aug 02 Javascript
Angular6新特性之Angular Material
Dec 28 Javascript
ElementUI多个子组件表单的校验管理实现
Nov 07 Javascript
vue elementUI表格控制对应列
Apr 13 Vue.js
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
初品cakephp 入门基础
2012/02/16 PHP
php读取文件内容的几种方法详解
2013/06/26 PHP
推荐几款用 Sublime Text 开发 Laravel 所用到的插件
2014/10/30 PHP
WIN8.1下搭建PHP5.6环境
2015/04/29 PHP
如何在Web页面上直接打开、编辑、创建Office文档
2007/03/12 Javascript
HTML代码中标签的全部属性 中文注释说明
2009/03/26 Javascript
多浏览器支持的右下角浮动窗口
2010/04/01 Javascript
文本框中,回车键触发事件的js代码[多浏览器兼容]
2010/06/07 Javascript
JavaScript中的Primitive对象封装介绍
2014/12/31 Javascript
究竟什么是Node.js?Node.js有什么好处?
2015/05/29 Javascript
浅谈Node.js中的定时器
2015/06/18 Javascript
js数组常用操作方法小结(增加,删除,合并,分割等)
2016/08/02 Javascript
JS传播事件、取消事件默认行为、阻止事件传播详解
2017/08/14 Javascript
javascript中神奇的 Date对象小结
2017/10/12 Javascript
jQuery时间戳和日期相互转换操作示例
2018/12/07 jQuery
vue-cli系列之vue-cli-service整体架构浅析
2019/01/14 Javascript
vue2.0实现的tab标签切换效果(内容可自定义)示例
2019/02/11 Javascript
详解nodejs http请求相关总结
2019/03/31 NodeJs
mpvue 页面预加载新增preLoad生命周期的两种方式
2019/10/17 Javascript
小程序实现可拖动的悬浮按钮
2020/09/07 Javascript
[00:32]2018DOTA2亚洲邀请赛出场——VP
2018/04/04 DOTA
Python创建xml的方法
2015/03/10 Python
Python内置函数delattr的具体用法
2017/11/23 Python
python2 与 pyhton3的输入语句写法小结
2018/09/10 Python
Pytorch 实现权重初始化
2019/12/31 Python
canvas像素点操作之视频绿幕抠图
2018/09/11 HTML / CSS
Saks Fifth Avenue澳洲/亚太地区:萨克斯第五大道精品百货店
2019/06/09 全球购物
abstract class和interface有什么区别?
2012/01/03 面试题
信息技术教学反思
2014/02/12 职场文书
监察建议书范文
2014/03/12 职场文书
2014年村支部书记四风对照检查材料思想汇报
2014/10/02 职场文书
2014年人事部工作总结
2014/12/03 职场文书
Java基础之线程锁相关知识总结
2021/06/30 Java/Android
Nginx防盗链与服务优化配置的全过程
2022/01/18 Servers
Python使用永中文档转换服务
2022/05/06 Python
MySQL如何修改字段类型和字段长度
2022/06/10 MySQL