[已解决] cocos creater websocket 断线重连 web正常,ios报错

用ccc写了一个websocket的测试,发现一个问题。

界面如下:

问题描述:在web端一切正常。在ios模拟器上当点击断开连接后点击重连和点击断开都会出现xcode报错
Error: Invalid Native Object!。

没有点击断开连接之前,ios上可以握手可以发送消息,可以接受消息。一旦点击断开后就不行了···按钮也会灰掉···

代码附上:

var single = require("SocketSingle");
cc.Class({
    extends: cc.Component,

    properties: {
        sendBtn:{
            default: null,
            type: cc.Button
        },
        sendMessage:{
            default: null,
            type: cc.Label
        },
        closeBtn: {
            default: null,
            type: cc.Button
        },
        connBtn: {
            default: null,
            type: cc.Button
        },
        ws: {
            default: null,
            type: WebSocket
        }
    },

    // use this for initialization
    onLoad: function () {
        var self = this;

        self.ws = single.getWebSocket("ws://192.168.0.106:3000", self);
        
        this.sendMessage.string = single.getUrl();

    },
    
    callBackOfOpen: function(event){
        console.log("连接" + single.getUrl() + "服务器成功!");
    },
    callBackOfMessage: function(event){
        console.log("接受服务器消息: " + event.data);
        this.sendMessage.string = event.data;
    },
    callBackOfClose: function(event){
        console.log("WebSocket instance closed.");
        this.sendMessage.string = "WebSocket instance closed.";
    },
    callBackOfError: function(event){
        console.log("Send Text fired an error");
    },
    
    sendTxt: function(){
        this.ws.send("客户端向服务端发送消息!");
    },
    closeClick: function(){
        this.ws.close();
    },
    connClick: function(){
        var self = this;
        self.ws = single.getWebSocket("ws://192.168.0.106:3000", self);
    }
    

    // called every frame, uncomment this function to activate update callback
    // update: function (dt) {

    // },
});



```


var _webSocket = null;  //WebSocket对象
var _url = "";          //服务器地址

module.exports = {
    getUrl: function(){
      return _url;  
    },
    //url是服务器地址,target是执行回调的对象
    getWebSocket: function(url, target){
        if(_webSocket){//对象存在
            if(_webSocket.readyState === WebSocket.OPEN){//已连接上服务器
                if(url != _url){//服务器地址不同
                    _webSocket.close();//断开连接
                    _url = url;
                    _webSocket = new WebSocket(_url);//重新创建连接
                }
            }else{//还没有连接上服务器
                _url = url;
                _webSocket = new WebSocket(_url);
            }
        }else{//对象不存在,创建对象
            _url = url;
            _webSocket = new WebSocket(_url);
        }
        
        //绑定连接成功的回调方法
        _webSocket.onopen = function(event){
            target.callBackOfOpen(event);
        };
        //绑定消息接收的回调方法
        _webSocket.onmessage = function(event){
            target.callBackOfMessage(event);
        };
        //绑定断开连接的回调方法
        _webSocket.onclose = function(event){
            target.callBackOfClose(event);
        };
        //绑定错误发生的回调方法
        _webSocket.onerror = function(event){
            target.callBackOfError(event);
        };
        
        return _webSocket;
    }
};

```


求大神解惑·····

这与 JSB 中 WebSocket 的实现有关系,在断开连接之后,就会释放这个 WebSocket 的对象,所以导致 Invalid Native Object 报错。只需要按照下面的方法修改 getWebSocket 方法即可:

var _webSocket = null;  //WebSocket对象
var _url = "";          //服务器地址 
module.exports = { 
    getUrl: function(){ return _url;   }, //url是服务器地址,target是执行回调的对象 
    getWebSocket: function(url, target){
        if (cc.sys.isObjectValid(_webSocket)) {//对象有效 
            // ...
        } else {//对象已失效,创建对象 
            _url = url; _webSocket = new WebSocket(_url); 
        } 
        // ... 
    }
};

```
1赞

是不是所有引擎定义的对象都用cc.sys.isObjectValid(obj)方法判断是否为空,不能直接用if(obj)来判断?

不是,大多数的对象我们已经做过处理了,一般不会出现这个问题。WebSocket 的处理比较特殊。

再过两个版本左右,我们会在 Creator 定制版引擎中解决这个内存模型问题,JS对象和C++对象生命周期会同步

这个内存模型问题解决了吗,我的工程在web中跑OK,在windows工程中测试,一断开websocket,再连就报和楼主一样的错误,我用的是creator1.3.3

新内存模型在 1.3.3 中已经引入,我检查一下这个问题

WebSocket 目前确实没有处理,每次 close 都会销毁对象,和以前还是一样的解决方案,我看要不要在 1.4 用垃圾回收机制来控制