Websockets not working on samsung galaxy s8 in facebook instant game

STILL NOT Solved…

see a video of the bug here https://youtu.be/BNcaiSggYZE

I thought i had solved this problem. It seems to be intermittent, and not only the galaxy S8 but all Samsung devices i have tried so far. I’'m preparing a video to try to better explain what is going on here. Essentially, a Samsung phone will randomly work or not work with currently no identifying reason.

When it stops working i have to clear the cache of the messenger app, click force stop, and then reload messenger and the websocket connects. It stays working for as long as im testing it. when i stop work, by the time i come back again it is doing the exact same thing. I have to clear the cache and press force stop. This completely renders my app useless as it requires a websocket every time. Iphone and ipad and mac and laptop all working lovely. But on a samsung, this same shitty problem every time! Later i will make a video to help show whats happening.

Sadly i can’t say exactly what was going wrong. However here is the code which works. intermittently.

cc.Class({
    extends: cc.Component,

    properties: {
        websocket: cc.Label,
 
    },

    // use this for initialization
    onLoad: function () {
        this._wsiSendBinary = null;
          this.websocket.string = "loading....";
     
          this.prepareWebSocket();
        },
    
   
    
    prepareWebSocket: function () {
        var self = this;
       this.websocket.string = "preparing";
         this._wsiSendBinary = new WebSocket("wss://www.domain.com:portnum");
       
        this._wsiSendBinary.onopen = function(evt) {
           self.websocket.string = "open socket";
       };

        this._wsiSendBinary.onmessage = function(evt) {
           self.websocket.string = evt.data;
            };

        this._wsiSendBinary.onerror = function(evt) {
      self.websocket.string = evt;
               };

        this._wsiSendBinary.onclose = function(evt) {
          self.websocket.string = "closed";
        // After close, it's no longer possible to use it again, 
            // if you want to send another request, you need to create a new websocket instance
            self._wsiSendBinary = null;
        };
        
        this.scheduleOnce(this.sendWebSocketBinary, 1);
    },

    sendWebSocketBinary: function(sender)
    {
        if (!this._wsiSendBinary) { return; }
        if (this._wsiSendBinary.readyState === WebSocket.OPEN)
        {
            this.websocket.string = "sending...";
     
            
            this._wsiSendBinary.send('testing');
        }
        else
        {

            this.websocket.string = "send binary websocket instance wasn't ready...";
		   this.scheduleOnce(function () {
                this.sendWebSocketBinary();
            }, 1);
        }
    },
});

///////////

OP
I have the issue where the websocket closes on startup on a galaxy s8? Its working fine through a laptop, mac, iphone 6, galaxy s4 but not on galaxy s8. Im using websockets and not socket.io. Its a facebook instant game. As i say, i cannot get it to work on a galaxy s8 for some reason… can anyone help?

cc.Class({
    extends: cc.Component,

    properties: {
           websocket: cc.Label,
        
    },

    // use this for initialization
    onLoad: function () {
        this.ws = null;
         
        this.prepareWebSocket();
         
    },
     
    prepareWebSocket: function () {
        var self = this;
        this.ws = new WebSocket("wss://www.mydomain.org:portnum");
       
	   this.ws.onopen = function(evt) {
            self.websocket.string = "on open fired...";
        };

        this.ws.onmessage = function(evt) {
          
            self.websocket.string = "message recieved.... /n"+evt.data;
        };

        this.ws.onerror = function(evt) {
            self.websocket.string = evt;
        };

        this.ws.onclose = function(evt) {
          self.websocket.string = "socket closed";
		  self.ws = null;
        };
        
        this.scheduleOnce(this.sendMessage, 1);
    },

    sendMessage: function(sender)
    {
        if (!this.ws) { return; }
        if (this.ws.readyState === WebSocket.OPEN)
        {
            this.websocket.string = "websocket open.....";
            
            this.ws.send('hello socket....');
        }
        else
        {
            this.websocket.string = "Websocket instance wasn't ready...";
             this.scheduleOnce(function () {
                this.sendMessage();
            }, 1);
        }
    },
 
});

my server code…

global.debug = true;

const server = require('./class/server.class.js');
const socketList = require('./class/socketList.class.js');
const servDB = require('./class/servDB.class.js');
const lobbyList = require('./class/lobbyList.class.js');
const thehelper = require('./class/helper.class.js');
 
var Helper = new thehelper(Helper);
var ServIO = new server(Helper);
var Lobbys = new lobbyList(Helper);
var MasterSocketList =  new socketList(Helper);
var TF= new servDB(Helper,ServIO,Lobbys,MasterSocketList);
var userLobby = [];
		
TF.wss.on('connection', function connection(thesocket) {
	
	 	
TF.helper.consolelog("User Connected", debug, true);

var myFBID;
console.log('connected');



	thesocket.on('message', function incoming(message) {
	
	console.log(message);
	
	thesocket.send('{"wsEvent":"initReply", "error" : "Omfg that took forever!!"}');
	
	return false;
	
     });




	thesocket.on('close',function(socket)
	{

console.log('user gone');

 });

   });

on a galaxy s8 this just outputs “socket closed”, its fired from the onclose function in the cocos script. No user connected message appears in the server console either, which leads me to believe it is not actually firing at all from cocos. On every other device i have tried, it works perfectly… I have not tried many different devices, iphone 6 and samsung galaxy s4, they both work. S8 doesn’t :confused: help please!

I will ask our engineering team to take a look at this. Thank you @jare.

I have no idea. It seems like there’s some bug about the browser. WebSocket is implemented by the browser, not cocos. Please try a different browser.

Jare, I am not using a browser,this is being called from the game.

I have solved this. I have found that if use the binary version of websockets from the example cases folder, then it works.

The game is running in a WebView.

What is the binary version?

This is the binary version…
prepareWebSocket: function () {
var self = this;
var websocketLabel = this.websocket;
var respLabel = this.websocketResp;
this._wsiSendBinary = new WebSocket(“wss://www.domain.org:8003”);
this._wsiSendBinary.binaryType = “arraybuffer”;
this._wsiSendBinary.onopen = function(evt) {
websocketLabel.textKey = “cases/05_scripting/11_network/NetworkCtrl.js.5”;
};

        this._wsiSendBinary.onmessage = function(evt) {
            var binary = new Uint16Array(evt.data);
            var binaryStr = 'response bin msg: ';

            var str = '';
            for (var i = 0; i < binary.length; i++) {
                if (binary[i] === 0)
                {
                    str += "\'\\0\'";
                }
                else
                {
                    var hexChar = '0x' + binary[i].toString('16').toUpperCase();
                    str += String.fromCharCode(hexChar);
                }
            }

            binaryStr += str;
            respLabel.string = binaryStr;
            websocketLabel.textKey = "cases/05_scripting/11_network/NetworkCtrl.js.6";
        };

        this._wsiSendBinary.onerror = function(evt) {
            websocketLabel.textKey = "cases/05_scripting/11_network/NetworkCtrl.js.7";
        };

        this._wsiSendBinary.onclose = function(evt) {
            websocketLabel.textKey = "cases/05_scripting/11_network/NetworkCtrl.js.8";
            // After close, it's no longer possible to use it again, 
            // if you want to send another request, you need to create a new websocket instance
            self._wsiSendBinary = null;
        };
        
        this.scheduleOnce(this.sendWebSocketBinary, 1);
    },

    sendWebSocketBinary: function(sender)
    {
        if (!this._wsiSendBinary) { return; }
        if (this._wsiSendBinary.readyState === WebSocket.OPEN)
        {
            this.websocket.textKey = "cases/05_scripting/11_network/NetworkCtrl.js.9";
            var buf = "Hello WebSocket中文,\0 I'm\0 a\0 binary\0 message\0.";
            
            var arrData = new Uint16Array(buf.length);
            for (var i = 0; i < buf.length; i++) {
                arrData[i] = buf.charCodeAt(i);
            }
            
            this._wsiSendBinary.send(arrData.buffer);
        }
        else
        {
            var warningStr = "send binary websocket instance wasn't ready...";
            this.websocket.string = i18n.t("cases/05_scripting/11_network/NetworkCtrl.js.10") + warningStr;
            this.scheduleOnce(function () {
                this.sendWebSocketBinary();
            }, 1);
        }
    },

It is not binary version… The example just send binary data by using arraybuffer.
It’s still the WebSocket embedded in WebView.

Jare, could you suggest a way i could try to do this sending plain text instead of using the array buffer?

Hi Guys… I am still having an issue here with this… i wonder if you could take a look at my video to see if that makes it easier to solve… https://youtu.be/BNcaiSggYZE

@jare, do you know how to solve this?

Sorry, I don’t know.