详细讲解nodejs中使用socket的私聊的方式

在上一次我使用nodejs+express+socketio+mysql搭建聊天室,这基本上就是从socket.io的官网上的一份教程式复制学习,然后,根据国情,我又在其中加入了私聊点对点,然后共享画图的你画我猜功能。

先上效果图:

由于本人太穷,所以服务器和数据库都是使用的国外免费的。域名是我的,它的访问地址是:http://chat.lovewebgames.com

先说下我对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
})
}
});

好了,这样就大功告成了。demo:http://chat.lovewebgames.com/  如果有任何的问题,可以加我的QQ群一起学习。QQ技术群:5678537,70210212,77813547

详细讲解nodejs中使用socket的私聊的方式的更多相关文章

  1. 详解nodejs中使用socket的私聊和公聊的办法

    详解nodejs中使用socket的私聊和公聊的办法 nodejs的应用中,关于socket应该是比较出彩的了,socket.io在github上有几万人的star,它的成功应该是不输于express ...

  2. 第九节:详细讲解Java中的泛型,多线程,网络编程

    前言 大家好,给大家带来详细讲解Java中的泛型,多线程,网络编程的概述,希望你们喜欢 泛型 泛型格式:ArrayList list= new ArrayList(); ArrayList list= ...

  3. 第五节:详细讲解Java中的接口与继承

    前言 大家好,给大家带来详细讲解Java中的接口与继承的概述,希望你们喜欢 什么是接口(interface) 接口中的方法都是抽象方法,public权限,全是抽象函数,不能生成对象 interface ...

  4. 第四节:详细讲解Java中的类和面向对象思想

    前言 大家好,给大家带来详细讲解Java中的类和面向对象思想的概述,希望你们喜欢 类和面向对象 在Java中怎样理解对象,创建对象和引用:什么是引用,对于基础学习的同学,要深入了解引用.示例:Stri ...

  5. 第八节:详细讲解Java中的异常处理情况与I/O流的介绍以及类集合框架

    前言 大家好,给大家带来详细讲解Java中的异常处理情况与I/O流的介绍以及类集合框架的概述,希望你们喜欢 JAVA 异常 try...catch...finally结构的使用方法 class Tes ...

  6. 第七节:详细讲解Java中的日期,java.util.date

    前言 大家好,给大家带来详细讲解Java中的日期,java.util.date的概述,希望你们喜欢 类Date Java.lang.Object->java.util.Date public c ...

  7. 第六节:详细讲解Java中的装箱与拆箱及其字符串

    前言 大家好,给大家带来详细讲解Java中的装箱与拆箱及其字符串的概述,希望你们喜欢 装箱与拆箱 封装类有:Byte , short , Integer , Character , long , Fl ...

  8. 【转】详细讲解Java中log4j的使用方法

    转载地址:http://www.233.com/Java/zhuangye/20070731/142625631.html 1.Log4j是什么? Log4j可以帮助调试(有时候debug是发挥不了作 ...

  9. 详细讲解Android中的Message的源码

    相信大家对于Android中的Handler是在为熟悉不过了,但是要知道,Handler就其本身而言只是一个壳子,真正在内部起到作用的是Message这个类,对于Message这个类,相信大家也不会陌 ...

随机推荐

  1. 自动生成Mapper和Entity工具MybatisGenerator的使用

    新建一个XML文件crmGeneratorConfig.xml,文件具体内容如下.把MybatisGenerator.zip解压出来,把MybatisGenerator文件夹复制到Eclipse安装目 ...

  2. jsp获得文件的绝对路径

    当前WEB应用的物理路径:<%=application.getRealPath("/")%>当前访问的JSP文件的物理路径:<%=application.getR ...

  3. 关于AJAX跨域调用ASP.NET MVC或者WebAPI服务的问题及解决方案

      作者:陈希章 时间:2014-7-3 问题描述 当跨域(cross domain)调用ASP.NET MVC或者ASP.NET Web API编写的服务时,会发生无法访问的情况. 重现方式 使用模 ...

  4. Yii2的深入学习--别名(Aliases)

    在之前自动加载机制的文章中,我们有提到别名,提到 getAlias 方法,大家当时可能不太清楚,这到底是什么,今天我们就来说一下别名. 别名用来表示文件路径和 URL,这样就避免了将一些文件路径.UR ...

  5. Webydo:一款在线自由创建网站的 Web 应用

    Webydo 是一款专业的在线建站应用,使平面设计师可以创建和管理 HTML 网站,而无需编写代码.设计人员可以设计任何类型网站,只需要点击按钮,就能够发布先进的 HTML 网站. 你可以控制所有的设 ...

  6. JS实现base64加密解密

    JS实现base64加密解密 转载自http://blog.csdn.net/fengzheng0306/archive/2006/04/25/676055.aspx 方法一: <HTML> ...

  7. 3.创建第一个android项目

    安卓开发学习笔记 1.安卓开发之环境搭建 2.SDK目录结构和adb工具及命令介绍 3.创建第一个android项目 1.打开Eclipse,选择File——>new——>others.. ...

  8. UMeditor宽度自适应

    百度编辑器UMeditor,生成富文本编辑框以后,改变窗口大小会出现横向滚动条,即使你调用接口设置了编辑器的宽度为100%.如: var um = UM.getEditor('<%=txtCon ...

  9. WordPress主题模板层次和常用模板函数

    首页: home.php index.php 文章页: single-{post_type}.php – 如果文章类型是videos(即视频),WordPress就会去查找single-videos. ...

  10. jQuery的Ajax请求数据时type无法使用GET

    写一个ASP.NET MVC例子,它是使用jQuery的$.Ajax来呼叫控制器的数据. 创建一个视图: 运行结果: 一切正常,但是本例子我们只是获取数据,并没有做任何数据POST上传至控制器,我们尝 ...