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


    详细讲解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

  • 相关阅读:
    API 生命周期管理
    devops注意事项
    持续交付
    如何进行自动化测试
    环境分类
    多环境配置管理
    一包到底
    111 Lucky
    python反射机制 Lucky
    单元测试框架(unittest) Lucky
  • 原文地址:https://www.cnblogs.com/tianxiangbing/p/chatprivate.html
Copyright © 2020-2023  润新知