Giter Club home page Giter Club logo

socketcluster-client's Introduction

SocketCluster JavaScript client

Client module for SocketCluster.

Setting up

You will need to install both socketcluster-client and socketcluster-server (https://github.com/SocketCluster/socketcluster-server).

To install this module:

npm install socketcluster-client

How to use

The socketcluster-client script is called socketcluster-client.js (located in the main socketcluster-client directory). Embed it in your HTML page like this:

<script type="text/javascript" src="/socketcluster-client.js"></script>

* Note that the src attribute may be different depending on how you setup your HTTP server.

Once you have embedded the client socketcluster-client.js into your page, you will gain access to a global socketClusterClient object. You may also use CommonJS require or ES6 module imports.

Connect to a server

let socket = socketClusterClient.create({
  hostname: 'localhost',
  port: 8000
});

Transmit data

// Transmit some data to the server.
// It does not expect a response from the server.
// From the server socket, it can be handled using either:
// - for await (let data of socket.receiver('foo')) {}
// - let data = await socket.receiver('foo').once()
socket.transmit('foo', 123);

Invoke an RPC

(async () => {

  // Invoke an RPC on the server.
  // It expects a response from the server.
  // From the server socket, it can be handled using either:
  // - for await (let req of socket.procedure('myProc')) {}
  // - let req = await socket.procedure('myProc').once()
  let result = await socket.invoke('myProc', 123);

})();

Subscribe to a channel

(async () => {

  // Subscribe to a channel.
  let myChannel = socket.subscribe('myChannel');

  await myChannel.listener('subscribe').once();
  // myChannel.state is now 'subscribed'.

})();

Get a channel without subscribing

(async () => {

  let myChannel = socket.channel('myChannel');

  // Can subscribe to the channel later as a separate step.
  myChannel.subscribe();
  await myChannel.listener('subscribe').once();
  // myChannel.state is now 'subscribed'.

})();

Publish data to a channel

// Publish data to the channel.
myChannel.transmitPublish('This is a message');

// Publish data to the channel from the socket.
socket.transmitPublish('myChannel', 'This is a message');

(async () => {
  // Publish data to the channel and await for the message
  // to reach the server.
  try {
    await myChannel.invokePublish('This is a message');
  } catch (error) {
    // Handle error.
  }

  // Publish data to the channel from the socket and await for
  // the message to reach the server.
  try {
    await socket.invokePublish('myChannel', 'This is a message');
  } catch (error) {
    // Handle error.
  }
})();

Consume data from a channel

(async () => {

  for await (let data of myChannel) {
    // ...
  }

})();

Connect over HTTPS:

let options = {
  hostname: 'securedomain.com',
  secure: true,
  port: 443,
  wsOptions: { rejectUnauthorized: false } // Only necessary during debug if using a self-signed certificate
};
// Initiate the connection to the server
let socket = socketClusterClient.create(options);

For more detailed examples of how to use SocketCluster, see test/integration.js. Also, see tests from the socketcluster-server module.

Connect Options

See all available options: https://socketcluster.io/

let options = {
  path: '/socketcluster/',
  port: 8000,
  hostname: '127.0.0.1',
  autoConnect: true,
  secure: false,
  connectTimeout: 10000, //milliseconds
  ackTimeout: 10000, //milliseconds
  channelPrefix: null,
  autoReconnectOptions: {
    initialDelay: 10000, //milliseconds
    randomness: 10000, //milliseconds
    multiplier: 1.5, //decimal
    maxDelay: 60000 //milliseconds
  },
  authEngine: null,
  codecEngine: null,
  subscriptionRetryOptions: {},
  wsOptions: { rejectUnauthorized: false },
  query: {
    yourparam: 'hello'
  }
};

Running the tests

  • Clone this repo: git clone [email protected]:SocketCluster/socketcluster-client.git
  • Navigate to project directory: cd socketcluster-client
  • Install all dependencies: npm install
  • Run the tests: npm test

Compatibility mode

For compatibility with an existing SocketCluster server, set the protocolVersion to 1 and make sure that the path matches your old server path:

let socket = socketClusterClient.create({
  protocolVersion: 1,
  path: '/socketcluster/'
});

Developing

Install all dependencies

cd socketcluster-client

npm install -g gulp gulp-cli browserify uglify-es

npm install

Building

To build the SocketCluster client:

npm run build

Change log

See the 'releases' section for changes: https://github.com/SocketCluster/socketcluster-client/releases

License

(The MIT License)

Copyright (c) 2013-2023 SocketCluster.io

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

socketcluster-client's People

Contributors

andersbv avatar artema avatar firest-dead avatar fredyc avatar gkze avatar hedgepigdaniel avatar jondubois avatar jscheel avatar linaco avatar mattkrick avatar megagm avatar odenktools avatar saberking avatar stipsan avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

socketcluster-client's Issues

Cross Domain WS connection

Hello,

I would like to initiate a cross domain WS connection.
I have a working secure server which accept WSS:// connections: "secure.HOST.com"

I'm testing from http://localhost/ with

            var options = {
                protocol: "https",
                hostname: 'secure.HOST.com',
                port: 80
            };

            // Init WebSocket
            this.AppSocket = socketCluster.connect(options);

But in Chrome I have the Cross domain error:

XMLHttpRequest cannot load http://secure.HOST.com/socketcluster/?EIO=3&transport=polling&t=1417080266437-2&sid=_w1_8080_0_xZfw6UDyHDHSlvB1AAA7. The request was redirected to 'https://secure.HOST.com/socketcluster/?EIO=3&transport=polling&t=1417080266437-2&sid=_w1_8080_0_xZfw6UDyHDHSlvB1AAA7', which is disallowed for cross-origin requests that require preflight.

unstable behaviour on embedded client

I am using the socketcluster client on openwrt routers and they are logging quite a lot by the socketcluster. I am running nodejs 0.10.28 on them (mips architecture). It is 100% out traffic, so no subscriptions are there currently. but with frequencies at 200ms I get consistently an exception.

has anyone an idea?

thanks

/node_modules/socketcluster-client/lib/scsocket.js:311
throw err;
^
Error: xhr poll error
at XHR.Transport.onError (/node_modules/socketcluster-client/node_modules/engine.io-client/lib/transport.js:57:13)
at Request. (/node_modules/socketcluster-client/node_modules/engine.io-client/lib/transports/polling-xhr.js:112:10)
at Request.Emitter.emit (/node_modules/socketcluster-client/node_modules/engine.io-client/node_modules/component-emitter/index.js:134:20)
at Request.onError (/node_modules/socketcluster-client/node_modules/engine.io-client/lib/transports/polling-xhr.js:247:8)
at null._onTimeout (/node_modules/socketcluster-client/node_modules/engine.io-client/lib/transports/polling-xhr.js:194:18)
at Timer.listOnTimeout as ontimeout

Unable to intercept error

Hi,

When I send back an error from my server after an emit like this :

socket.on('login', function(data, res){
  if(login.status == "fail"){
    res('incorrect email');
  }
}

I get this kind of message in my chrome console :

Uncaught incorrect email

Is there any way to catch the error ?

PS : I'm on SC1

[Question] Private messages

Is there a way to emit a message from one socket to another one (knowing the socket.id) instead of creating a channel, subscribing to it and adding a middleware to prevent watching it by other users (which is somehow cumbersome)?

Can't connect after disconnect

I'm using socketcluster-client in a angular controller.

At first I try connect to the server and it's connected:

var options = {
  port: 8000
};
// Initiate the connection to the server
var socketInstance = socketCluster.connect(options);
socketInstance.on('connect', function () {
  console.log('connected');
});

then I try to disconnect on controller destroy event and it's disconnected:

$scope.$on('$destroy', function () {
  socketInstance.disconnect();
});

now I try to load controller again and connect to the server again to apply this code:

var options = {
  port: 8000
};
// Initiate the connection to the server
var socketInstance = socketCluster.connect(options);
socketInstance.on('connect', function () {
 console.log('connected');
});

server sees that connection was initiated, but 'connect' event doesn't work on the client side.

Safari private browsing breaks authToken localStorage implementation

How to reproduce,

I have a personal project setup where this bug can be reproduced in a few steps:

  1. open a new private tab in safari
  2. go to https://epic.vg
  3. type "Batman" and submit the form
  4. nothing happens, web inspector will show you an error that goes like: "QuotaExceededError: DOM Exception 22: An attempt was made to add something to storage that exceeded the quota."

Sample fix

If we update this:

global.localStorage;

With something like this: https://gist.github.com/philfreo/68ea3cd980d72383c951
The problem is solved.

I didn't have the time to fork and submit a PR with the fix, but thought I'd share this and my findings and submit a PR later if nobody beats me to it ๐Ÿ˜„

Function expected error in (sc1) socketcluster.js

Error stack in ie8:
Message: Function expected
Line: 545
Char: 1
Code: 0
URI: http://192.168.225.158/socketcluster.js

Message: 'socketCluster' is undefined
Line: 74
Char: 5
Code: 0
URI: http://192.168.225.158/

While loading sc1 myapp example in ie8. We want our application to support ie8 socket long polling functionality, however client library don't seem to work.

I have used npm -g install sc1
and sc1 create myApp commands to create sample app. And running python simple server at port inside public folder 80. Also running node server.js at app folder level.

Replace the underlying socket on a connected client

We run a cluster of servers running socketcluster and clients are randomly allocated to a particular server on page load. We release changes to our code quite frequently. When this happens, some of our servers go down and are taken off HTTP load balancers in order to be upgraded before going back online. The load balancers allow open connections to end gracefully, but this isn't an option for websocket connections which can stay open for a long time.

My idea for dealing with this problem is for a message to be published to a channel (say 'server-status') when a server is about to go offline. The message would also contain the address of a new server to connect to. The client could then copy all its subscriptions and callbacks to the new socket before disconnecting the old one (and ignoring duplicate messages in the meantime). This way, a server can go down without the user missing out on delivery of any published messages.

This seems to be something best implemented inside socketcluster, since it's necessary to transfer all the registered callbacks on subscriptions as well as just the list of subscriptions. Perhaps a new function could be added to the client socket object, something along the lines of socket.transferConnection({host: 'blerg.com', port: 1337})

Interested to hear thoughts.

Cannot disconnect a socket if the initial connection wasn't established

Though the title sounds bizarre, the issue can be reproduced as following:

  1. Try to connect to a server that is not available with socket.connect().
  2. Disconnect the socket via socket.disconnect().
  3. Connect to a live server with socket.connect().

It works well, but it still tries to reconnect to the first not available server every second and throw SocketProtocolError with the message Socket hung up. Should we somehow destroy it?

Auto-resubscribe fails when auth token expires or becomes invalid

I'm having a problem where channels which are subscribed are not correctly resubscribed when a broken connection comes back up and the authentication token has become invalid. It can become invalid because it expires or because the socketcluster server was restarted.

If a client is authenticated and subscribed to a whole lot of channels requiring authentication when it is disconnected, if it is no longer authenticated when it reconnects then it will try and fail to resubscribe to all the channels it was subscribed to.

I think instead it should be possible to register a callback on the connect/reconnect event so that the client can reauthenticate before socketcluster automatically resubscribes to channels previously subscribed to.

Example client code
'''javascript
socket.on('connect', function(status, callback) {
if (!status.isAuthenticated) {
reAuthenticate(function(err) {
callback(err);
// Now the automatic resubscriptions can happen
});
} else {
callback(null);
}
});
'''

For background, our authentication system involves the browser doing an xmlhttp request to our webservers to get a temporary authentication token. This token is given to socketcluster with a socket.emit('login', token), and socketcluster then checks with our webservers that the token is valid. Since our webservers can't reliably revoke socketcluster's authentication token when the user logs out, the socketcluster auth token timeout is short. We also disconnect sockets after a period of browser inactivity to reduce server load, so this situation often arises when the browser becomes active and reconnects after the auth token has expired.

License

As socketcluster is licensed under MIT, it would be logically that socketcluster-client is under MIT as well, but could you specify this explicitly, so we wouldn't worry about any licenses collision? In README, as a LICENSE file or in package.json.

How to use cluster on socketcluster-client?

Hi,

I want to use cluster on both side (Server and Client). I have got success on server side, but unable to do on client side. I am using node.js on both (Server side and Client side).

Please help.

How do I handle a connection error?

I'm not sure if I'm supposed to try/catch (since the socket repeatedly tries to connect), watch for an event, or what. I've read this but it only covers errors that I publish. I'm trying to watch for a "socket hung up" which appears to be thrown when the client can't connect to the server, so I can pop up a message in my application saying that the server isn't reachable.

Client not connecting in nodejs

I'm trying to use the client to connect to my server, but can't seem to do that under nodejs, though the same works fine in a browser. Running the latest SocketCluster both client and server side.

var options = {
    protocol: 'wss',
    secure: true,
    hostname: 'localhost',
    port: 443
};

var socketCluster = require('socketcluster-client');
// Initiate the connection to the server
 socket = socketCluster.connect(options);

   socket.on('error', function (err) {
     console.log('Socket error - ' + err);
   });
   socket.on('connect', function () {
     console.log('CONNECTED');
   });

I'm getting:
Socket error - Error: Socket hung up

This seems to be triggered by a 1006 code after:

/scc/node_modules/socketcluster-client/lib/scsocket.js:399
      throw err;
            ^
Error: Socket hung up
    at Emitter.SCSocket._onSCClose (/scc/node_modules/socketcluster-client/lib/scsocket.js:462:15)
    at Emitter.<anonymous> (/scc/node_modules/socketcluster-client/lib/scsocket.js:293:12)
    at Emitter.emit (/scc/node_modules/socketcluster-client/node_modules/sc-emitter/node_modules/component-emitter/index.js:131:20)
    at Emitter.SCEmitter.emit (/scc/node_modules/socketcluster-client/node_modules/sc-emitter/index.js:28:26)
    at Emitter.SCTransport._onClose (/scc/node_modules/socketcluster-client/lib/sctransport.js:132:30)
    at WebSocket.wsSocket.onerror (/scc/node_modules/socketcluster-client/lib/sctransport.js:79:12)
    at WebSocket.onError (/scc/node_modules/socketcluster-client/node_modules/sc-ws/lib/WebSocket.js:428:14)
    at WebSocket.emit (events.js:107:17)
    at ClientRequest.onerror (/scc/node_modules/socketcluster-client/node_modules/sc-ws/lib/WebSocket.js:686:10)
    at ClientRequest.emit (events.js:107:17)

Things that have been tried:

  1. Older versions:
    in 2.3.12 I get the same error
    in versions older than 2.3.11 the code just exits. It's like nothing got executed. The client does not connect, I have something that tells me when a client connects server-side
  2. secure:false
  3. removing protocol: 'wss'
  4. running on a different machine than the server

Authentication without cookies

There are use cases where cookie-based authentication cannot be used.
For example, in a hybrid mobile application page is served from the 'file://', and it is not possible to use cookies neither to store jwt token (cookies are recommended against in hybrid applications) nor to send the token to the server (there's no way to customize websocket connection headers from javascript).

For such use cases there should be:

  1. An option to customize the way token is stored.
  2. Some standard way to authenticate after connection is established.

My current workaround is:

  1. socket.auth._setCookie is monkey-patched to store token in localStorage.
  2. After connection is established, client reads token from localStorage and emits a custom event with this token. Server pick it up with the following (some error checks are omitted for clarity):
// @EXPECTS:
// - encToken: '<encToken>'
function onHello(data, next) {
  var encToken = data.encToken;
  var key = scServer.auth.key; // @NOTE: whacky
  jwt.verify(encToken, key, function(err, token) {
    if (err) {
      socket.emit('badAuthToken', err); // @NOTE: whacky
    } else {
      socket._authToken = token; // @NOTE: whacky
    }
    next();
  });
}

Is there a better way to do this?

Store serverTimeDiff in socket

Let's say I'm a client & i like to keep my clock set 2 days forward.
If a dev writes some client code to keep the token alive by calling a refreshToken when the token TTL is less than a minute, and the token expires every 24 hours, that dev could inadvertently spin up an infinite stream of refresh requests to his server just because the client is a jerk. Sure, the dev could write code to protect against this, but we could help.

Before the handshake is emitted the client saves preShakeTime.
The server includes the server time in the handshake.
When the server handshake is received, the client saves postShakeTime
roundTripTime = postShakeTime - preShakeTime
Now, we have a time differential (including transmission time!) stored in the socket: this._serverTimeDiff;
Now, we can calculate token TTL = Date.now() - this._serverTimeDiff.

We can use this internally for #31 waitOnAuth. Additionally, devs can use this to defends against wonky clients when they write their refresh code.

undefined is not an object (evaluating 'global.WebSocket')

This is probably me doing something dumb, but I'm unable to get this working on the client. What I did:

  • npm install socketcluster-client
  • cd node_modules/socketcluster-client
  • browserify -s socketCluster index.js > socketcluster.js

and include that file.

I've also tried just using the socketcluster.js file from the repo, but that seems to fail when I attempt to use the socket like so:

var socket = window.socketCluster.connect({hostname: 'localhost', port: 8000});
console.log(socket.state); //undefined

And in my server:

module.exports.run = function (worker) {
  var scServer = worker.scServer;

  scServer.on('connection', function (socket) {
    console.log('client connect');

    socket.on('login', function(credentials, respond) {
      console.log('begin login', credentials);
    });

  });
};

But I get nothing in my browser console, except eventually, I get an xhr polling error. Not sure how to get started with this.

invalid querystring version with 5.0.7 under package.json

https://www.npmjs.com/package/querystring

npm ERR! Darwin 15.5.0                                                                                                                              
npm ERR! argv "/usr/local/Cellar/node/6.5.0/bin/node" "/usr/local/bin/npm" "install"                                                                
npm ERR! node v6.5.0                                                                                                                                
npm ERR! npm  v3.10.6                                                                                                                               

npm ERR! No compatible version found: [email protected]                                                                                             
npm ERR! Valid install targets:                                                                                                                     
npm ERR! 0.2.0, 0.1.0, 0.0.4, 0.0.1                                                                                                                 
npm ERR!                                                                                                                                            
npm ERR!                                                                                                                                            
npm ERR! If you need help, you may report this error at:                                                                                            
npm ERR!     <https://github.com/npm/npm/issues>                                                                                                    

npm ERR! Please include the following file with any support request:                                                                                
npm ERR!     /Users/user/projects/scchat/npm-debug.log

Add 'subscribeRequest' event to client

Currently, the subscribe method internally adds the sub & its pending state to a queue, but it doesn't emit anything, so nothing else in the app knows we're trying to subscribe. This would be useful for showing a loading UI on recently mounted components.

I propose emitting a subscribeRequest event at the bottom of SCSocket.prototype.subscribe. Will be happy to submit a PR & update docs.

Token does not get removed if it was not set during connection

From lib/scsocket.js:

... else if (eventName == '#removeAuthToken') {
  if (this._tokenData) {
    this._setCookie(this._tokenData.cookieName, null, -1);
    Emitter.prototype.emit.call(this, 'removeAuthToken');
  }
  var response = new Response(this, obj.cid);
  response.end();
} ...

The only place where this._tokenData gets set is the #setAuthToken handler. But when user reconnects (and provides token via cookie or by other means), the only received message is #status, so this._tokenData never gets set.

As far as I can tell, this._tokenData is required by #removeAuthToken handler purely because it contains the cookie name. I guess this name should also be sent with the #status message to resolve the issue described above.

v3.1.0 breaks in react-native

Some recent changes have broken compatibility with react-native. When running socketcluster-client within iOS JavascriptCore environment, the following exception occurs:

Can't find variable: location

I suspect it has to do with something in scsocketcreator:

var isSecure = global.location && location.protocol == 'https:';
var opts = {
port: options.port || global.location && location.port ? location.port : isSecure ? 443 : 80,
autoReconnect: true,
autoProcessSubscriptions: true,
ackTimeout: 10000,
hostname: global.location && location.hostname,
path: '/socketcluster/',
secure: isSecure,
timestampRequests: false,
timestampParam: 't',
authEngine: null,
authTokenName: 'socketCluster.authToken',
binaryType: 'arraybuffer',
multiplex: true
};
for (var i in options) {
if (options.hasOwnProperty(i)) {
opts[i] = options[i];
}
}
var multiplexId = getMultiplexId(isSecure, opts.hostname, opts.port, opts.path);
if (opts.multiplex === false) {
return new SCSocket(opts);
}
if (!_connections[multiplexId]) {
_connections[multiplexId] = new SCSocket(opts);
}
return _connections[multiplexId];
}
function destroy(options) {
var self = this;
options = options || {};
var isSecure = global.location && location.protocol == 'https:';
var opts = {
port: options.port || global.location && location.port ? location.port : isSecure ? 443 : 80,
hostname: global.location && location.hostname,

I have to dig deeper, but perhaps some of the location variable checks aren't full proof, and this variable is probably not present with JSC.

a few requests/suggestions

  • uglifyjs --compress --mangle --screw-ie8 socketcluster.js -o ./socketcluster.min.js
  • authentication make possible to dispatch a request to an api endpoint to authenticate. this make it easy to integrate with a website, for instance an app using php or python that can really benefit by sticking to what it is good at, and letting the socket cluster generate the real time data feeds.
  • documentation

Using MessagePack (binary frames) with SocketCluster

Currently the SocketCluster client uses a format of:

{"event":"someType","data":{"foo":"bar"},"cid":3}

The format has considerable overhead on the messaging structure and I was wondering how we could go about implementing a buffered-approach such as MessagePack. This could save us big on bandwidth as we're developing an application with a high rate of message throughput.

Right now I'm trying something like:

/**
 * Send a Message to Remote over WebSocket.
 * Note: This method is part of an abstracted Transport layer used by both Client and Server
 */
send(messageType, message, callback = null) {
  // this.socket = SocketCluster socket

  if (this.socket.getState() !== 'open') {
    return;
  }

  const encoded = msgpack.encode({event: messageType, data: message}); // returns Buffer

  // Get the SocketCluster Transport and send Binary frame
  if (this.socket.transport) { // SCClient Socket
    this.socket.transport.socket.send(encoded);
  } else { // SCServer Socket
    this.socket.socket.send(encoded);
  }

  // The original SocketCluster way which reproduces a "heavy" json string-payload
  this.socket.emit(messageType, message);
}

What do you think of supporting raw binary frames directly? And if there's no interest in official support, could you share your thoughts on this? Thanks!

Multiple transports

Is there a way to have some other transports besides WebSockets? I want to support older clients too that do not support WebSockets at the moment.

Add waitForAuth to subscribe method

Apologies for the recent activity, but this is a really neat package that's almost perfect.

Here's the problem scenario: a parent component calls socket.authenticate to authorize the socket connection. That same component also calls subscribe. We now have a race condition.

Next, the MIDDLEWARE_SUBSCRIBE requires a valid token. if authentication wins, then the subscription is successful. If not, the subscription fails & doesn't try again.

As a workaround, on EVERY subscription, the dev has to write code that checks if the socket is authenticated, & if not, call subscribe inside an authenticate event. We can do this behind the scenes. I propose a waitForAuth property on the subscribe method.

First, we have to store isAuthenticated in the socket state. That means when the server emits connect we save that value. We'll also set it to false on disconnect / state close.

Inside subscribe, if waitForAuth is false OR isAuthenticated is true, it's business as usual. Otherwise, we open a listener for authenticate and put _trySubscribe inside that.

In doing so, we only wait when we have to, the rest of the time, we still get the massive speed benefit of subscribing before a SC connection is open. Thoughts?

watch() will be re-occur when socket reconnected

hello, I try to use socketcluster, and I found watch() would re-triggered when socket reconnected, How to solve it? thanks ~

my code:

    var connectCount = 1;
    var options = {
        port: 8123
    };
    var socket = socketCluster.connect(options);
    socket.on('connect', function(socket){
        console.log(arguments);
        console.log('CONNECTED');
    });
    socket.on('error', function(err){
        console.error('Socket error - ' + err);
        reconnect();
    });
    socket.on('disconnect', function(err){
        console.error('Socket disconnect - ' + err);
        reconnect();
    });
    function reconnect(){
        if(connectCount <= 100 && socket.state != 'open'){
            setTimeout(function(){
                console.log('reconnect:' + connectCount);
                socket.connect();
                ++connectCount;
            }, 5000);
        }
    }

    socket.on('event', function(data){
        $('#result').append(JSON.stringify(data) + '<br/>');
    });

    var channel = socket.subscribe('channel');
    channel.on('subscribeFail', function(err){
        console.log('Failed to subscribe the channel due to error: ' + err);
    });
    channel.watch(function(data){
        $('#result').html(data + '<br/>');
    });

Socketcluster Client Library :

I want to develop native android client library for socketcluster .Current available libraries are based on Webview jsbridge which degrades performance of connection. Can you provide me with some sort of documentation so that I can contribute to development of java client library for socketcluster.

bower package

It'd be nice to have this on bower so those of us that don't use browserify could still install this.

socket.constructor.name returns `Emitter`

Object.create doesn't assign anything to the prototype. There are 2 workarounds for this:
Option 1 use new (technically, this is faster since V8 optimizes for it, but used so infrequently it really doesn't matter)
Option 2 SCSocket.prototype.constructor = SCSocket + don't use anonymous function for creators (eg var SCSocket = function SCSocket(...`

use case:
user passes in either a socket or a channel into a function. If socket do x, if channel, do y.

_tryReconnect for auth errors

Hi, I have a server to server setup where the client issues a login event right after connecting to the SCServer. The server depends on another service to perform authentication. If there's an error during the process, for example if the auth service is down, the server will respond with an error to the login event. In such case, I'd like for the client to wait for a period of time and retry the authentication, in the same way a reconnect is attempted when the connection to the server is lost.

I've found that the following code does what I expect:

socket.on('connect', function (status) {
  if (!status.isAuthenticated) {
    socket.emit('login', credentials, function (err) {
      if (err) {
        // auth failure, try to reconnect
        socket.disconnect();
        socket._tryReconnect();
      } else {
        // auth OK, setup other listeners
       // ...
      }
    });
  } else {
     // already authenticated, setup other listeners
     // ...
  }
});

But I feel a bit uneasy using the _tryReconnect method. I wonder if there's a recommended way to handle this scenario without having to rewrite the reconnect behaviour myself. If not maybe _tryReconnect could be exposed as a public method?

Thanks!

[React Native] Unable to resolve module querystring ...

"socketcluster-client": "^4.3.19"
npm i
import socketCluster from 'socketcluster-client';

excute, and throws error

Unable to resolve module querystring from PROJECT_PATH/node_modules/socketcluster-client/lib/scsocket.js: Unable to fine this module in its module map or any of the node_modules directories under node_modules/querystring and its parent directories

Reuse connection instance

Each call to connect() creates a new connection. If I call this from different components, I'll end up with a bunch of different connections, each with their own subs. Socket.io handles this with a manager & allows for multiplexing.

In socket.io:

s1 = socketIO.connect();
s2 = socketIO.connect();
s1 === s2 //true

Would is be possible to do the same with SC?

Disconnection occurs within 'beforeunload' event

I'm prompting the user that their connection will be interrupted if they leave the page, however socketcluster will optimistically trigger disconnect before the user has made their selection at the confirmation prompt. The offending code is:

var unloadHandler = function () {
  self.disconnect();
};

if (global.attachEvent) {
  global.attachEvent('onunload', unloadHandler);
} else if (global.addEventListener) {
  global.addEventListener('beforeunload', unloadHandler, false);
}

All beforeunload events occur as near to "at the same time" as possible, so the user is not able to cancel unloading of the page before disconnection occurs.

I have toyed with using e.stopImmediatePropagation() in my beforeunload event handler, but this is only effective if my script loaded before socketcluster. Then it seems non-trivial to ensure trailing beforeunload events fire afterward.

Perhaps socketcluster could try more aggressively to attach to the unload event, rather than the more commonly utilised beforeunload event.

Can't connect to wss/https

client.js on Node.js 7.2.0

var socketCluster = require('socketcluster-client');
console.log("Socket Cluster Client version", socketCluster.version);
var socket = socketCluster.connect({
    hostname: 'localhost',
    protocol: 'https',
    port: 8500,
    rejectUnauthorized: false
});

socket.on('connect', function(status){
    console.log("connect", status);
});

socket.on('error', function(e){
    console.log("Error", e);
});

Output:

Socket Cluster Client version 5.2.4
Error { Error
at SCSocket._onSCClose (/home/node/node_modules/socketcluster-client/lib/scsocket.js:597:15)
at SCTransport. (/home/node/node_modules/socketcluster-client/lib/scsocket.js:286:12)
at SCTransport.Emitter.emit (/home/node/node_modules/component-emitter/index.js:131:20)
at SCTransport.SCEmitter.emit (/home/node/node_modules/sc-emitter/index.js:28:26)
at SCTransport._onClose (/home/node/node_modules/socketcluster-client/lib/sctransport.js:175:30)
at WebSocket.wsSocket.onerror (/home/node/node_modules/socketcluster-client/lib/sctransport.js:104:12)
at WebSocket.onError (/home/node/node_modules/ws/lib/WebSocket.js:452:14)
at emitOne (events.js:96:13)
at WebSocket.emit (events.js:188:7)
at ClientRequest.onerror (/home/node/node_modules/ws/lib/WebSocket.js:711:10)
name: 'SocketProtocolError',
message: 'Socket hung up',
code: 1006 }

But I using socketcluster-client on browser and can connect to https server

JavaScript file does not get served

Hey,
I think I've might encountered a problem in the client.
You state in the description that the js file should usually be served automatically.
However, even in your sample it is not available for me. (npm install and node server.js were executed before)

screen shot 2016-02-24 at 22 33 51

socket.deauthenticate([callback]); callback don't work properly

I need to deauthenticate the socket before to use it but even when callback is called, sometimes, the socket is not deauthenticated.

for example:

socket.deauthenticate((err) => {
     if (!err){
         console.log(socket.getAuthToken()); //it returns a object instead of null
     }
})

JS errors on Yosemite Safari 8.0.5

Just run the sample app, and you'll see a few console errors.

image

Complete console logs

[Error] TypeError: Type error
send (socketcluster.js, line 940)
_send (socketcluster.js, line 940)
_sendObject (socketcluster.js, line 945)
_emitRaw (socketcluster.js, line 969)
_emitDirect (socketcluster.js, line 1018)
_trySubscribe (socketcluster.js, line 1115)
(anonymous function) (socketcluster.js, line 1263)
_resubscribe (socketcluster.js, line 1265)
_onSCOpen (socketcluster.js, line 582)
onopen (socketcluster.js, line 543)
[Error] Failed to load resource: the server responded with a status of 404 (Not Found) (favicon.ico, line 0)
[Log] RANDOM: 1 :D (127.0.0.1, line 33)
[Log] RANDOM: 2 :) (127.0.0.1, line 33)
[Log] RANDOM: 4 ;) (127.0.0.1, line 33)
[Error] TypeError: Type error
send (socketcluster.js, line 940)
_send (socketcluster.js, line 940)
_sendObject (socketcluster.js, line 945)
sendObject (socketcluster.js, line 953)
disconnect (socketcluster.js, line 560)
unloadHandler (socketcluster.js, line 458)
[Error] TypeError: Type error
send (socketcluster.js, line 940)
_send (socketcluster.js, line 940)
_sendObject (socketcluster.js, line 945)
_emitRaw (socketcluster.js, line 969)
_emitDirect (socketcluster.js, line 1018)
_trySubscribe (socketcluster.js, line 1115)
(anonymous function) (socketcluster.js, line 1263)
_resubscribe (socketcluster.js, line 1265)
_onSCOpen (socketcluster.js, line 582)
onopen (socketcluster.js, line 543)
[Log] RANDOM: 3 :3 (127.0.0.1, line 33)
[Log] RANDOM: 4 ;) (127.0.0.1, line 33)
[Log] RANDOM: 2 :) (127.0.0.1, line 33)
[Log] RANDOM: 0 ;p (127.0.0.1, line 33, x2)
[Log] RANDOM: 3 :3 (127.0.0.1, line 33)
[Log] RANDOM: 2 :) (127.0.0.1, line 33)
[Log] RANDOM: 3 :3 (127.0.0.1, line 33)
[Log] RANDOM: 2 :) (127.0.0.1, line 33)
[Error] ReferenceError: Can't find variable: callback
_handleEventAckTimeout (socketcluster.js, line 996)
(anonymous function) (socketcluster.js, line 1013)
[Log] RANDOM: 1 :D (127.0.0.1, line 33)
[Log] RANDOM: 0 ;p (127.0.0.1, line 33)
[Log] RANDOM: 2 :) (127.0.0.1, line 33)
[Error] TypeError: Type error
send (socketcluster.js, line 940)
_send (socketcluster.js, line 940)
_sendObject (socketcluster.js, line 945)
sendObject (socketcluster.js, line 953)
disconnect (socketcluster.js, line 560)
unloadHandler (socketcluster.js, line 458)
[Log] RANDOM: 3 :3 (127.0.0.1, line 33)
[Error] TypeError: Type error
send (socketcluster.js, line 940)
_send (socketcluster.js, line 940)
_sendObject (socketcluster.js, line 945)
_emitRaw (socketcluster.js, line 969)
_emitDirect (socketcluster.js, line 1018)
_trySubscribe (socketcluster.js, line 1115)
(anonymous function) (socketcluster.js, line 1263)
_resubscribe (socketcluster.js, line 1265)
_onSCOpen (socketcluster.js, line 582)
onopen (socketcluster.js, line 543)
[Log] RANDOM: 1 :D (127.0.0.1, line 33)
[Log] RANDOM: 4 ;) (127.0.0.1, line 33)
[Log] RANDOM: 2 :) (127.0.0.1, line 33, x2)
[Log] RANDOM: 3 :3 (127.0.0.1, line 33)
[Log] RANDOM: 1 :D (127.0.0.1, line 33, x3)
[Log] RANDOM: 2 :) (127.0.0.1, line 33)
[Error] ReferenceError: Can't find variable: callback
_handleEventAckTimeout (socketcluster.js, line 996)
(anonymous function) (socketcluster.js, line 1013)
[Log] RANDOM: 2 :) (127.0.0.1, line 33)
[Log] RANDOM: 3 :3 (127.0.0.1, line 33)
[Log] RANDOM: 1 :D (127.0.0.1, line 33, x2)
[Log] RANDOM: 4 ;) (127.0.0.1, line 33)
[Log] RANDOM: 1 :D (127.0.0.1, line 33)
[Log] RANDOM: 0 ;p (127.0.0.1, line 33)
[Log] RANDOM: 2 :) (127.0.0.1, line 33)
[Log] RANDOM: 3 :3 (127.0.0.1, line 33)
[Log] RANDOM: 1 :D (127.0.0.1, line 33, x2)
[Log] RANDOM: 2 :) (127.0.0.1, line 33)
[Log] RANDOM: 4 ;) (127.0.0.1, line 33, x2)
[Log] RANDOM: 1 :D (127.0.0.1, line 33)
[Error] TypeError: Type error
send (socketcluster.js, line 940)
_send (socketcluster.js, line 940)
send (socketcluster.js, line 949)
_onSCMessage (socketcluster.js, line 732)
onmessage (socketcluster.js, line 551)
[Log] RANDOM: 2 :) (127.0.0.1, line 33, x2)
[Log] RANDOM: 4 ;) (127.0.0.1, line 33)
[Log] RANDOM: 2 :) (127.0.0.1, line 33, x3)
[Log] RANDOM: 1 :D (127.0.0.1, line 33)
[Log] RANDOM: 4 ;) (127.0.0.1, line 33)
[Log] RANDOM: 2 :) (127.0.0.1, line 33)
[Log] RANDOM: 1 :D (127.0.0.1, line 33)
[Log] RANDOM: 0 ;p (127.0.0.1, line 33)
[Log] RANDOM: 2 :) (127.0.0.1, line 33)
[Log] RANDOM: 1 :D (127.0.0.1, line 33)
[Log] RANDOM: 4 ;) (127.0.0.1, line 33)
[Log] RANDOM: 1 :D (127.0.0.1, line 33, x3)
[Log] RANDOM: 0 ;p (127.0.0.1, line 33)
[Log] RANDOM: 1 :D (127.0.0.1, line 33, x2)
[Log] RANDOM: 3 :3 (127.0.0.1, line 33)
[Log] RANDOM: 0 ;p (127.0.0.1, line 33)
[Log] RANDOM: 4 ;) (127.0.0.1, line 33, x2)
[Log] RANDOM: 2 :) (127.0.0.1, line 33)
[Error] TypeError: Type error
send (socketcluster.js, line 940)
_send (socketcluster.js, line 940)
send (socketcluster.js, line 949)
_onSCMessage (socketcluster.js, line 732)
onmessage (socketcluster.js, line 551)
[Log] RANDOM: 3 :3 (127.0.0.1, line 33)
[Log] RANDOM: 4 ;) (127.0.0.1, line 33)
[Log] RANDOM: 0 ;p (127.0.0.1, line 33, x2)
[Log] RANDOM: 1 :D (127.0.0.1, line 33)
[Log] RANDOM: 4 ;) (127.0.0.1, line 33)
[Log] RANDOM: 1 :D (127.0.0.1, line 33, x2)
[Log] RANDOM: 2 :) (127.0.0.1, line 33)
[Log] RANDOM: 1 :D (127.0.0.1, line 33)
[Error] Socket error - Error: Client pong timed out
(anonymous function) (127.0.0.1, line 18)
emit (socketcluster.js, line 1419)
(anonymous function) (socketcluster.js, line 632)
[Error] TypeError: Type error
send (socketcluster.js, line 940)
_send (socketcluster.js, line 940)
_sendObject (socketcluster.js, line 945)
_emitRaw (socketcluster.js, line 969)
_emitDirect (socketcluster.js, line 1018)
_trySubscribe (socketcluster.js, line 1115)
(anonymous function) (socketcluster.js, line 1263)
_resubscribe (socketcluster.js, line 1265)
_onSCOpen (socketcluster.js, line 582)
onopen (socketcluster.js, line 543)
[Log] RANDOM: 0 ;p (127.0.0.1, line 33)
[Log] RANDOM: 4 ;) (127.0.0.1, line 33)
[Log] RANDOM: 0 ;p (127.0.0.1, line 33)
[Log] RANDOM: 2 :) (127.0.0.1, line 33)
[Log] RANDOM: 3 :3 (127.0.0.1, line 33)
[Log] RANDOM: 0 ;p (127.0.0.1, line 33)
[Log] RANDOM: 3 :3 (127.0.0.1, line 33)
[Log] RANDOM: 2 :) (127.0.0.1, line 33)
[Log] RANDOM: 4 ;) (127.0.0.1, line 33)
[Error] ReferenceError: Can't find variable: callback
_handleEventAckTimeout (socketcluster.js, line 996)
(anonymous function) (socketcluster.js, line 1013)
[Log] RANDOM: 1 :D (127.0.0.1, line 33, x2)
[Log] RANDOM: 0 ;p (127.0.0.1, line 33)
[Log] RANDOM: 4 ;) (127.0.0.1, line 33)
[Log] RANDOM: 1 :D (127.0.0.1, line 33)
[Log] RANDOM: 3 :3 (127.0.0.1, line 33)
[Log] RANDOM: 0 ;p (127.0.0.1, line 33, x2)
[Log] RANDOM: 4 ;) (127.0.0.1, line 33)
[Log] RANDOM: 2 :) (127.0.0.1, line 33)
[Log] RANDOM: 4 ;) (127.0.0.1, line 33)
[Log] RANDOM: 2 :) (127.0.0.1, line 33)
[Log] RANDOM: 3 :3 (127.0.0.1, line 33)
[Log] RANDOM: 1 :D (127.0.0.1, line 33)
[Log] RANDOM: 3 :3 (127.0.0.1, line 33)
[Error] TypeError: Type error
send (socketcluster.js, line 940)
_send (socketcluster.js, line 940)
send (socketcluster.js, line 949)
_onSCMessage (socketcluster.js, line 732)
onmessage (socketcluster.js, line 551)
[Log] RANDOM: 0 ;p (127.0.0.1, line 33)
[Log] RANDOM: 3 :3 (127.0.0.1, line 33)
[Log] RANDOM: 2 :) (127.0.0.1, line 33)
[Log] RANDOM: 4 ;) (127.0.0.1, line 33)
[Log] RANDOM: 0 ;p (127.0.0.1, line 33)
[Log] RANDOM: 1 :D (127.0.0.1, line 33)
[Log] RANDOM: 2 :) (127.0.0.1, line 33)
[Log] RANDOM: 4 ;) (127.0.0.1, line 33)
[Log] RANDOM: 3 :3 (127.0.0.1, line 33, x2)
[Log] RANDOM: 2 :) (127.0.0.1, line 33)
[Log] RANDOM: 3 :3 (127.0.0.1, line 33)
[Log] RANDOM: 0 ;p (127.0.0.1, line 33)
[Log] RANDOM: 4 ;) (127.0.0.1, line 33)
[Log] RANDOM: 2 :) (127.0.0.1, line 33, x2)
[Log] RANDOM: 0 ;p (127.0.0.1, line 33)
[Log] RANDOM: 1 :D (127.0.0.1, line 33)
[Log] RANDOM: 0 ;p (127.0.0.1, line 33)
[Log] RANDOM: 3 :3 (127.0.0.1, line 33)
[Log] RANDOM: 4 ;) (127.0.0.1, line 33)
[Log] RANDOM: 0 ;p (127.0.0.1, line 33)
[Log] RANDOM: 4 ;) (127.0.0.1, line 33, x2)
[Log] RANDOM: 3 :3 (127.0.0.1, line 33)
[Error] TypeError: Type error
send (socketcluster.js, line 940)
_send (socketcluster.js, line 940)
send (socketcluster.js, line 949)
_onSCMessage (socketcluster.js, line 732)
onmessage (socketcluster.js, line 551)
[Log] RANDOM: 4 ;) (127.0.0.1, line 33)
[Log] RANDOM: 3 :3 (127.0.0.1, line 33)
[Log] RANDOM: 1 :D (127.0.0.1, line 33)
[Log] RANDOM: 2 :) (127.0.0.1, line 33)
[Log] RANDOM: 1 :D (127.0.0.1, line 33)
[Log] RANDOM: 4 ;) (127.0.0.1, line 33)
[Log] RANDOM: 1 :D (127.0.0.1, line 33)
[Log] RANDOM: 4 ;) (127.0.0.1, line 33)
[Log] RANDOM: 3 :3 (127.0.0.1, line 33)
[Log] RANDOM: 0 ;p (127.0.0.1, line 33)
[Error] Socket error - Error: Client pong timed out
(anonymous function) (127.0.0.1, line 18)
emit (socketcluster.js, line 1419)
(anonymous function) (socketcluster.js, line 632)
[Error] TypeError: Type error
send (socketcluster.js, line 940)
_send (socketcluster.js, line 940)
_sendObject (socketcluster.js, line 945)
_emitRaw (socketcluster.js, line 969)
_emitDirect (socketcluster.js, line 1018)
_trySubscribe (socketcluster.js, line 1115)
(anonymous function) (socketcluster.js, line 1263)
_resubscribe (socketcluster.js, line 1265)
_onSCOpen (socketcluster.js, line 582)
onopen (socketcluster.js, line 543)
[Log] RANDOM: 2 :) (127.0.0.1, line 33, x2)
[Log] RANDOM: 4 ;) (127.0.0.1, line 33, x2)
[Log] RANDOM: 2 :) (127.0.0.1, line 33)
[Log] RANDOM: 0 ;p (127.0.0.1, line 33)
[Log] RANDOM: 1 :D (127.0.0.1, line 33)
[Log] RANDOM: 0 ;p (127.0.0.1, line 33)
[Log] RANDOM: 2 :) (127.0.0.1, line 33)
[Error] ReferenceError: Can't find variable: callback
_handleEventAckTimeout (socketcluster.js, line 996)
(anonymous function) (socketcluster.js, line 1013)
[Log] RANDOM: 4 ;) (127.0.0.1, line 33)
[Log] RANDOM: 2 :) (127.0.0.1, line 33, x4)
[Log] RANDOM: 1 :D (127.0.0.1, line 33)
[Log] RANDOM: 3 :3 (127.0.0.1, line 33)
[Log] RANDOM: 2 :) (127.0.0.1, line 33, x2)
[Log] RANDOM: 4 ;) (127.0.0.1, line 33)
[Log] RANDOM: 0 ;p (127.0.0.1, line 33)
[Log] RANDOM: 2 :) (127.0.0.1, line 33)
[Log] RANDOM: 1 :D (127.0.0.1, line 33)
[Log] RANDOM: 3 :3 (127.0.0.1, line 33)
[Log] RANDOM: 0 ;p (127.0.0.1, line 33)
[Error] TypeError: Type error
send (socketcluster.js, line 940)
_send (socketcluster.js, line 940)
send (socketcluster.js, line 949)
_onSCMessage (socketcluster.js, line 732)
onmessage (socketcluster.js, line 551)
[Log] RANDOM: 0 ;p (127.0.0.1, line 33)
[Log] RANDOM: 1 :D (127.0.0.1, line 33)
[Log] RANDOM: 4 ;) (127.0.0.1, line 33)
[Log] RANDOM: 0 ;p (127.0.0.1, line 33, x3)
[Log] RANDOM: 3 :3 (127.0.0.1, line 33, x2)
[Log] RANDOM: 1 :D (127.0.0.1, line 33, x2)
[Log] RANDOM: 0 ;p (127.0.0.1, line 33)
[Log] RANDOM: 4 ;) (127.0.0.1, line 33)
[Log] RANDOM: 1 :D (127.0.0.1, line 33)
[Log] RANDOM: 3 :3 (127.0.0.1, line 33)
[Log] RANDOM: 2 :) (127.0.0.1, line 33)
[Log] RANDOM: 1 :D (127.0.0.1, line 33, x2)
[Log] RANDOM: 4 ;) (127.0.0.1, line 33, x2)
[Log] RANDOM: 1 :D (127.0.0.1, line 33, x3)
[Log] RANDOM: 3 :3 (127.0.0.1, line 33)
[Log] RANDOM: 0 ;p (127.0.0.1, line 33)
[Log] RANDOM: 4 ;) (127.0.0.1, line 33)
[Error] TypeError: Type error
send (socketcluster.js, line 940)
_send (socketcluster.js, line 940)
send (socketcluster.js, line 949)
_onSCMessage (socketcluster.js, line 732)
onmessage (socketcluster.js, line 551)
[Log] RANDOM: 0 ;p (127.0.0.1, line 33)
[Log] RANDOM: 3 :3 (127.0.0.1, line 33)
[Log] RANDOM: 4 ;) (127.0.0.1, line 33)
[Log] RANDOM: 2 :) (127.0.0.1, line 33)
[Log] RANDOM: 3 :3 (127.0.0.1, line 33, x3)
[Log] RANDOM: 2 :) (127.0.0.1, line 33)
[Log] RANDOM: 0 ;p (127.0.0.1, line 33)
[Log] RANDOM: 4 ;) (127.0.0.1, line 33)
[Error] Socket error - Error: Client pong timed out
(anonymous function) (127.0.0.1, line 18)
emit (socketcluster.js, line 1419)
(anonymous function) (socketcluster.js, line 632)
[Error] TypeError: Type error
send (socketcluster.js, line 940)
_send (socketcluster.js, line 940)
_sendObject (socketcluster.js, line 945)
_emitRaw (socketcluster.js, line 969)
_emitDirect (socketcluster.js, line 1018)
_trySubscribe (socketcluster.js, line 1115)
(anonymous function) (socketcluster.js, line 1263)
_resubscribe (socketcluster.js, line 1265)
_onSCOpen (socketcluster.js, line 582)
onopen (socketcluster.js, line 543)
[Log] RANDOM: 4 ;) (127.0.0.1, line 33, x2)
[Log] RANDOM: 2 :) (127.0.0.1, line 33)
[Log] RANDOM: 3 :3 (127.0.0.1, line 33)
[Log] RANDOM: 2 :) (127.0.0.1, line 33)
[Log] RANDOM: 3 :3 (127.0.0.1, line 33)
[Log] RANDOM: 0 ;p (127.0.0.1, line 33, x2)
[Log] RANDOM: 2 :) (127.0.0.1, line 33)
[Error] ReferenceError: Can't find variable: callback
_handleEventAckTimeout (socketcluster.js, line 996)
(anonymous function) (socketcluster.js, line 1013)
[Log] RANDOM: 2 :) (127.0.0.1, line 33)
[Log] RANDOM: 1 :D (127.0.0.1, line 33)
[Log] RANDOM: 0 ;p (127.0.0.1, line 33)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.