Closed astutesoftware closed 6 years ago
Not sure because the code is a bit vague but are you missing the async aspect ? Eg are you waiting for the init to run ? Because before init, socket is undefined.
init gets called on document load of the page. I have some GUI elements to be rendered first and would like to create the socket after rendering everything.
Although it shouldn't make a difference, I am not sure why you are waiting for the DOM to be loaded. a connection to the socket cluster should not be waiting for the UI to be loaded first. Over HTTP/1.1 your browser can load 10(ish) resources at the same time per somain/subdomain/port.
can you console.log() the global socket client right before you call the socket.on() that is causing the issue ? Because as state before, if this is undefined, you are calling them too soon and they need to be called after the init.
Also you could try and get around this with a promise wrapper (which you will need to compile with either babel or a promise polyfill on the fly)
For example (this is from one of my own projects, where the whole thing is browserified on deploy)
const scClient = require('socketcluster-client');
class SocketWrapper {
constructor(socketConfig) {
//setup with empty callbacks for now for typehinting
this.connectionResolver = () => {
};
this.connectionError = () => {
};
this.socketConfig = socketConfig;
//setup connection promise
this.connectionPromise();
//bind connection promises
this.socket.on('connect', (socket) => {
this.connectionResolver(socket)
});
this.socket.on('disconnect', () => {
//reconnect, get new promise
this.connectionPromise();
});
this.socket.on('error', (err) => {
this.connectionError(err)
});
}
connectionPromise() {
this.connection = new Promise((resolve, reject) => {
this.connectionResolver = resolve;
this.connectionError = reject;
});
//new connect event will fire, so new promise will be resolved
this.socket = scClient.connect(this.socketConfig);
}
on(eventName, callback) {
this.connection
.then(() => {
this.socket.on(eventName, (data) => {
callback(Promise.resolve(data));
});
});
}
subscribe(eventName, callback) {
this.connection
.then(() => {
let channel = this.socket.subscribe(eventName);
channel.watch((data) => {
callback(Promise.resolve(data));
});
});
}
}
module.exports = {SocketWrapper: SocketWrapper};
Usage:
const socketConfig = {
hostname: "socket.server.com",
port: 3000
};
const {SocketWrapper} = require('./SocketWrapper');
const wrapper = new SocketWrapper(socketConfig);
wrapper.on('myEvent', (eventHandler) => {
eventHandler
.then((event) => {
//do something with the data
})
.catch((err) => {
console.log(err.stack);
});
});
This ensures that there is always an open connection to the cluster when calling on
or subscribe
, it also handles the watch
for subscribe
, so you don't have to write a handler for it yourself. it also deals with errors in a bit of a better way.
Granted this may sound like an extreme solution for your problem, but the point I am trying to make is that you can't ever call any of the socket functions, if the socket isn't initialised.
Thanks for the detailed reply. Here is what my scenario is. I have a single page application. User comes in.. signs up.. logs on to the service and then qualifies to connect to the socket and chat or message. Considering that sockets are expensive I would want to utilize it only when required. For ex. i have a banned client and would not want him to access the service. So hence had this issue. A simple workaround would be to move him to a different page and connect which is a dirty hack. So thought might as well post an issue here and get some feedback.
Thanks again.
i don't think there's an issue with what you are trying to do, i think there is an issue with the code.
have you console.log'ed the socket before you call .on() or where the error occurs ?
I am writing a javascript client and use this
var socket;
When i use the global var socket all the .on events report no such method.
How do i overcome this?
Basically what i need is to wait for a couple of HTML DOM processes to end and then start the socketCluster connection but the moment i move the socket var inside a variable inside a function everything goes for a toss.