请教一个关于Socket.io的问题!

按照论坛的教程,我顺利搭起了nodejs服务器,前后台可以互相通信了,我在场景A里用io(url)连接了一次,场景B里也用相同的代码,发现他创建了两个连接,请问我该怎么做可以让整个项目始终使用一个链接?

用全局变量保存建立的连接

感谢你回复我,如果可以,能给我个简单的示例吗?

1、最简单的,每次引用socket的时候从全局对象中尝试获取连接,若无已建立的连接则建立一个新连接:

if (!window.Socket) window.Socket = io(url);
window.Socket.on(...);

2、进一步,如果游戏中大量使用连接,可以在游戏开始的时候就建立连接,以后直接获取即可:

// 游戏启动时:
window.Socket = io(url);
// 场景A和场景B中:
window.Socket.on(...);

3、比2好一点的方法,第一次需要连接的时候才建立连接:

// 游戏启动时:
Object.defineProperty(window, "Socket", {
    get: function() {
        if (!window._socket) window._Socket = io(url);
        return window._Socket;
    }
});
// 场景A和场景B中:
window.Socket.on(...)

4、模块化的方法(推荐),将创建连接封装成一个模块,方便自己以后管理和添加功能:

// 创建一个Socket.js文件,内容:
var Socket = {
    _instance: null,
    get instance() {
        if (!this._instance) this._instance = io(url);
        return this._instance;
    }
};
module.exports = Socket;
// 场景A和场景B中:
let Socket = require("Socket");
Socket.instance.on(...);

大哥,给您鞠躬了,十分感谢,下班回去马上试试!

1赞

客户端emit正常,运行on的时候浏览报了这个错误:
Uncaught TypeError: Cannot read property ‘on’ of undefined

你用的哪个方法?调用的代码发出现看看啊

我使用您教我的方法4
这是我的代码

//socket.my.js
var Socket = {
    _instance : null,
    get instance() {
        if (!this._instance) {
            this._instance = io('http://127.0.0.1:3000');
            return this._instance;
        }
    }
};
module.exports = Socket;

//引用

var Socket = require('socket.my');

cc.Class({
    extends: cc.Component,

    properties: {
        
    },

    onLoad: function () {
        
    },
    
    onBtnLoginClicked: function () {
        ````````````
                Socket.instance.emit('login',User);
                Socket.instance.on('login',function(msg){
                    cc.log('111');
                    if(msg.status){
                        LblHint.string = '用户名密码正确!';
                        var tmpAnmi = cc.find("Login/Form").getComponent(cc.Animation);
                        var animation = tmpAnmi;
                        EditBoxName.string = '';
                        EditBoxPwd.string = '';
                        tmpAnmi.play("LoginFormOut");
                        animation.on('stop',self.LoginFormAnimOut,this);
                    }else{
                        LblHint.string = '用户名密码错误!';
                    }
                });
         ```````````
    },

});

socket.my.js里面,return this._instance不要放在if的括号里。

if (!this._instance) {
    this._instance = io('http://127.0.0.1:3000');
}
return this._instance;

这段代码的意思是如果没有已经创建的连接,则创建一个。然后总是会返回this._instance。你那样写就变成如果没有已经创建的连接,则创建并返回;如果已经有连接,就什么都不做(也不返回this._instance),你场景里第二次引用的Socket.instance就变成未定义undefined。

可以了,哥,实在抱歉耽误你时间了,我水平太差了,连这个都看不出来。